Firstborn/Library/PackageCache/com.unity.test-framework@1..../UnityEngine.TestRunner/NUnitExtensions/ConstructDelegator.cs

142 lines
4.4 KiB
C#
Raw Normal View History

2023-03-28 13:24:16 -04:00
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);
}
}
}