2023-06-21 13:28:15 -04:00
|
|
|
using System;
|
|
|
|
using System.Reflection;
|
|
|
|
using System.Text;
|
|
|
|
using System.Collections.Generic;
|
|
|
|
using UnityEngine;
|
|
|
|
using UnityEngine.TestRunner.NUnitExtensions.Runner;
|
|
|
|
using UnityEngine.TestTools.NUnitExtensions;
|
|
|
|
using UnityEngine.TestTools.Logging;
|
|
|
|
|
|
|
|
namespace UnityEditor.TestTools.TestRunner
|
|
|
|
{
|
|
|
|
[Serializable]
|
|
|
|
internal class TestRunnerStateSerializer : IStateSerializer
|
|
|
|
{
|
|
|
|
private const BindingFlags Flags = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy;
|
|
|
|
|
|
|
|
[SerializeField]
|
|
|
|
private HideFlags m_OriginalHideFlags;
|
|
|
|
|
|
|
|
[SerializeField]
|
|
|
|
private bool m_ShouldRestore;
|
|
|
|
|
|
|
|
[SerializeField]
|
|
|
|
private string m_TestObjectTypeName;
|
|
|
|
|
|
|
|
[SerializeField]
|
|
|
|
private ScriptableObject m_TestObject;
|
|
|
|
|
|
|
|
[SerializeField]
|
|
|
|
private string m_TestObjectTxt;
|
|
|
|
|
|
|
|
[SerializeField]
|
|
|
|
private long StartTicks;
|
|
|
|
|
|
|
|
[SerializeField]
|
|
|
|
private double StartTimeOA;
|
|
|
|
|
|
|
|
[SerializeField]
|
|
|
|
private string output;
|
|
|
|
|
|
|
|
[SerializeField]
|
|
|
|
private LogMatch[] m_ExpectedLogs;
|
|
|
|
|
|
|
|
public bool ShouldRestore()
|
|
|
|
{
|
|
|
|
return m_ShouldRestore;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void SaveContext()
|
|
|
|
{
|
|
|
|
var currentContext = UnityTestExecutionContext.CurrentContext;
|
|
|
|
|
|
|
|
if (currentContext.TestObject != null)
|
|
|
|
{
|
|
|
|
m_TestObjectTypeName = currentContext.TestObject.GetType().AssemblyQualifiedName;
|
|
|
|
m_TestObject = null;
|
|
|
|
m_TestObjectTxt = null;
|
|
|
|
if (currentContext.TestObject is ScriptableObject)
|
|
|
|
{
|
|
|
|
m_TestObject = currentContext.TestObject as ScriptableObject;
|
|
|
|
m_OriginalHideFlags = m_TestObject.hideFlags;
|
|
|
|
m_TestObject.hideFlags |= HideFlags.DontSave;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
m_TestObjectTxt = JsonUtility.ToJson(currentContext.TestObject);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
output = currentContext.CurrentResult.Output;
|
|
|
|
StartTicks = currentContext.StartTicks;
|
|
|
|
StartTimeOA = currentContext.StartTime.ToOADate();
|
|
|
|
if (LogScope.HasCurrentLogScope())
|
|
|
|
{
|
|
|
|
m_ExpectedLogs = LogScope.Current.ExpectedLogs.ToArray();
|
|
|
|
}
|
|
|
|
|
|
|
|
m_ShouldRestore = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void RestoreContext()
|
|
|
|
{
|
|
|
|
var currentContext = UnityTestExecutionContext.CurrentContext;
|
|
|
|
|
|
|
|
var outputProp = currentContext.CurrentResult.GetType().BaseType.GetField("_output", Flags);
|
|
|
|
(outputProp.GetValue(currentContext.CurrentResult) as StringBuilder).Append(output);
|
|
|
|
|
|
|
|
currentContext.StartTicks = StartTicks;
|
|
|
|
currentContext.StartTime = DateTime.FromOADate(StartTimeOA);
|
|
|
|
if (LogScope.HasCurrentLogScope())
|
|
|
|
{
|
|
|
|
LogScope.Current.ExpectedLogs = new Queue<LogMatch>(m_ExpectedLogs);
|
|
|
|
}
|
|
|
|
|
|
|
|
m_ShouldRestore = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
public bool CanRestoreFromScriptableObject(Type requestedType)
|
|
|
|
{
|
|
|
|
if (m_TestObject == null)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return m_TestObjectTypeName == requestedType.AssemblyQualifiedName;
|
|
|
|
}
|
|
|
|
|
|
|
|
public ScriptableObject RestoreScriptableObjectInstance()
|
|
|
|
{
|
|
|
|
if (m_TestObject == null)
|
|
|
|
{
|
|
|
|
Debug.LogError("No object to restore");
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
EditorApplication.playModeStateChanged += OnPlayModeStateChanged;
|
|
|
|
var temp = m_TestObject;
|
|
|
|
m_TestObject = null;
|
|
|
|
m_TestObjectTypeName = null;
|
|
|
|
return temp;
|
|
|
|
}
|
|
|
|
|
|
|
|
public bool CanRestoreFromJson(Type requestedType)
|
|
|
|
{
|
|
|
|
if (string.IsNullOrEmpty(m_TestObjectTxt))
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return m_TestObjectTypeName == requestedType.AssemblyQualifiedName;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void RestoreClassFromJson(ref object instance)
|
|
|
|
{
|
|
|
|
if (string.IsNullOrEmpty(m_TestObjectTxt))
|
|
|
|
{
|
|
|
|
Debug.LogWarning("No JSON representation to restore");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
JsonUtility.FromJsonOverwrite(m_TestObjectTxt, instance);
|
|
|
|
m_TestObjectTxt = null;
|
|
|
|
m_TestObjectTypeName = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
private void OnPlayModeStateChanged(PlayModeStateChange state)
|
|
|
|
{
|
|
|
|
if (m_TestObject == null)
|
|
|
|
{
|
|
|
|
EditorApplication.playModeStateChanged -= OnPlayModeStateChanged;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
//We set the DontSave flag here because the ScriptableObject would be nulled right before entering EditMode
|
|
|
|
if (state == PlayModeStateChange.ExitingPlayMode)
|
|
|
|
{
|
|
|
|
m_TestObject.hideFlags |= HideFlags.DontSave;
|
|
|
|
}
|
|
|
|
else if (state == PlayModeStateChange.EnteredEditMode)
|
|
|
|
{
|
|
|
|
m_TestObject.hideFlags = m_OriginalHideFlags;
|
|
|
|
EditorApplication.playModeStateChanged -= OnPlayModeStateChanged;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|