A game about forced loneliness, made by TACStudios
1using System;
2using System.Collections;
3using NUnit.Framework.Interfaces;
4using NUnit.Framework.Internal;
5using NUnit.Framework.Internal.Commands;
6using Unity.Profiling;
7using UnityEngine.TestRunner.NUnitExtensions.Runner;
8using UnityEngine.TestTools.TestRunner;
9
10namespace UnityEngine.TestTools
11{
12 internal class EnumerableTestMethodCommand : TestCommand, IEnumerableTestMethodCommand
13 {
14 private readonly TestMethod testMethod;
15
16 public EnumerableTestMethodCommand(TestMethod testMethod)
17 : base(testMethod)
18 {
19 this.testMethod = testMethod;
20 }
21
22 public IEnumerable ExecuteEnumerable(ITestExecutionContext context)
23 {
24 var unityContext = (UnityTestExecutionContext) context;
25 yield return null;
26
27 IEnumerator currentExecutingTestEnumerator;
28 try
29 {
30 currentExecutingTestEnumerator = new TestEnumeratorWrapper(testMethod).GetEnumerator(context);
31 }
32 catch (Exception ex)
33 {
34 context.CurrentResult.RecordException(ex);
35 yield break;
36 }
37
38 if (currentExecutingTestEnumerator != null)
39 {
40 var testEnumeraterYieldInstruction = new TestEnumerator(context, currentExecutingTestEnumerator);
41
42 yield return testEnumeraterYieldInstruction;
43
44 var enumerator = testEnumeraterYieldInstruction.Execute();
45
46 var executingEnumerator = ExecuteEnumerableAndRecordExceptions(enumerator, new EnumeratorContext(context), unityContext);
47 while (AdvanceEnumerator(executingEnumerator))
48 {
49 yield return executingEnumerator.Current;
50 }
51 }
52 else
53 {
54 if (context.CurrentResult.ResultState != ResultState.Ignored)
55 {
56 context.CurrentResult.SetResult(ResultState.Success);
57 }
58 }
59 }
60
61 private bool AdvanceEnumerator(IEnumerator enumerator)
62 {
63 using (new ProfilerMarker(testMethod.MethodName).Auto())
64 return enumerator.MoveNext();
65 }
66
67 private IEnumerator ExecuteEnumerableAndRecordExceptions(IEnumerator enumerator, EnumeratorContext context, UnityTestExecutionContext unityContext)
68 {
69 while (true)
70 {
71 if (context.ExceptionWasRecorded)
72 {
73 break;
74 }
75
76 try
77 {
78 if (!enumerator.MoveNext())
79 {
80 break;
81 }
82 if (unityContext.TestMode == TestPlatform.PlayMode && enumerator.Current is IEditModeTestYieldInstruction)
83 {
84 throw new Exception($"PlayMode test are not allowed to yield {enumerator.Current.GetType().Name}");
85 }
86 }
87 catch (Exception ex)
88 {
89 context.RecordExceptionWithHint(ex);
90 break;
91 }
92
93 if (enumerator.Current is IEnumerator nestedEnumerator)
94 {
95 yield return ExecuteEnumerableAndRecordExceptions(nestedEnumerator, context, unityContext);
96 }
97 else
98 {
99 yield return enumerator.Current;
100 }
101 }
102 }
103
104 private class EnumeratorContext
105 {
106 private readonly ITestExecutionContext m_Context;
107
108 public EnumeratorContext(ITestExecutionContext context)
109 {
110 m_Context = context;
111 }
112
113 public bool ExceptionWasRecorded
114 {
115 get;
116 private set;
117 }
118
119 public void RecordExceptionWithHint(Exception ex)
120 {
121 if (ExceptionWasRecorded)
122 {
123 return;
124 }
125 m_Context.CurrentResult.RecordException(ex);
126 ExceptionWasRecorded = true;
127 }
128 }
129
130
131 public override TestResult Execute(ITestExecutionContext context)
132 {
133 throw new NotImplementedException("Use ExecuteEnumerable");
134 }
135 }
136}