ConstructDelegator.cs
4.41 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
using System;
using System.Linq;
using NUnit.Framework.Internal;
using UnityEngine.TestRunner.NUnitExtensions.Runner;
using UnityEngine.TestTools.Logging;
using UnityEngine.TestTools.TestRunner;
namespace UnityEngine.TestTools.NUnitExtensions
{
/// <summary>
/// Specialization of BaseDelegator that makes sure objects are created on the MainThread.
/// It also deals with ScriptableObjects so that tests can survive assembly reload.
/// </summary>
internal class ConstructDelegator
{
private Type m_RequestedType;
private object[] m_Arguments;
private ScriptableObject m_CurrentRunningTest;
private readonly IStateSerializer m_StateSerializer;
protected Exception m_Exception;
protected object m_Result;
protected ITestExecutionContext m_Context;
public ConstructDelegator(IStateSerializer stateSerializer)
{
m_StateSerializer = stateSerializer;
}
protected object HandleResult()
{
SetCurrentTestContext();
if (m_Exception != null)
{
var temp = m_Exception;
m_Exception = null;
throw temp;
}
var tempResult = m_Result;
m_Result = null;
return tempResult;
}
protected void SetCurrentTestContext()
{
var prop = typeof(UnityTestExecutionContext).GetProperty("CurrentContext");
if (prop != null)
{
prop.SetValue(null, m_Context, null);
}
}
public object Delegate(Type type, object[] arguments)
{
AssertState();
m_Context = UnityTestExecutionContext.CurrentContext;
m_RequestedType = type;
m_Arguments = arguments;
using (var logScope = new LogScope())
{
Execute(logScope);
}
return HandleResult();
}
private void AssertState()
{
if (m_RequestedType != null)
{
throw new Exception("Constructor not executed yet");
}
}
public bool HasAction()
{
return m_RequestedType != null;
}
public void Execute(LogScope logScope)
{
try
{
if (typeof(ScriptableObject).IsAssignableFrom(m_RequestedType))
{
if (m_CurrentRunningTest != null && m_RequestedType != m_CurrentRunningTest.GetType())
{
DestroyCurrentTestObjectIfExists();
}
if (m_CurrentRunningTest == null)
{
if (m_StateSerializer.CanRestoreFromScriptableObject(m_RequestedType))
{
m_CurrentRunningTest = m_StateSerializer.RestoreScriptableObjectInstance();
}
else
{
m_CurrentRunningTest = ScriptableObject.CreateInstance(m_RequestedType);
}
}
m_Result = m_CurrentRunningTest;
}
else
{
DestroyCurrentTestObjectIfExists();
m_Result = Activator.CreateInstance(m_RequestedType, m_Arguments);
if (m_StateSerializer.CanRestoreFromJson(m_RequestedType))
{
m_StateSerializer.RestoreClassFromJson(ref m_Result);
}
}
if (logScope.AnyFailingLogs())
{
var failingLog = logScope.FailingLogs.First();
throw new UnhandledLogMessageException(failingLog);
}
if (logScope.ExpectedLogs.Any())
throw new UnexpectedLogMessageException(LogScope.Current.ExpectedLogs.Peek());
}
catch (Exception e)
{
m_Exception = e;
}
finally
{
m_RequestedType = null;
m_Arguments = null;
}
}
public void DestroyCurrentTestObjectIfExists()
{
if (m_CurrentRunningTest == null)
return;
Object.DestroyImmediate(m_CurrentRunningTest);
}
}
}