A game about forced loneliness, made by TACStudios
1using System;
2using System.Collections;
3using System.Collections.Generic;
4using System.Linq;
5using System.Reflection;
6using System.Runtime.ExceptionServices;
7using System.Threading.Tasks;
8using NUnit.Framework;
9using NUnit.Framework.Internal;
10using NUnit.Framework.Internal.Commands;
11using Unity.Profiling;
12using UnityEngine.TestRunner.NUnitExtensions.Runner;
13
14namespace UnityEngine.TestTools
15{
16 internal class SetUpTearDownCommand : BeforeAfterTestCommandBase<MethodInfo>
17 {
18 private static readonly Dictionary<Type, List<MethodInfo>> m_BeforeActionsCache = new Dictionary<Type, List<MethodInfo>>();
19 private static readonly Dictionary<Type, List<MethodInfo>> m_AfterActionsCache = new Dictionary<Type, List<MethodInfo>>();
20
21 public SetUpTearDownCommand(TestCommand innerCommand)
22 : base(innerCommand, "SetUp", "TearDown")
23 {
24 using (new ProfilerMarker(nameof(SetUpTearDownCommand)).Auto())
25 {
26 if (Test.TypeInfo.Type != null)
27 {
28 BeforeActions = GetActions(m_BeforeActionsCache, Test.TypeInfo.Type, typeof(SetUpAttribute), new[] {typeof(void), typeof(Task)});
29 AfterActions = GetActions(m_AfterActionsCache, Test.TypeInfo.Type, typeof(TearDownAttribute), new[] {typeof(void), typeof(Task)}).Reverse().ToArray();
30 }
31 }
32 }
33
34 protected override bool AllowFrameSkipAfterAction(MethodInfo action)
35 {
36 return action.ReturnType == typeof(Task);
37 }
38
39 protected override IEnumerator InvokeBefore(MethodInfo action, Test test, UnityTestExecutionContext context)
40 {
41 if (action.ReturnType == typeof(Task))
42 {
43 Task task;
44 using (new ProfilerMarker(test.Name + ".Setup").Auto())
45 task = HandleTaskCommand(action, context);
46 while (!task.IsCompleted)
47 {
48 yield return null;
49 }
50
51 if (task.IsFaulted)
52 {
53 ExceptionDispatchInfo.Capture(task.Exception.InnerExceptions.Count == 1 ? task.Exception.InnerException : task.Exception).Throw();
54 }
55 }
56 else
57 {
58 using (new ProfilerMarker(test.Name + ".Setup").Auto())
59 Reflect.InvokeMethod(action, context.TestObject);
60 yield return null;
61 }
62 }
63
64 protected override IEnumerator InvokeAfter(MethodInfo action, Test test, UnityTestExecutionContext context)
65 {
66 if (action.ReturnType == typeof(Task))
67 {
68 Task task;
69 using (new ProfilerMarker(test.Name + ".TearDown").Auto())
70 task = HandleTaskCommand(action, context);
71 while (!task.IsCompleted)
72 {
73 yield return null;
74 }
75
76 if (task.IsFaulted)
77 {
78 ExceptionDispatchInfo.Capture(task.Exception.InnerExceptions.Count == 1 ? task.Exception.InnerException : task.Exception).Throw();
79 }
80 }
81 else
82 {
83 using (new ProfilerMarker(test.Name + ".TearDown").Auto())
84 Reflect.InvokeMethod(action, context.TestObject);
85 yield return null;
86 }
87 }
88
89 private Task HandleTaskCommand(MethodInfo action, UnityTestExecutionContext context)
90 {
91 try
92 {
93 return Reflect.InvokeMethod(action, context.TestObject) as Task;
94 }
95 catch (TargetInvocationException e)
96 {
97 throw e;
98 }
99 }
100
101 protected override BeforeAfterTestCommandState GetState(UnityTestExecutionContext context)
102 {
103 // Normal Setup/Teardown does not support domain reloads and will not need a persisted state.
104 return new BeforeAfterTestCommandState();
105 }
106 }
107}