UnityGame/Library/PackageCache/com.unity.test-framework/UnityEditor.TestRunner/NUnitExtension/TestRunnerStateSerializer.cs
2024-10-27 10:53:47 +03:00

163 lines
5.1 KiB
C#

using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
using UnityEngine;
using UnityEngine.TestRunner.NUnitExtensions.Runner;
using UnityEngine.TestTools.Logging;
using UnityEngine.TestTools.NUnitExtensions;
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;
}
}
}
}