Commit af571a61 authored by BlackAngle233's avatar BlackAngle233
Browse files

212

parent 1d9b5391
using UnityEditor.TestTools.TestRunner.Api;
using UnityEditor.TestTools.TestRunner.CommandLineTest;
using UnityEngine.TestTools.TestRunner.GUI;
using UnityEngine;
namespace UnityEditor.TestTools.TestRunner
{
internal class RerunCallback : ScriptableObject, ICallbacks
{
public static bool useMockRunFilter = false;
public static TestRunnerFilter mockRunFilter = null;
public void RunFinished(ITestResultAdaptor result)
{
if (RerunCallbackData.instance.runFilters == null || RerunCallbackData.instance.runFilters.Length == 0)
RerunCallbackData.instance.runFilters = new[] {new TestRunnerFilter()};
var runFilter = RerunCallbackData.instance.runFilters[0];
if (useMockRunFilter)
{
runFilter = mockRunFilter;
}
runFilter.testRepetitions--;
if (runFilter.testRepetitions <= 0 || result.TestStatus != TestStatus.Passed)
{
ExitCallbacks.preventExit = false;
return;
}
ExitCallbacks.preventExit = true;
if (EditorApplication.isPlaying)
{
EditorApplication.playModeStateChanged += WaitForExitPlaymode;
return;
}
if (!useMockRunFilter)
{
ExecuteTestRunnerAPI();
}
}
private static void WaitForExitPlaymode(PlayModeStateChange state)
{
if (state == PlayModeStateChange.EnteredEditMode)
{
ExecuteTestRunnerAPI();
}
}
private static void ExecuteTestRunnerAPI()
{
var runFilter = RerunCallbackData.instance.runFilters[0];
var testMode = RerunCallbackData.instance.testMode;
var testRunnerApi = ScriptableObject.CreateInstance<TestRunnerApi>();
testRunnerApi.Execute(new Api.ExecutionSettings()
{
filters = new[]
{
new Filter()
{
categoryNames = runFilter.categoryNames,
groupNames = runFilter.groupNames,
testMode = testMode,
testNames = runFilter.testNames
}
}
});
}
public void TestStarted(ITestAdaptor test)
{
}
public void TestFinished(ITestResultAdaptor result)
{
}
public void RunStarted(ITestAdaptor testsToRun)
{
}
}
}
using UnityEditor.TestTools.TestRunner.Api;
using UnityEditor.TestTools.TestRunner.CommandLineTest;
using UnityEngine.TestTools.TestRunner.GUI;
using UnityEngine;
namespace UnityEditor.TestTools.TestRunner
{
internal class RerunCallback : ScriptableObject, ICallbacks
{
public static bool useMockRunFilter = false;
public static TestRunnerFilter mockRunFilter = null;
public void RunFinished(ITestResultAdaptor result)
{
if (RerunCallbackData.instance.runFilters == null || RerunCallbackData.instance.runFilters.Length == 0)
RerunCallbackData.instance.runFilters = new[] {new TestRunnerFilter()};
var runFilter = RerunCallbackData.instance.runFilters[0];
if (useMockRunFilter)
{
runFilter = mockRunFilter;
}
runFilter.testRepetitions--;
if (runFilter.testRepetitions <= 0 || result.TestStatus != TestStatus.Passed)
{
ExitCallbacks.preventExit = false;
return;
}
ExitCallbacks.preventExit = true;
if (EditorApplication.isPlaying)
{
EditorApplication.playModeStateChanged += WaitForExitPlaymode;
return;
}
if (!useMockRunFilter)
{
ExecuteTestRunnerAPI();
}
}
private static void WaitForExitPlaymode(PlayModeStateChange state)
{
if (state == PlayModeStateChange.EnteredEditMode)
{
ExecuteTestRunnerAPI();
}
}
private static void ExecuteTestRunnerAPI()
{
var runFilter = RerunCallbackData.instance.runFilters[0];
var testMode = RerunCallbackData.instance.testMode;
var testRunnerApi = ScriptableObject.CreateInstance<TestRunnerApi>();
testRunnerApi.Execute(new Api.ExecutionSettings()
{
filters = new[]
{
new Filter()
{
categoryNames = runFilter.categoryNames,
groupNames = runFilter.groupNames,
testMode = testMode,
testNames = runFilter.testNames
}
}
});
}
public void TestStarted(ITestAdaptor test)
{
}
public void TestFinished(ITestResultAdaptor result)
{
}
public void RunStarted(ITestAdaptor testsToRun)
{
}
}
}
fileFormatVersion: 2
guid: b7ff2b2e91321ff4381d4ab45870a32e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: b7ff2b2e91321ff4381d4ab45870a32e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
using UnityEditor.TestTools.TestRunner.Api;
using UnityEngine;
using UnityEngine.TestTools.TestRunner.GUI;
namespace UnityEditor.TestTools.TestRunner
{
internal class RerunCallbackData : ScriptableSingleton<RerunCallbackData>
{
[SerializeField]
internal TestRunnerFilter[] runFilters;
[SerializeField]
internal TestMode testMode;
}
}
using UnityEditor.TestTools.TestRunner.Api;
using UnityEngine;
using UnityEngine.TestTools.TestRunner.GUI;
namespace UnityEditor.TestTools.TestRunner
{
internal class RerunCallbackData : ScriptableSingleton<RerunCallbackData>
{
[SerializeField]
internal TestRunnerFilter[] runFilters;
[SerializeField]
internal TestMode testMode;
}
}
fileFormatVersion: 2
guid: 087cba9fa6ac867479a0b0fdc0a5864b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 087cba9fa6ac867479a0b0fdc0a5864b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
using UnityEngine;
using UnityEditor.TestTools.TestRunner.Api;
namespace UnityEditor.TestTools.TestRunner
{
[InitializeOnLoad]
static class RerunCallbackInitializer
{
static RerunCallbackInitializer()
{
var testRunnerApi = ScriptableObject.CreateInstance<TestRunnerApi>();
var rerunCallback = ScriptableObject.CreateInstance<RerunCallback>();
testRunnerApi.RegisterCallbacks<RerunCallback>(rerunCallback);
}
}
}
using UnityEngine;
using UnityEditor.TestTools.TestRunner.Api;
namespace UnityEditor.TestTools.TestRunner
{
[InitializeOnLoad]
static class RerunCallbackInitializer
{
static RerunCallbackInitializer()
{
var testRunnerApi = ScriptableObject.CreateInstance<TestRunnerApi>();
var rerunCallback = ScriptableObject.CreateInstance<RerunCallback>();
testRunnerApi.RegisterCallbacks<RerunCallback>(rerunCallback);
}
}
}
fileFormatVersion: 2
guid: f73fc901e4b0f2d4daf11f46506054ba
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: f73fc901e4b0f2d4daf11f46506054ba
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
using NUnit.Framework.Interfaces;
using UnityEngine;
using UnityEngine.TestTools.TestRunner;
namespace UnityEditor.TestTools.TestRunner
{
internal class TestRunnerCallback : ScriptableObject, ITestRunnerListener
{
public void RunStarted(ITest testsToRun)
{
EditorApplication.playModeStateChanged += OnPlayModeStateChanged;
}
private void OnPlayModeStateChanged(PlayModeStateChange state)
{
if (state == PlayModeStateChange.ExitingPlayMode)
{
EditorApplication.playModeStateChanged -= OnPlayModeStateChanged;
//We need to make sure we don't block NUnit thread in case we exit PlayMode earlier
PlaymodeTestsController.TryCleanup();
}
}
public void RunFinished(ITestResult testResults)
{
EditorApplication.isPlaying = false;
}
public void TestStarted(ITest testName)
{
}
public void TestFinished(ITestResult test)
{
}
}
}
using NUnit.Framework.Interfaces;
using UnityEngine;
using UnityEngine.TestTools.TestRunner;
namespace UnityEditor.TestTools.TestRunner
{
internal class TestRunnerCallback : ScriptableObject, ITestRunnerListener
{
public void RunStarted(ITest testsToRun)
{
EditorApplication.playModeStateChanged += OnPlayModeStateChanged;
}
private void OnPlayModeStateChanged(PlayModeStateChange state)
{
if (state == PlayModeStateChange.ExitingPlayMode)
{
EditorApplication.playModeStateChanged -= OnPlayModeStateChanged;
//We need to make sure we don't block NUnit thread in case we exit PlayMode earlier
PlaymodeTestsController.TryCleanup();
}
}
public void RunFinished(ITestResult testResults)
{
EditorApplication.isPlaying = false;
}
public void TestStarted(ITest testName)
{
}
public void TestFinished(ITestResult test)
{
}
}
}
fileFormatVersion: 2
guid: d44e6804bc58be84ea71a619b468f150
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: d44e6804bc58be84ea71a619b468f150
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
using System.Linq;
using TestRunner.Callbacks;
using UnityEditor.TestTools.TestRunner.Api;
namespace UnityEditor.TestTools.TestRunner.GUI
{
internal class WindowResultUpdater : ICallbacks, ITestTreeRebuildCallbacks
{
public WindowResultUpdater()
{
var cachedResults = WindowResultUpdaterDataHolder.instance.CachedResults;
var testList = TestRunnerWindow.s_Instance.m_SelectedTestTypes;
foreach (var result in cachedResults)
{
testList.UpdateResult(result);
}
cachedResults.Clear();
}
public void RunStarted(ITestAdaptor testsToRun)
{
}
public void RunFinished(ITestResultAdaptor testResults)
{
if (TestRunnerWindow.s_Instance != null)
{
TestRunnerWindow.s_Instance.RebuildUIFilter();
}
}
public void TestStarted(ITestAdaptor testName)
{
}
public void TestFinished(ITestResultAdaptor test)
{
var result = new TestRunnerResult(test);
if (TestRunnerWindow.s_Instance == null)
{
WindowResultUpdaterDataHolder.instance.CachedResults.Add(result);
return;
}
TestRunnerWindow.s_Instance.m_SelectedTestTypes.UpdateResult(result);
}
public void TestTreeRebuild(ITestAdaptor test)
{
if (TestRunnerWindow.s_Instance == null)
{
return;
}
TestRunnerWindow.s_Instance.m_SelectedTestTypes.UpdateTestTree(test);
}
}
}
using System.Linq;
using TestRunner.Callbacks;
using UnityEditor.TestTools.TestRunner.Api;
namespace UnityEditor.TestTools.TestRunner.GUI
{
internal class WindowResultUpdater : ICallbacks, ITestTreeRebuildCallbacks
{
public WindowResultUpdater()
{
var cachedResults = WindowResultUpdaterDataHolder.instance.CachedResults;
var testList = TestRunnerWindow.s_Instance.m_SelectedTestTypes;
foreach (var result in cachedResults)
{
testList.UpdateResult(result);
}
cachedResults.Clear();
}
public void RunStarted(ITestAdaptor testsToRun)
{
}
public void RunFinished(ITestResultAdaptor testResults)
{
if (TestRunnerWindow.s_Instance != null)
{
TestRunnerWindow.s_Instance.RebuildUIFilter();
}
}
public void TestStarted(ITestAdaptor testName)
{
}
public void TestFinished(ITestResultAdaptor test)
{
var result = new TestRunnerResult(test);
if (TestRunnerWindow.s_Instance == null)
{
WindowResultUpdaterDataHolder.instance.CachedResults.Add(result);
return;
}
TestRunnerWindow.s_Instance.m_SelectedTestTypes.UpdateResult(result);
}
public void TestTreeRebuild(ITestAdaptor test)
{
if (TestRunnerWindow.s_Instance == null)
{
return;
}
TestRunnerWindow.s_Instance.m_SelectedTestTypes.UpdateTestTree(test);
}
}
}
fileFormatVersion: 2
guid: 6d468ee3657be7a43a2ef2178ec14239
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 6d468ee3657be7a43a2ef2178ec14239
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
using System.Collections.Generic;
using UnityEditor;
using UnityEditor.TestTools.TestRunner.GUI;
namespace TestRunner.Callbacks
{
internal class WindowResultUpdaterDataHolder : ScriptableSingleton<WindowResultUpdaterDataHolder>
{
public List<TestRunnerResult> CachedResults = new List<TestRunnerResult>();
}
using System.Collections.Generic;
using UnityEditor;
using UnityEditor.TestTools.TestRunner.GUI;
namespace TestRunner.Callbacks
{
internal class WindowResultUpdaterDataHolder : ScriptableSingleton<WindowResultUpdaterDataHolder>
{
public List<TestRunnerResult> CachedResults = new List<TestRunnerResult>();
}
}
\ No newline at end of file
fileFormatVersion: 2
guid: 82075836be5e0c64bbe84e1f9436682e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 82075836be5e0c64bbe84e1f9436682e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
using System.Collections;
using System.Reflection;
using UnityEngine.TestTools;
namespace UnityEditor.TestTools.TestRunner
{
internal class EditModePcHelper : TestCommandPcHelper
{
public override void SetEnumeratorPC(IEnumerator enumerator, int pc)
{
GetPCFieldInfo(enumerator).SetValue(enumerator, pc);
}
public override int GetEnumeratorPC(IEnumerator enumerator)
{
if (enumerator == null)
{
return 0;
}
return (int)GetPCFieldInfo(enumerator).GetValue(enumerator);
}
private FieldInfo GetPCFieldInfo(IEnumerator enumerator)
{
var field = enumerator.GetType().GetField("$PC", BindingFlags.NonPublic | BindingFlags.Instance);
if (field == null) // Roslyn
field = enumerator.GetType().GetField("<>1__state", BindingFlags.NonPublic | BindingFlags.Instance);
return field;
}
}
}
using System.Collections;
using System.Reflection;
using UnityEngine.TestTools;
namespace UnityEditor.TestTools.TestRunner
{
internal class EditModePcHelper : TestCommandPcHelper
{
public override void SetEnumeratorPC(IEnumerator enumerator, int pc)
{
GetPCFieldInfo(enumerator).SetValue(enumerator, pc);
}
public override int GetEnumeratorPC(IEnumerator enumerator)
{
if (enumerator == null)
{
return 0;
}
return (int)GetPCFieldInfo(enumerator).GetValue(enumerator);
}
private FieldInfo GetPCFieldInfo(IEnumerator enumerator)
{
var field = enumerator.GetType().GetField("$PC", BindingFlags.NonPublic | BindingFlags.Instance);
if (field == null) // Roslyn
field = enumerator.GetType().GetField("<>1__state", BindingFlags.NonPublic | BindingFlags.Instance);
return field;
}
}
}
fileFormatVersion: 2
guid: 6d16f2e78a356d34c9a32108929de932
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 6d16f2e78a356d34c9a32108929de932
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework.Interfaces;
using NUnit.Framework.Internal;
using NUnit.Framework.Internal.Filters;
using UnityEngine;
using UnityEngine.TestTools.NUnitExtensions;
using UnityEngine.TestTools.TestRunner;
using UnityEngine.TestTools;
using UnityEngine.TestTools.TestRunner.GUI;
using UnityEditor.Callbacks;
using UnityEditor.TestTools.TestRunner.Api;
using UnityEngine.TestRunner.NUnitExtensions;
using UnityEngine.TestRunner.NUnitExtensions.Runner;
namespace UnityEditor.TestTools.TestRunner
{
internal interface IUnityTestAssemblyRunnerFactory
{
IUnityTestAssemblyRunner Create(TestPlatform testPlatform, WorkItemFactory factory);
}
internal class UnityTestAssemblyRunnerFactory : IUnityTestAssemblyRunnerFactory
{
public IUnityTestAssemblyRunner Create(TestPlatform testPlatform, WorkItemFactory factory)
{
return new UnityTestAssemblyRunner(new UnityTestAssemblyBuilder(), factory);
}
}
[Serializable]
internal class EditModeRunner : ScriptableObject, IDisposable
{
[SerializeField]
private Filter[] m_Filters;
//The counter from the IEnumerator object
[SerializeField]
private int m_CurrentPC;
[SerializeField]
private bool m_ExecuteOnEnable;
[SerializeField]
private List<string> m_AlreadyStartedTests;
[SerializeField]
private List<TestResultSerializer> m_ExecutedTests;
[SerializeField]
private List<ScriptableObject> m_CallbackObjects = new List<ScriptableObject>();
[SerializeField]
private TestStartedEvent m_TestStartedEvent = new TestStartedEvent();
[SerializeField]
private TestFinishedEvent m_TestFinishedEvent = new TestFinishedEvent();
[SerializeField]
private RunStartedEvent m_RunStartedEvent = new RunStartedEvent();
[SerializeField]
private RunFinishedEvent m_RunFinishedEvent = new RunFinishedEvent();
[SerializeField]
private TestRunnerStateSerializer m_TestRunnerStateSerializer = new TestRunnerStateSerializer();
[SerializeField]
private bool m_RunningTests;
[SerializeField]
private TestPlatform m_TestPlatform;
[SerializeField]
private object m_CurrentYieldObject;
[SerializeField]
private BeforeAfterTestCommandState m_SetUpTearDownState;
[SerializeField]
private BeforeAfterTestCommandState m_OuterUnityTestActionState;
[SerializeField]
public bool RunFinished = false;
public bool RunningSynchronously { get; private set; }
internal IUnityTestAssemblyRunner m_Runner;
private ConstructDelegator m_ConstructDelegator;
private IEnumerator m_RunStep;
public IUnityTestAssemblyRunnerFactory UnityTestAssemblyRunnerFactory { get; set; }
public void Init(Filter[] filters, TestPlatform platform, bool runningSynchronously)
{
m_Filters = filters;
m_TestPlatform = platform;
m_AlreadyStartedTests = new List<string>();
m_ExecutedTests = new List<TestResultSerializer>();
RunningSynchronously = runningSynchronously;
InitRunner();
}
private void InitRunner()
{
//We give the EditMode platform here so we dont suddenly create Playmode work items in the test Runner.
m_Runner = (UnityTestAssemblyRunnerFactory ?? new UnityTestAssemblyRunnerFactory()).Create(TestPlatform.EditMode, new EditmodeWorkItemFactory());
var testAssemblyProvider = new EditorLoadedTestAssemblyProvider(new EditorCompilationInterfaceProxy(), new EditorAssembliesProxy());
var assemblies = testAssemblyProvider.GetAssembliesGroupedByType(m_TestPlatform).Select(x => x.Assembly).ToArray();
var loadedTests = m_Runner.Load(assemblies, TestPlatform.EditMode,
UnityTestAssemblyBuilder.GetNUnitTestBuilderSettings(m_TestPlatform));
loadedTests.ParseForNameDuplicates();
CallbacksDelegator.instance.TestTreeRebuild(loadedTests);
hideFlags |= HideFlags.DontSave;
EnumerableSetUpTearDownCommand.ActivePcHelper = new EditModePcHelper();
OuterUnityTestActionCommand.ActivePcHelper = new EditModePcHelper();
}
public void OnEnable()
{
if (m_ExecuteOnEnable)
{
InitRunner();
m_ExecuteOnEnable = false;
foreach (var callback in m_CallbackObjects)
{
AddListeners(callback as ITestRunnerListener);
}
m_ConstructDelegator = new ConstructDelegator(m_TestRunnerStateSerializer);
EnumeratorStepHelper.SetEnumeratorPC(m_CurrentPC);
UnityWorkItemDataHolder.alreadyExecutedTests = m_ExecutedTests.Select(x => x.uniqueName).ToList();
UnityWorkItemDataHolder.alreadyStartedTests = m_AlreadyStartedTests;
Run();
}
}
public void TestStartedEvent(ITest test)
{
m_AlreadyStartedTests.Add(test.GetUniqueName());
}
public void TestFinishedEvent(ITestResult testResult)
{
m_AlreadyStartedTests.Remove(testResult.Test.GetUniqueName());
m_ExecutedTests.Add(TestResultSerializer.MakeFromTestResult(testResult));
}
public void Run()
{
EditModeTestCallbacks.RestoringTestContext += OnRestoringTest;
var context = m_Runner.GetCurrentContext();
if (m_SetUpTearDownState == null)
{
m_SetUpTearDownState = CreateInstance<BeforeAfterTestCommandState>();
}
context.SetUpTearDownState = m_SetUpTearDownState;
if (m_OuterUnityTestActionState == null)
{
m_OuterUnityTestActionState = CreateInstance<BeforeAfterTestCommandState>();
}
context.OuterUnityTestActionState = m_OuterUnityTestActionState;
if (!m_RunningTests)
{
m_RunStartedEvent.Invoke(m_Runner.LoadedTest);
}
if (m_ConstructDelegator == null)
m_ConstructDelegator = new ConstructDelegator(m_TestRunnerStateSerializer);
Reflect.ConstructorCallWrapper = m_ConstructDelegator.Delegate;
m_TestStartedEvent.AddListener(TestStartedEvent);
m_TestFinishedEvent.AddListener(TestFinishedEvent);
AssemblyReloadEvents.beforeAssemblyReload += OnBeforeAssemblyReload;
RunningTests = true;
EditorApplication.LockReloadAssemblies();
var testListenerWrapper = new TestListenerWrapper(m_TestStartedEvent, m_TestFinishedEvent);
m_RunStep = m_Runner.Run(testListenerWrapper, GetFilter()).GetEnumerator();
m_RunningTests = true;
if (!RunningSynchronously)
EditorApplication.update += TestConsumer;
}
public void CompleteSynchronously()
{
while (!m_Runner.IsTestComplete)
TestConsumer();
}
private void OnBeforeAssemblyReload()
{
EditorApplication.update -= TestConsumer;
if (m_ExecuteOnEnable)
{
AssemblyReloadEvents.beforeAssemblyReload -= OnBeforeAssemblyReload;
return;
}
if (m_Runner != null && m_Runner.TopLevelWorkItem != null)
m_Runner.TopLevelWorkItem.ResultedInDomainReload = true;
if (RunningTests)
{
Debug.LogError("TestRunner: Unexpected assembly reload happened while running tests");
EditorUtility.ClearProgressBar();
if (m_Runner.GetCurrentContext() != null && m_Runner.GetCurrentContext().CurrentResult != null)
{
m_Runner.GetCurrentContext().CurrentResult.SetResult(ResultState.Cancelled, "Unexpected assembly reload happened");
}
OnRunCancel();
}
}
private bool RunningTests;
private Stack<IEnumerator> StepStack = new Stack<IEnumerator>();
private bool MoveNextAndUpdateYieldObject()
{
var result = m_RunStep.MoveNext();
if (result)
{
m_CurrentYieldObject = m_RunStep.Current;
while (m_CurrentYieldObject is IEnumerator) // going deeper
{
var currentEnumerator = (IEnumerator)m_CurrentYieldObject;
// go deeper and add parent to stack
StepStack.Push(m_RunStep);
m_RunStep = currentEnumerator;
m_CurrentYieldObject = m_RunStep.Current;
}
if (StepStack.Count > 0 && m_CurrentYieldObject != null) // not null and not IEnumerator, nested
{
Debug.LogError("EditMode test can only yield null, but not <" + m_CurrentYieldObject.GetType().Name + ">");
}
return true;
}
if (StepStack.Count == 0) // done
return false;
m_RunStep = StepStack.Pop(); // going up
return MoveNextAndUpdateYieldObject();
}
private void TestConsumer()
{
var moveNext = MoveNextAndUpdateYieldObject();
if (m_CurrentYieldObject != null)
{
InvokeDelegator();
}
if (!moveNext && !m_Runner.IsTestComplete)
{
CompleteTestRun();
throw new IndexOutOfRangeException("There are no more elements to process and IsTestComplete is false");
}
if (m_Runner.IsTestComplete)
{
CompleteTestRun();
}
}
private void CompleteTestRun()
{
if (!RunningSynchronously)
EditorApplication.update -= TestConsumer;
TestLauncherBase.ExecutePostBuildCleanupMethods(this.GetLoadedTests(), this.GetFilter(), Application.platform);
m_RunFinishedEvent.Invoke(m_Runner.Result);
RunFinished = true;
if (m_ConstructDelegator != null)
m_ConstructDelegator.DestroyCurrentTestObjectIfExists();
Dispose();
UnityWorkItemDataHolder.alreadyExecutedTests = null;
}
private void OnRestoringTest()
{
var item = m_ExecutedTests.Find(t => t.fullName == UnityTestExecutionContext.CurrentContext.CurrentTest.FullName);
if (item != null)
{
item.RestoreTestResult(UnityTestExecutionContext.CurrentContext.CurrentResult);
}
}
private static bool IsCancelled()
{
return UnityTestExecutionContext.CurrentContext.ExecutionStatus == TestExecutionStatus.AbortRequested || UnityTestExecutionContext.CurrentContext.ExecutionStatus == TestExecutionStatus.StopRequested;
}
private void InvokeDelegator()
{
if (m_CurrentYieldObject == null)
{
return;
}
if (IsCancelled())
{
return;
}
if (m_CurrentYieldObject is RestoreTestContextAfterDomainReload)
{
if (m_TestRunnerStateSerializer.ShouldRestore())
{
m_TestRunnerStateSerializer.RestoreContext();
}
return;
}
try
{
if (m_CurrentYieldObject is IEditModeTestYieldInstruction)
{
var editModeTestYieldInstruction = (IEditModeTestYieldInstruction)m_CurrentYieldObject;
if (editModeTestYieldInstruction.ExpectDomainReload)
{
PrepareForDomainReload();
}
return;
}
}
catch (Exception e)
{
UnityTestExecutionContext.CurrentContext.CurrentResult.RecordException(e);
return;
}
Debug.LogError("EditMode test can only yield null");
}
private void CompilationFailureWatch()
{
if (EditorApplication.isCompiling)
return;
EditorApplication.update -= CompilationFailureWatch;
if (EditorUtility.scriptCompilationFailed)
{
EditorUtility.ClearProgressBar();
OnRunCancel();
}
}
private void PrepareForDomainReload()
{
m_TestRunnerStateSerializer.SaveContext();
m_CurrentPC = EnumeratorStepHelper.GetEnumeratorPC(TestEnumerator.Enumerator);
m_ExecuteOnEnable = true;
RunningTests = false;
}
public T AddEventHandler<T>() where T : ScriptableObject, ITestRunnerListener
{
var eventHandler = CreateInstance<T>();
eventHandler.hideFlags |= HideFlags.DontSave;
m_CallbackObjects.Add(eventHandler);
AddListeners(eventHandler);
return eventHandler;
}
private void AddListeners(ITestRunnerListener eventHandler)
{
m_TestStartedEvent.AddListener(eventHandler.TestStarted);
m_TestFinishedEvent.AddListener(eventHandler.TestFinished);
m_RunStartedEvent.AddListener(eventHandler.RunStarted);
m_RunFinishedEvent.AddListener(eventHandler.RunFinished);
}
public void Dispose()
{
Reflect.MethodCallWrapper = null;
EditorApplication.update -= TestConsumer;
DestroyImmediate(this);
if (m_CallbackObjects != null)
{
foreach (var obj in m_CallbackObjects)
{
DestroyImmediate(obj);
}
m_CallbackObjects.Clear();
}
RunningTests = false;
EditorApplication.UnlockReloadAssemblies();
}
public void OnRunCancel()
{
UnityWorkItemDataHolder.alreadyExecutedTests = null;
m_ExecuteOnEnable = false;
m_Runner.StopRun();
RunFinished = true;
}
public ITest GetLoadedTests()
{
return m_Runner.LoadedTest;
}
public ITestFilter GetFilter()
{
return new OrFilter(m_Filters.Select(filter => filter.BuildNUnitFilter(RunningSynchronously)).ToArray());
}
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework.Interfaces;
using NUnit.Framework.Internal;
using NUnit.Framework.Internal.Filters;
using UnityEngine;
using UnityEngine.TestTools.NUnitExtensions;
using UnityEngine.TestTools.TestRunner;
using UnityEngine.TestTools;
using UnityEngine.TestTools.TestRunner.GUI;
using UnityEditor.Callbacks;
using UnityEditor.TestTools.TestRunner.Api;
using UnityEngine.TestRunner.NUnitExtensions;
using UnityEngine.TestRunner.NUnitExtensions.Runner;
namespace UnityEditor.TestTools.TestRunner
{
internal interface IUnityTestAssemblyRunnerFactory
{
IUnityTestAssemblyRunner Create(TestPlatform testPlatform, WorkItemFactory factory);
}
internal class UnityTestAssemblyRunnerFactory : IUnityTestAssemblyRunnerFactory
{
public IUnityTestAssemblyRunner Create(TestPlatform testPlatform, WorkItemFactory factory)
{
return new UnityTestAssemblyRunner(new UnityTestAssemblyBuilder(), factory);
}
}
[Serializable]
internal class EditModeRunner : ScriptableObject, IDisposable
{
[SerializeField]
private Filter[] m_Filters;
//The counter from the IEnumerator object
[SerializeField]
private int m_CurrentPC;
[SerializeField]
private bool m_ExecuteOnEnable;
[SerializeField]
private List<string> m_AlreadyStartedTests;
[SerializeField]
private List<TestResultSerializer> m_ExecutedTests;
[SerializeField]
private List<ScriptableObject> m_CallbackObjects = new List<ScriptableObject>();
[SerializeField]
private TestStartedEvent m_TestStartedEvent = new TestStartedEvent();
[SerializeField]
private TestFinishedEvent m_TestFinishedEvent = new TestFinishedEvent();
[SerializeField]
private RunStartedEvent m_RunStartedEvent = new RunStartedEvent();
[SerializeField]
private RunFinishedEvent m_RunFinishedEvent = new RunFinishedEvent();
[SerializeField]
private TestRunnerStateSerializer m_TestRunnerStateSerializer = new TestRunnerStateSerializer();
[SerializeField]
private bool m_RunningTests;
[SerializeField]
private TestPlatform m_TestPlatform;
[SerializeField]
private object m_CurrentYieldObject;
[SerializeField]
private BeforeAfterTestCommandState m_SetUpTearDownState;
[SerializeField]
private BeforeAfterTestCommandState m_OuterUnityTestActionState;
[SerializeField]
public bool RunFinished = false;
public bool RunningSynchronously { get; private set; }
internal IUnityTestAssemblyRunner m_Runner;
private ConstructDelegator m_ConstructDelegator;
private IEnumerator m_RunStep;
public IUnityTestAssemblyRunnerFactory UnityTestAssemblyRunnerFactory { get; set; }
public void Init(Filter[] filters, TestPlatform platform, bool runningSynchronously)
{
m_Filters = filters;
m_TestPlatform = platform;
m_AlreadyStartedTests = new List<string>();
m_ExecutedTests = new List<TestResultSerializer>();
RunningSynchronously = runningSynchronously;
InitRunner();
}
private void InitRunner()
{
//We give the EditMode platform here so we dont suddenly create Playmode work items in the test Runner.
m_Runner = (UnityTestAssemblyRunnerFactory ?? new UnityTestAssemblyRunnerFactory()).Create(TestPlatform.EditMode, new EditmodeWorkItemFactory());
var testAssemblyProvider = new EditorLoadedTestAssemblyProvider(new EditorCompilationInterfaceProxy(), new EditorAssembliesProxy());
var assemblies = testAssemblyProvider.GetAssembliesGroupedByType(m_TestPlatform).Select(x => x.Assembly).ToArray();
var loadedTests = m_Runner.Load(assemblies, TestPlatform.EditMode,
UnityTestAssemblyBuilder.GetNUnitTestBuilderSettings(m_TestPlatform));
loadedTests.ParseForNameDuplicates();
CallbacksDelegator.instance.TestTreeRebuild(loadedTests);
hideFlags |= HideFlags.DontSave;
EnumerableSetUpTearDownCommand.ActivePcHelper = new EditModePcHelper();
OuterUnityTestActionCommand.ActivePcHelper = new EditModePcHelper();
}
public void OnEnable()
{
if (m_ExecuteOnEnable)
{
InitRunner();
m_ExecuteOnEnable = false;
foreach (var callback in m_CallbackObjects)
{
AddListeners(callback as ITestRunnerListener);
}
m_ConstructDelegator = new ConstructDelegator(m_TestRunnerStateSerializer);
EnumeratorStepHelper.SetEnumeratorPC(m_CurrentPC);
UnityWorkItemDataHolder.alreadyExecutedTests = m_ExecutedTests.Select(x => x.uniqueName).ToList();
UnityWorkItemDataHolder.alreadyStartedTests = m_AlreadyStartedTests;
Run();
}
}
public void TestStartedEvent(ITest test)
{
m_AlreadyStartedTests.Add(test.GetUniqueName());
}
public void TestFinishedEvent(ITestResult testResult)
{
m_AlreadyStartedTests.Remove(testResult.Test.GetUniqueName());
m_ExecutedTests.Add(TestResultSerializer.MakeFromTestResult(testResult));
}
public void Run()
{
EditModeTestCallbacks.RestoringTestContext += OnRestoringTest;
var context = m_Runner.GetCurrentContext();
if (m_SetUpTearDownState == null)
{
m_SetUpTearDownState = CreateInstance<BeforeAfterTestCommandState>();
}
context.SetUpTearDownState = m_SetUpTearDownState;
if (m_OuterUnityTestActionState == null)
{
m_OuterUnityTestActionState = CreateInstance<BeforeAfterTestCommandState>();
}
context.OuterUnityTestActionState = m_OuterUnityTestActionState;
if (!m_RunningTests)
{
m_RunStartedEvent.Invoke(m_Runner.LoadedTest);
}
if (m_ConstructDelegator == null)
m_ConstructDelegator = new ConstructDelegator(m_TestRunnerStateSerializer);
Reflect.ConstructorCallWrapper = m_ConstructDelegator.Delegate;
m_TestStartedEvent.AddListener(TestStartedEvent);
m_TestFinishedEvent.AddListener(TestFinishedEvent);
AssemblyReloadEvents.beforeAssemblyReload += OnBeforeAssemblyReload;
RunningTests = true;
EditorApplication.LockReloadAssemblies();
var testListenerWrapper = new TestListenerWrapper(m_TestStartedEvent, m_TestFinishedEvent);
m_RunStep = m_Runner.Run(testListenerWrapper, GetFilter()).GetEnumerator();
m_RunningTests = true;
if (!RunningSynchronously)
EditorApplication.update += TestConsumer;
}
public void CompleteSynchronously()
{
while (!m_Runner.IsTestComplete)
TestConsumer();
}
private void OnBeforeAssemblyReload()
{
EditorApplication.update -= TestConsumer;
if (m_ExecuteOnEnable)
{
AssemblyReloadEvents.beforeAssemblyReload -= OnBeforeAssemblyReload;
return;
}
if (m_Runner != null && m_Runner.TopLevelWorkItem != null)
m_Runner.TopLevelWorkItem.ResultedInDomainReload = true;
if (RunningTests)
{
Debug.LogError("TestRunner: Unexpected assembly reload happened while running tests");
EditorUtility.ClearProgressBar();
if (m_Runner.GetCurrentContext() != null && m_Runner.GetCurrentContext().CurrentResult != null)
{
m_Runner.GetCurrentContext().CurrentResult.SetResult(ResultState.Cancelled, "Unexpected assembly reload happened");
}
OnRunCancel();
}
}
private bool RunningTests;
private Stack<IEnumerator> StepStack = new Stack<IEnumerator>();
private bool MoveNextAndUpdateYieldObject()
{
var result = m_RunStep.MoveNext();
if (result)
{
m_CurrentYieldObject = m_RunStep.Current;
while (m_CurrentYieldObject is IEnumerator) // going deeper
{
var currentEnumerator = (IEnumerator)m_CurrentYieldObject;
// go deeper and add parent to stack
StepStack.Push(m_RunStep);
m_RunStep = currentEnumerator;
m_CurrentYieldObject = m_RunStep.Current;
}
if (StepStack.Count > 0 && m_CurrentYieldObject != null) // not null and not IEnumerator, nested
{
Debug.LogError("EditMode test can only yield null, but not <" + m_CurrentYieldObject.GetType().Name + ">");
}
return true;
}
if (StepStack.Count == 0) // done
return false;
m_RunStep = StepStack.Pop(); // going up
return MoveNextAndUpdateYieldObject();
}
private void TestConsumer()
{
var moveNext = MoveNextAndUpdateYieldObject();
if (m_CurrentYieldObject != null)
{
InvokeDelegator();
}
if (!moveNext && !m_Runner.IsTestComplete)
{
CompleteTestRun();
throw new IndexOutOfRangeException("There are no more elements to process and IsTestComplete is false");
}
if (m_Runner.IsTestComplete)
{
CompleteTestRun();
}
}
private void CompleteTestRun()
{
if (!RunningSynchronously)
EditorApplication.update -= TestConsumer;
TestLauncherBase.ExecutePostBuildCleanupMethods(this.GetLoadedTests(), this.GetFilter(), Application.platform);
m_RunFinishedEvent.Invoke(m_Runner.Result);
RunFinished = true;
if (m_ConstructDelegator != null)
m_ConstructDelegator.DestroyCurrentTestObjectIfExists();
Dispose();
UnityWorkItemDataHolder.alreadyExecutedTests = null;
}
private void OnRestoringTest()
{
var item = m_ExecutedTests.Find(t => t.fullName == UnityTestExecutionContext.CurrentContext.CurrentTest.FullName);
if (item != null)
{
item.RestoreTestResult(UnityTestExecutionContext.CurrentContext.CurrentResult);
}
}
private static bool IsCancelled()
{
return UnityTestExecutionContext.CurrentContext.ExecutionStatus == TestExecutionStatus.AbortRequested || UnityTestExecutionContext.CurrentContext.ExecutionStatus == TestExecutionStatus.StopRequested;
}
private void InvokeDelegator()
{
if (m_CurrentYieldObject == null)
{
return;
}
if (IsCancelled())
{
return;
}
if (m_CurrentYieldObject is RestoreTestContextAfterDomainReload)
{
if (m_TestRunnerStateSerializer.ShouldRestore())
{
m_TestRunnerStateSerializer.RestoreContext();
}
return;
}
try
{
if (m_CurrentYieldObject is IEditModeTestYieldInstruction)
{
var editModeTestYieldInstruction = (IEditModeTestYieldInstruction)m_CurrentYieldObject;
if (editModeTestYieldInstruction.ExpectDomainReload)
{
PrepareForDomainReload();
}
return;
}
}
catch (Exception e)
{
UnityTestExecutionContext.CurrentContext.CurrentResult.RecordException(e);
return;
}
Debug.LogError("EditMode test can only yield null");
}
private void CompilationFailureWatch()
{
if (EditorApplication.isCompiling)
return;
EditorApplication.update -= CompilationFailureWatch;
if (EditorUtility.scriptCompilationFailed)
{
EditorUtility.ClearProgressBar();
OnRunCancel();
}
}
private void PrepareForDomainReload()
{
m_TestRunnerStateSerializer.SaveContext();
m_CurrentPC = EnumeratorStepHelper.GetEnumeratorPC(TestEnumerator.Enumerator);
m_ExecuteOnEnable = true;
RunningTests = false;
}
public T AddEventHandler<T>() where T : ScriptableObject, ITestRunnerListener
{
var eventHandler = CreateInstance<T>();
eventHandler.hideFlags |= HideFlags.DontSave;
m_CallbackObjects.Add(eventHandler);
AddListeners(eventHandler);
return eventHandler;
}
private void AddListeners(ITestRunnerListener eventHandler)
{
m_TestStartedEvent.AddListener(eventHandler.TestStarted);
m_TestFinishedEvent.AddListener(eventHandler.TestFinished);
m_RunStartedEvent.AddListener(eventHandler.RunStarted);
m_RunFinishedEvent.AddListener(eventHandler.RunFinished);
}
public void Dispose()
{
Reflect.MethodCallWrapper = null;
EditorApplication.update -= TestConsumer;
DestroyImmediate(this);
if (m_CallbackObjects != null)
{
foreach (var obj in m_CallbackObjects)
{
DestroyImmediate(obj);
}
m_CallbackObjects.Clear();
}
RunningTests = false;
EditorApplication.UnlockReloadAssemblies();
}
public void OnRunCancel()
{
UnityWorkItemDataHolder.alreadyExecutedTests = null;
m_ExecuteOnEnable = false;
m_Runner.StopRun();
RunFinished = true;
}
public ITest GetLoadedTests()
{
return m_Runner.LoadedTest;
}
public ITestFilter GetFilter()
{
return new OrFilter(m_Filters.Select(filter => filter.BuildNUnitFilter(RunningSynchronously)).ToArray());
}
}
}
fileFormatVersion: 2
guid: c9219e99d466b7741a057132d1994f35
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: c9219e99d466b7741a057132d1994f35
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
using NUnit.Framework.Interfaces;
using NUnit.Framework.Internal;
using UnityEngine.TestRunner.NUnitExtensions.Runner;
namespace UnityEditor.TestTools.TestRunner
{
internal class EditmodeWorkItemFactory : WorkItemFactory
{
protected override UnityWorkItem Create(TestMethod method, ITestFilter filter, ITest loadedTest)
{
return new EditorEnumeratorTestWorkItem(method, filter);
}
}
}
using NUnit.Framework.Interfaces;
using NUnit.Framework.Internal;
using UnityEngine.TestRunner.NUnitExtensions.Runner;
namespace UnityEditor.TestTools.TestRunner
{
internal class EditmodeWorkItemFactory : WorkItemFactory
{
protected override UnityWorkItem Create(TestMethod method, ITestFilter filter, ITest loadedTest)
{
return new EditorEnumeratorTestWorkItem(method, filter);
}
}
}
fileFormatVersion: 2
guid: 3dde15f260b0dd1469e60d16eaa795dc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 3dde15f260b0dd1469e60d16eaa795dc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
using System;
using System.Collections;
using NUnit.Framework.Interfaces;
using NUnit.Framework.Internal;
using NUnit.Framework.Internal.Commands;
using NUnit.Framework.Internal.Execution;
using UnityEngine;
using UnityEngine.TestRunner.NUnitExtensions.Runner;
using UnityEngine.TestTools;
namespace UnityEditor.TestTools.TestRunner
{
internal class EditorEnumeratorTestWorkItem : UnityWorkItem
{
private TestCommand m_Command;
public EditorEnumeratorTestWorkItem(TestMethod test, ITestFilter filter)
: base(test, null)
{
m_Command = TestCommandBuilder.BuildTestCommand(test, filter);
}
private static IEnumerableTestMethodCommand FindFirstIEnumerableTestMethodCommand(TestCommand command)
{
if (command == null)
{
return null;
}
if (command is IEnumerableTestMethodCommand)
{
return (IEnumerableTestMethodCommand)command;
}
if (command is DelegatingTestCommand)
{
var delegatingTestCommand = (DelegatingTestCommand)command;
return FindFirstIEnumerableTestMethodCommand(delegatingTestCommand.GetInnerCommand());
}
return null;
}
protected override IEnumerable PerformWork()
{
if (IsCancelledRun())
{
yield break;
}
if (m_DontRunRestoringResult)
{
if (EditModeTestCallbacks.RestoringTestContext == null)
{
throw new NullReferenceException("RestoringTestContext is not set");
}
EditModeTestCallbacks.RestoringTestContext();
Result = Context.CurrentResult;
yield break;
}
try
{
if (IsCancelledRun())
{
yield break;
}
if (m_Command is SkipCommand)
{
m_Command.Execute(Context);
Result = Context.CurrentResult;
yield break;
}
//Check if we can execute this test
var firstEnumerableCommand = FindFirstIEnumerableTestMethodCommand(m_Command);
if (firstEnumerableCommand == null)
{
Context.CurrentResult.SetResult(ResultState.Error, "Returning IEnumerator but not using test attribute supporting this");
yield break;
}
if (m_Command.Test.Method.ReturnType.IsType(typeof(IEnumerator)))
{
if (m_Command is ApplyChangesToContextCommand)
{
var applyChangesToContextCommand = ((ApplyChangesToContextCommand)m_Command);
applyChangesToContextCommand.ApplyChanges(Context);
m_Command = applyChangesToContextCommand.GetInnerCommand();
}
var innerCommand = m_Command as IEnumerableTestMethodCommand;
if (innerCommand == null)
{
Debug.Log("failed getting innerCommand");
throw new Exception("Tests returning IEnumerator can only use test attributes handling those");
}
foreach (var workItemStep in innerCommand.ExecuteEnumerable(Context))
{
if (IsCancelledRun())
{
yield break;
}
if (workItemStep is TestEnumerator)
{
if (EnumeratorStepHelper.UpdateEnumeratorPcIfNeeded(TestEnumerator.Enumerator))
{
yield return new RestoreTestContextAfterDomainReload();
}
continue;
}
if (workItemStep is AsyncOperation)
{
var asyncOperation = (AsyncOperation)workItemStep;
while (!asyncOperation.isDone)
{
if (IsCancelledRun())
{
yield break;
}
yield return null;
}
continue;
}
ResultedInDomainReload = false;
if (workItemStep is IEditModeTestYieldInstruction)
{
var editModeTestYieldInstruction = (IEditModeTestYieldInstruction)workItemStep;
yield return editModeTestYieldInstruction;
var enumerator = editModeTestYieldInstruction.Perform();
while (true)
{
bool moveNext;
try
{
moveNext = enumerator.MoveNext();
}
catch (Exception e)
{
Context.CurrentResult.RecordException(e);
break;
}
if (!moveNext)
{
break;
}
yield return null;
}
}
else
{
yield return workItemStep;
}
}
Result = Context.CurrentResult;
EditorApplication.isPlaying = false;
yield return null;
}
}
finally
{
WorkItemComplete();
}
}
private bool IsCancelledRun()
{
return Context.ExecutionStatus == TestExecutionStatus.AbortRequested || Context.ExecutionStatus == TestExecutionStatus.StopRequested;
}
}
}
using System;
using System.Collections;
using NUnit.Framework.Interfaces;
using NUnit.Framework.Internal;
using NUnit.Framework.Internal.Commands;
using NUnit.Framework.Internal.Execution;
using UnityEngine;
using UnityEngine.TestRunner.NUnitExtensions.Runner;
using UnityEngine.TestTools;
namespace UnityEditor.TestTools.TestRunner
{
internal class EditorEnumeratorTestWorkItem : UnityWorkItem
{
private TestCommand m_Command;
public EditorEnumeratorTestWorkItem(TestMethod test, ITestFilter filter)
: base(test, null)
{
m_Command = TestCommandBuilder.BuildTestCommand(test, filter);
}
private static IEnumerableTestMethodCommand FindFirstIEnumerableTestMethodCommand(TestCommand command)
{
if (command == null)
{
return null;
}
if (command is IEnumerableTestMethodCommand)
{
return (IEnumerableTestMethodCommand)command;
}
if (command is DelegatingTestCommand)
{
var delegatingTestCommand = (DelegatingTestCommand)command;
return FindFirstIEnumerableTestMethodCommand(delegatingTestCommand.GetInnerCommand());
}
return null;
}
protected override IEnumerable PerformWork()
{
if (IsCancelledRun())
{
yield break;
}
if (m_DontRunRestoringResult)
{
if (EditModeTestCallbacks.RestoringTestContext == null)
{
throw new NullReferenceException("RestoringTestContext is not set");
}
EditModeTestCallbacks.RestoringTestContext();
Result = Context.CurrentResult;
yield break;
}
try
{
if (IsCancelledRun())
{
yield break;
}
if (m_Command is SkipCommand)
{
m_Command.Execute(Context);
Result = Context.CurrentResult;
yield break;
}
//Check if we can execute this test
var firstEnumerableCommand = FindFirstIEnumerableTestMethodCommand(m_Command);
if (firstEnumerableCommand == null)
{
Context.CurrentResult.SetResult(ResultState.Error, "Returning IEnumerator but not using test attribute supporting this");
yield break;
}
if (m_Command.Test.Method.ReturnType.IsType(typeof(IEnumerator)))
{
if (m_Command is ApplyChangesToContextCommand)
{
var applyChangesToContextCommand = ((ApplyChangesToContextCommand)m_Command);
applyChangesToContextCommand.ApplyChanges(Context);
m_Command = applyChangesToContextCommand.GetInnerCommand();
}
var innerCommand = m_Command as IEnumerableTestMethodCommand;
if (innerCommand == null)
{
Debug.Log("failed getting innerCommand");
throw new Exception("Tests returning IEnumerator can only use test attributes handling those");
}
foreach (var workItemStep in innerCommand.ExecuteEnumerable(Context))
{
if (IsCancelledRun())
{
yield break;
}
if (workItemStep is TestEnumerator)
{
if (EnumeratorStepHelper.UpdateEnumeratorPcIfNeeded(TestEnumerator.Enumerator))
{
yield return new RestoreTestContextAfterDomainReload();
}
continue;
}
if (workItemStep is AsyncOperation)
{
var asyncOperation = (AsyncOperation)workItemStep;
while (!asyncOperation.isDone)
{
if (IsCancelledRun())
{
yield break;
}
yield return null;
}
continue;
}
ResultedInDomainReload = false;
if (workItemStep is IEditModeTestYieldInstruction)
{
var editModeTestYieldInstruction = (IEditModeTestYieldInstruction)workItemStep;
yield return editModeTestYieldInstruction;
var enumerator = editModeTestYieldInstruction.Perform();
while (true)
{
bool moveNext;
try
{
moveNext = enumerator.MoveNext();
}
catch (Exception e)
{
Context.CurrentResult.RecordException(e);
break;
}
if (!moveNext)
{
break;
}
yield return null;
}
}
else
{
yield return workItemStep;
}
}
Result = Context.CurrentResult;
EditorApplication.isPlaying = false;
yield return null;
}
}
finally
{
WorkItemComplete();
}
}
private bool IsCancelledRun()
{
return Context.ExecutionStatus == TestExecutionStatus.AbortRequested || Context.ExecutionStatus == TestExecutionStatus.StopRequested;
}
}
}
fileFormatVersion: 2
guid: 1ebc1994f9a3d5649a1201d3a84b38df
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 1ebc1994f9a3d5649a1201d3a84b38df
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment