A game about forced loneliness, made by TACStudios
1using System; 2using System.Collections; 3using System.Linq; 4using System.Threading.Tasks; 5using NUnit.Framework; 6using NUnit.Framework.Interfaces; 7using NUnit.Framework.Internal; 8using NUnit.Framework.Internal.Commands; 9using UnityEngine.TestTools; 10using SetUpTearDownCommand = UnityEngine.TestTools.SetUpTearDownCommand; 11using TestActionCommand = UnityEngine.TestTools.TestActionCommand; 12 13namespace UnityEngine.TestRunner.NUnitExtensions.Runner 14{ 15 internal static class TestCommandBuilder 16 { 17 public static TestCommand BuildTestCommand(TestMethod test, ITestFilter filter) 18 { 19 if (test.RunState != RunState.Runnable && 20 !(test.RunState == RunState.Explicit && filter.IsExplicitMatch(test))) 21 { 22 return new SkipCommand(test); 23 } 24 25 var testReturnsIEnumerator = test.Method.ReturnType.Type == typeof(IEnumerator); 26 var testReturnsTask = test.Method.ReturnType.Type == typeof(Task); 27 28 TestCommand command; 29 if (testReturnsTask) 30 { 31 command = new TaskTestMethodCommand(test); 32 } 33 else if (testReturnsIEnumerator) 34 { 35 command = new EnumerableTestMethodCommand(test); 36 } 37 else 38 { 39 command = new UnityTestMethodCommand(test); 40 } 41 42 command = new UnityLogCheckDelegatingCommand(command); 43 foreach (var wrapper in test.Method.GetCustomAttributes<IWrapTestMethod>(true)) 44 { 45 command = wrapper.Wrap(command); 46 if (command == null) 47 { 48 var message = String.Format("IWrapTestMethod implementation '{0}' returned null as command.", 49 wrapper.GetType().FullName); 50 return new FailCommand(test, ResultState.Failure, message); 51 } 52 53 if (testReturnsIEnumerator && !(command is IEnumerableTestMethodCommand)) 54 { 55 command = TryReplaceWithEnumerableCommand(command); 56 if (command != null) 57 { 58 continue; 59 } 60 61 var message = String.Format("'{0}' is not supported on {1} as it does not handle returning IEnumerator.", 62 wrapper.GetType().FullName, 63 GetTestBuilderName(test)); 64 return new FailCommand(test, ResultState.Failure, message); 65 } 66 } 67 68 command = new TestActionCommand(command); 69 70 if (!testReturnsIEnumerator && !testReturnsTask) 71 { 72 command = new ImmediateEnumerableCommand(command); 73 } 74 75 command = new SetUpTearDownCommand(command); 76 77 foreach (var wrapper in test.Method.GetCustomAttributes<IWrapSetUpTearDown>(true)) 78 { 79 if (command is SetUpTearDownCommand && !testReturnsIEnumerator && !testReturnsTask) 80 { 81 // Ensure that we can use the immediate execute on the setup/teardown 82 command = new ImmediateEnumerableCommand(command); 83 } 84 85 command = wrapper.Wrap(command); 86 if (command == null) 87 { 88 var message = String.Format("IWrapSetUpTearDown implementation '{0}' returned null as command.", 89 wrapper.GetType().FullName); 90 return new FailCommand(test, ResultState.Failure, message); 91 } 92 93 if ((testReturnsIEnumerator || testReturnsTask) && !(command is IEnumerableTestMethodCommand)) 94 { 95 command = TryReplaceWithEnumerableCommand(command); 96 if (command != null) 97 { 98 continue; 99 } 100 101 var message = String.Format("'{0}' is not supported on {1} as it does not handle returning IEnumerator.", 102 wrapper.GetType().FullName, 103 GetTestBuilderName(test)); 104 return new FailCommand(test, ResultState.Failure, message); 105 } 106 } 107 108 command = new EnumerableSetUpTearDownCommand(command); 109 command = new OuterUnityTestActionCommand(command); 110 command = new RetryCommand(command); 111 command = new RepeatCommand(command); 112 113 IApplyToContext[] changes = test.Method.GetCustomAttributes<IApplyToContext>(true); 114 if (changes.Length > 0) 115 { 116 command = new EnumerableApplyChangesToContextCommand(command, changes); 117 } 118 119 command = new TimeoutCommand(command); 120 command = new IgnoreTestCommand(command, test); 121 command = new StrictCheckCommand(command); 122 return command; 123 } 124 125 private static string GetTestBuilderName(TestMethod testMethod) 126 { 127 return new[] 128 { 129 testMethod.Method.GetCustomAttributes<ITestBuilder>(true).Select(attribute => attribute.GetType().Name), 130 testMethod.Method.GetCustomAttributes<ISimpleTestBuilder>(true).Select(attribute => attribute.GetType().Name) 131 }.SelectMany(v => v).FirstOrDefault(); 132 } 133 134 private static TestCommand TryReplaceWithEnumerableCommand(TestCommand command) 135 { 136 switch (command.GetType().Name) 137 { 138 case nameof(RepeatAttribute.RepeatedTestCommand): 139 return new EnumerableRepeatedTestCommand(command as RepeatAttribute.RepeatedTestCommand); 140 case nameof(RetryAttribute.RetryCommand): 141 return new EnumerableRetryTestCommand(command as RetryAttribute.RetryCommand); 142 case nameof(MaxTimeCommand): 143 return new EnumerableMaxTimeCommand(command as MaxTimeCommand); 144 default: 145 return null; 146 } 147 } 148 } 149}