135 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			135 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| using System;
 | |
| using NUnit.Framework.Internal;
 | |
| using UnityEngine.TestRunner.NUnitExtensions.Runner;
 | |
| using UnityEngine.TestTools.Logging;
 | |
| 
 | |
| 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;
 | |
| 
 | |
|         protected 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);
 | |
|                     }
 | |
|                 }
 | |
|                 logScope.EvaluateLogScope(true);
 | |
|             }
 | |
|             catch (Exception e)
 | |
|             {
 | |
|                 m_Exception = e;
 | |
|             }
 | |
|             finally
 | |
|             {
 | |
|                 m_RequestedType = null;
 | |
|                 m_Arguments = null;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         public void DestroyCurrentTestObjectIfExists()
 | |
|         {
 | |
|             if (m_CurrentRunningTest != null)
 | |
|             {
 | |
|                 Object.DestroyImmediate(m_CurrentRunningTest);
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| }
 |