test
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5d7f0d6acfced954682a89e7002c04d9
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,50 @@
|
||||
using System;
|
||||
using TestRunner.Callbacks;
|
||||
using UnityEditor.TestTools.TestRunner.Api;
|
||||
|
||||
namespace UnityEditor.TestTools.TestRunner.GUI
|
||||
{
|
||||
internal class WindowResultUpdater : ICallbacks
|
||||
{
|
||||
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();
|
||||
TestRunnerWindow.s_Instance.m_SelectedTestTypes.RunFinished(testResults);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6d468ee3657be7a43a2ef2178ec14239
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,12 @@
|
||||
using System;
|
||||
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>();
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 82075836be5e0c64bbe84e1f9436682e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,33 @@
|
||||
using System;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6d16f2e78a356d34c9a32108929de932
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,328 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NUnit.Framework.Interfaces;
|
||||
using NUnit.Framework.Internal;
|
||||
using UnityEngine;
|
||||
using UnityEngine.TestRunner.NUnitExtensions;
|
||||
using UnityEngine.TestRunner.NUnitExtensions.Runner;
|
||||
using UnityEngine.TestTools;
|
||||
using UnityEngine.TestTools.NUnitExtensions;
|
||||
using UnityEngine.TestTools.TestRunner;
|
||||
|
||||
namespace UnityEditor.TestTools.TestRunner
|
||||
{
|
||||
internal interface IUnityTestAssemblyRunnerFactory
|
||||
{
|
||||
IUnityTestAssemblyRunner Create(TestPlatform testPlatform, string[] orderedTestNames, int randomOrderSeed, WorkItemFactory factory, UnityTestExecutionContext context);
|
||||
}
|
||||
|
||||
internal class UnityTestAssemblyRunnerFactory : IUnityTestAssemblyRunnerFactory
|
||||
{
|
||||
public IUnityTestAssemblyRunner Create(TestPlatform testPlatform, string[] orderedTestNames, int randomOrderSeed,
|
||||
WorkItemFactory factory, UnityTestExecutionContext context)
|
||||
{
|
||||
return new UnityTestAssemblyRunner(new UnityTestAssemblyBuilder(orderedTestNames, randomOrderSeed), factory, context);
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
internal class EditModeRunner : ScriptableObject, IDisposable
|
||||
{
|
||||
//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;
|
||||
|
||||
private TestStartedEvent m_TestStartedEvent;
|
||||
private TestFinishedEvent m_TestFinishedEvent;
|
||||
|
||||
[SerializeField]
|
||||
private object m_CurrentYieldObject;
|
||||
|
||||
[SerializeField]
|
||||
private string[] m_OrderedTestNames;
|
||||
|
||||
[SerializeField]
|
||||
public bool RunFinished;
|
||||
|
||||
[SerializeField]
|
||||
private bool m_DisableNestedEnumeratorBugfix;
|
||||
|
||||
public bool RunningSynchronously { get; private set; }
|
||||
|
||||
internal IUnityTestAssemblyRunner m_Runner;
|
||||
|
||||
private IEnumerator m_RunStep;
|
||||
|
||||
public IUnityTestAssemblyRunnerFactory UnityTestAssemblyRunnerFactory { get; set; }
|
||||
|
||||
public void Init(ITestFilter filter, bool runningSynchronously, ITest testTree, TestStartedEvent testStartedEvent, TestFinishedEvent testFinishedEvent, UnityTestExecutionContext context,
|
||||
string[] orderedTestNames, int randomOrderSeed, bool disableNestedEnumeratorBugfix)
|
||||
{
|
||||
TestEnumerator.Reset();
|
||||
m_AlreadyStartedTests = new List<string>();
|
||||
m_ExecutedTests = new List<TestResultSerializer>();
|
||||
m_OrderedTestNames = orderedTestNames;
|
||||
m_randomOrderSeed = randomOrderSeed;
|
||||
RunningSynchronously = runningSynchronously;
|
||||
m_DisableNestedEnumeratorBugfix = disableNestedEnumeratorBugfix;
|
||||
Run(testTree, filter, context, testStartedEvent, testFinishedEvent);
|
||||
}
|
||||
|
||||
public void Resume(ITestFilter filter, ITest testTree, TestStartedEvent testStartedEvent, TestFinishedEvent testFinishedEvent, UnityTestExecutionContext context)
|
||||
{
|
||||
if (m_ExecuteOnEnable)
|
||||
{
|
||||
m_ExecuteOnEnable = false;
|
||||
|
||||
if (m_CurrentPC >= 0)
|
||||
{
|
||||
EnumeratorStepHelper.SetEnumeratorPC(m_CurrentPC);
|
||||
}
|
||||
|
||||
UnityWorkItemDataHolder.alreadyExecutedTests = m_ExecutedTests.Select(x => x.uniqueName).ToList();
|
||||
UnityWorkItemDataHolder.alreadyStartedTests = m_AlreadyStartedTests;
|
||||
Run(testTree, filter, context, testStartedEvent, testFinishedEvent);
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
private void Run(ITest testTree, ITestFilter filter, UnityTestExecutionContext context, TestStartedEvent testStartedEvent, TestFinishedEvent testFinishedEvent)
|
||||
{
|
||||
m_TestStartedEvent = testStartedEvent;
|
||||
m_TestFinishedEvent = testFinishedEvent;
|
||||
|
||||
m_Runner = (UnityTestAssemblyRunnerFactory ?? new UnityTestAssemblyRunnerFactory()).Create(TestPlatform.EditMode, m_OrderedTestNames, m_randomOrderSeed, new EditmodeWorkItemFactory(), context);
|
||||
m_Runner.LoadTestTree(testTree);
|
||||
hideFlags |= HideFlags.DontSave;
|
||||
EnumeratorHelper.ActivePcHelper = new EditModePcHelper();
|
||||
|
||||
EditModeTestCallbacks.RestoringTestContext += OnRestoringTest;
|
||||
|
||||
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, filter).GetEnumerator();
|
||||
}
|
||||
|
||||
private void OnBeforeAssemblyReload()
|
||||
{
|
||||
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 int m_randomOrderSeed;
|
||||
|
||||
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 (!m_DisableNestedEnumeratorBugfix)
|
||||
{
|
||||
return MoveNextAndUpdateYieldObject();
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
public void TestConsumer(TestRunnerStateSerializer testRunnerStateSerializer)
|
||||
{
|
||||
var moveNext = MoveNextAndUpdateYieldObject();
|
||||
|
||||
if (m_CurrentYieldObject != null)
|
||||
{
|
||||
InvokeDelegator(testRunnerStateSerializer);
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
RunFinished = true;
|
||||
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(TestRunnerStateSerializer testRunnerStateSerializer)
|
||||
{
|
||||
if (m_CurrentYieldObject == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsCancelled())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_CurrentYieldObject is RestoreTestContextAfterDomainReload)
|
||||
{
|
||||
if (testRunnerStateSerializer.ShouldRestore())
|
||||
{
|
||||
testRunnerStateSerializer.RestoreContext();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (m_CurrentYieldObject is IEditModeTestYieldInstruction)
|
||||
{
|
||||
var editModeTestYieldInstruction = (IEditModeTestYieldInstruction)m_CurrentYieldObject;
|
||||
if (editModeTestYieldInstruction.ExpectDomainReload)
|
||||
{
|
||||
PrepareForDomainReload(testRunnerStateSerializer);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
UnityTestExecutionContext.CurrentContext.CurrentResult.RecordException(e);
|
||||
return;
|
||||
}
|
||||
|
||||
UnityTestExecutionContext.CurrentContext.CurrentResult.RecordException(new InvalidOperationException("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(TestRunnerStateSerializer testRunnerStateSerializer)
|
||||
{
|
||||
testRunnerStateSerializer.SaveContext();
|
||||
m_CurrentPC = EnumeratorStepHelper.GetEnumeratorPC(TestEnumerator.Enumerator);
|
||||
m_ExecuteOnEnable = true;
|
||||
|
||||
RunningTests = false;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Reflect.MethodCallWrapper = null;
|
||||
|
||||
DestroyImmediate(this);
|
||||
|
||||
RunningTests = false;
|
||||
EditorApplication.UnlockReloadAssemblies();
|
||||
}
|
||||
|
||||
public void OnRunCancel()
|
||||
{
|
||||
UnityWorkItemDataHolder.alreadyExecutedTests = null;
|
||||
m_ExecuteOnEnable = false;
|
||||
m_Runner.StopRun();
|
||||
RunFinished = true;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c9219e99d466b7741a057132d1994f35
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3dde15f260b0dd1469e60d16eaa795dc
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,180 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using NUnit.Framework.Interfaces;
|
||||
using NUnit.Framework.Internal;
|
||||
using NUnit.Framework.Internal.Commands;
|
||||
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 (Context.TestCaseTimeout == 0)
|
||||
{
|
||||
Context.TestCaseTimeout = k_DefaultTimeout;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1ebc1994f9a3d5649a1201d3a84b38df
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,52 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Reflection;
|
||||
|
||||
namespace UnityEditor.TestTools.TestRunner
|
||||
{
|
||||
internal class EnumeratorStepHelper
|
||||
{
|
||||
private static int m_PC;
|
||||
|
||||
public static void SetEnumeratorPC(int pc)
|
||||
{
|
||||
m_PC = pc;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current enumerator PC
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The PC
|
||||
/// 0 if no current Enumeration
|
||||
/// </returns>
|
||||
public static int GetEnumeratorPC(IEnumerator enumerator)
|
||||
{
|
||||
if (enumerator == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return (int)GetPCFieldInfo(enumerator).GetValue(enumerator);
|
||||
}
|
||||
|
||||
public static bool UpdateEnumeratorPcIfNeeded(IEnumerator enumerator)
|
||||
{
|
||||
if (m_PC != 0)
|
||||
{
|
||||
GetPCFieldInfo(enumerator).SetValue(enumerator, m_PC);
|
||||
m_PC = 0;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static 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;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 901b761c5c1e22d4e8a3ba7d95bc1f5d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d9682e749d3efc642af54d789d9090a6
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,57 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using UnityEditor;
|
||||
|
||||
namespace UnityEngine.TestTools
|
||||
{
|
||||
/// <summary>
|
||||
/// Implements <see cref="IEditModeTestYieldInstruction"/>. Creates a yield instruction to enter Play Mode.
|
||||
/// </summary>
|
||||
public class EnterPlayMode : IEditModeTestYieldInstruction
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns true if the instruction expects a domain reload to occur.
|
||||
/// </summary>
|
||||
public bool ExpectDomainReload { get; }
|
||||
/// <summary>
|
||||
/// Returns true if the instruction expects the Unity Editor to be in **Play Mode**.
|
||||
/// </summary>
|
||||
public bool ExpectedPlaymodeState { get; private set; }
|
||||
/// <summary>
|
||||
/// When creating an Editor test that uses the UnityTest attribute, use this to trigger the Editor to enter Play Mode.
|
||||
/// Throws an exception if the Editor is already in Play Mode or if there is a script compilation error.
|
||||
/// </summary>
|
||||
/// <param name="expectDomainReload">A flag indication whether to expect a domain reload.</param>
|
||||
public EnterPlayMode(bool expectDomainReload = true)
|
||||
{
|
||||
ExpectDomainReload = expectDomainReload;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs the multi-step instructions of entering PlayMode.
|
||||
/// </summary>
|
||||
/// <returns>An IEnumerator with the async steps.</returns>
|
||||
/// <exception cref="Exception">An exception is thrown if the editor is already in PlayMode or if script compilation failed.</exception>
|
||||
public IEnumerator Perform()
|
||||
{
|
||||
if (EditorApplication.isPlaying)
|
||||
{
|
||||
throw new Exception("Editor is already in PlayMode");
|
||||
}
|
||||
if (EditorUtility.scriptCompilationFailed)
|
||||
{
|
||||
throw new Exception("Script compilation failed");
|
||||
}
|
||||
yield return null;
|
||||
ExpectedPlaymodeState = true;
|
||||
|
||||
EditorApplication.UnlockReloadAssemblies();
|
||||
EditorApplication.isPlaying = true;
|
||||
|
||||
while (!EditorApplication.isPlaying)
|
||||
{
|
||||
yield return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9bd5a110ed89025499ddee8c7e73778e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,48 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using UnityEditor;
|
||||
|
||||
namespace UnityEngine.TestTools
|
||||
{
|
||||
/// <summary>
|
||||
/// Implements <see cref="IEditModeTestYieldInstruction"/>. A new instance of the class is a yield instruction to exit Play Mode.
|
||||
/// </summary>
|
||||
public class ExitPlayMode : IEditModeTestYieldInstruction
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the value of ExpectDomainReload
|
||||
/// </summary>
|
||||
public bool ExpectDomainReload { get; }
|
||||
/// <summary>
|
||||
/// Gets the value of ExpectedPlaymodeState
|
||||
/// </summary>
|
||||
public bool ExpectedPlaymodeState { get; private set; }
|
||||
/// <summary>
|
||||
/// Sets ExpectDomainReload and ExpectedPlaymodeState to false.
|
||||
/// </summary>
|
||||
public ExitPlayMode()
|
||||
{
|
||||
ExpectDomainReload = false;
|
||||
ExpectedPlaymodeState = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs the multi-step instruction of exiting PlayMode.
|
||||
/// </summary>
|
||||
/// <returns>An IEnumerator with the async steps.</returns>
|
||||
/// <exception cref="Exception">An exception is thrown if the editor is not in PlayMode.</exception>
|
||||
public IEnumerator Perform()
|
||||
{
|
||||
if (!EditorApplication.isPlayingOrWillChangePlaymode)
|
||||
{
|
||||
throw new Exception("Editor is already in EditMode");
|
||||
}
|
||||
|
||||
EditorApplication.isPlaying = false;
|
||||
while (EditorApplication.isPlaying)
|
||||
{
|
||||
yield return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 408674d91d506a54aac9a7f07951c018
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,112 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using UnityEditor;
|
||||
|
||||
namespace UnityEngine.TestTools
|
||||
{
|
||||
/// <summary>
|
||||
/// `RecompileScripts` is an <see cref="IEditModeTestYieldInstruction"/> that you can yield in Edit Mode tests. It lets you trigger a recompilation of scripts in the Unity Editor.
|
||||
/// </summary>
|
||||
public class RecompileScripts : IEditModeTestYieldInstruction
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new instance of the `RecompileScripts` yield instruction.
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// [UnitySetUp]
|
||||
/// public IEnumerator SetUp()
|
||||
/// {
|
||||
/// using (var file = File.CreateText("Assets/temp/myScript.cs"))
|
||||
/// {
|
||||
/// file.Write("public class ATempClass { }");
|
||||
/// }
|
||||
/// AssetDatabase.Refresh();
|
||||
/// yield return new RecompileScripts();
|
||||
/// }
|
||||
/// </code>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
public RecompileScripts() : this(true)
|
||||
{
|
||||
}
|
||||
/// <summary>
|
||||
/// Creates a new instance of the `RecompileScripts` yield instruction.
|
||||
/// </summary>
|
||||
/// <param name="expectScriptCompilation">This parameter indicates if you expect a script compilation to start (defaults to true). If a script compilation does not start and `expectScriptCompilation` is true, then it throws an exception.</param>
|
||||
public RecompileScripts(bool expectScriptCompilation) : this(expectScriptCompilation, true)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the `RecompileScripts` yield instruction.
|
||||
/// </summary>
|
||||
/// <param name="expectScriptCompilation">This parameter indicates if you expect a script compilation to start (defaults to true). If a script compilation does not start and `expectScriptCompilation` is `true`, then it throws an exception.</param>
|
||||
/// <param name="expectScriptCompilationSuccess">This parameter indicates if you expect a script compilation to succeed. If not succeeded then an exception will be thrown.</param>
|
||||
public RecompileScripts(bool expectScriptCompilation, bool expectScriptCompilationSuccess)
|
||||
{
|
||||
ExpectScriptCompilation = expectScriptCompilation;
|
||||
ExpectScriptCompilationSuccess = expectScriptCompilationSuccess;
|
||||
ExpectDomainReload = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the instruction expects a domain reload to occur.
|
||||
/// </summary>
|
||||
public bool ExpectDomainReload { get; private set; }
|
||||
/// <summary>
|
||||
/// Returns true if the instruction expects the Unity Editor to be in **Play Mode**.
|
||||
/// </summary>
|
||||
public bool ExpectedPlaymodeState { get; }
|
||||
/// <summary>
|
||||
/// Indicates whether a script compilation is expected.
|
||||
/// </summary>
|
||||
public bool ExpectScriptCompilation { get; private set; }
|
||||
/// <summary>
|
||||
/// Indicates whether the expected script compilation is expected to succeed.
|
||||
/// </summary>
|
||||
public bool ExpectScriptCompilationSuccess { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The current active instance of the RecompileScripts yield instruction.
|
||||
/// </summary>
|
||||
public static RecompileScripts Current { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Perform the multi step instruction of triggering a recompilation of scripts and waiting for its completion.
|
||||
/// </summary>
|
||||
/// <returns>An IEnumerator with the async steps.</returns>
|
||||
/// <exception cref="Exception">Throws an exception if the editor does not need to recompile scripts or if the script compilation failed when expected to succeed.</exception>
|
||||
public IEnumerator Perform()
|
||||
{
|
||||
Current = this;
|
||||
|
||||
// We need to yield, to give the test runner a chance to prepare for the domain reload
|
||||
// If the script compilation happens very fast, then EditModeRunner.MoveNextAndUpdateYieldObject will not have a chance to set m_CurrentYieldObject
|
||||
// This really should be fixed in EditModeRunner.MoveNextAndUpdateYieldObject
|
||||
yield return null;
|
||||
|
||||
AssetDatabase.Refresh();
|
||||
|
||||
if (ExpectScriptCompilation && !EditorApplication.isCompiling)
|
||||
{
|
||||
Current = null;
|
||||
throw new Exception("Editor does not need to recompile scripts");
|
||||
}
|
||||
|
||||
EditorApplication.UnlockReloadAssemblies();
|
||||
|
||||
while (EditorApplication.isCompiling)
|
||||
{
|
||||
yield return null;
|
||||
}
|
||||
|
||||
Current = null;
|
||||
|
||||
if (ExpectScriptCompilationSuccess && EditorUtility.scriptCompilationFailed)
|
||||
{
|
||||
EditorApplication.LockReloadAssemblies();
|
||||
throw new Exception("Script compilation failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9202fbba95ea8294cb5e718f028f21b0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,63 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using UnityEditor;
|
||||
using UnityEditorInternal;
|
||||
|
||||
namespace UnityEngine.TestTools
|
||||
{
|
||||
/// <summary>
|
||||
/// WaitForDomainReload is an <see cref="IEditModeTestYieldInstruction"/> that you can yield in Edit Mode tests. It delays the execution of scripts until after an incoming domain reload. If the domain reload results in a script compilation failure, then it throws an exception.
|
||||
/// </summary>
|
||||
public class WaitForDomainReload : IEditModeTestYieldInstruction
|
||||
{
|
||||
/// <summary>
|
||||
/// Create a new instance of the `WaitForDomainReload` yield instruction.
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// [UnitySetUp]
|
||||
/// public IEnumerator SetUp()
|
||||
/// {
|
||||
/// File.Copy("Resources/MyDll.dll", @"Assets/MyDll.dll", true); // Trigger a domain reload.
|
||||
/// AssetDatabase.Refresh();
|
||||
/// yield return new WaitForDomainReload();
|
||||
/// }
|
||||
/// </code>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
public WaitForDomainReload()
|
||||
{
|
||||
ExpectDomainReload = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the instruction expects a domain reload to occur.
|
||||
/// </summary>
|
||||
public bool ExpectDomainReload { get; }
|
||||
/// <summary>
|
||||
/// Returns true if the instruction expects the Unity Editor to be in **Play Mode**.
|
||||
/// </summary>
|
||||
public bool ExpectedPlaymodeState { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Perform the multi step action of waiting for a domain reload.
|
||||
/// </summary>
|
||||
/// <returns>An IEnumerator with steps.</returns>
|
||||
/// <exception cref="Exception">Throws an exception if script compilation failed or if the expected domain reload did not occur.</exception>
|
||||
public IEnumerator Perform()
|
||||
{
|
||||
EditorApplication.UnlockReloadAssemblies();
|
||||
|
||||
while (InternalEditorUtility.IsScriptReloadRequested() || EditorApplication.isCompiling)
|
||||
{
|
||||
yield return null;
|
||||
}
|
||||
|
||||
// Add this point the domain reload should have occured and stopped any further progress on the instruction.
|
||||
EditorApplication.LockReloadAssemblies();
|
||||
throw new Exception(
|
||||
EditorUtility.scriptCompilationFailed
|
||||
? "Script compilation failed"
|
||||
: "Expected domain reload, but it did not occur");
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5df3c21c5237c994db89660fbdfee07d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1f5bbb88ca730434483440cbc0278ef6
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,50 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor.TestTools.TestRunner.Api;
|
||||
using UnityEditor.TestTools.TestRunner.Api.Analytics;
|
||||
using UnityEngine.TestTools;
|
||||
|
||||
namespace UnityEditor.TestTools.TestRunner
|
||||
{
|
||||
internal class CachingTestListProvider
|
||||
{
|
||||
private readonly ITestListProvider m_InnerTestListProvider;
|
||||
private readonly ITestListCache m_TestListCache;
|
||||
private readonly ITestAdaptorFactory m_TestAdaptorFactory;
|
||||
public CachingTestListProvider(ITestListProvider innerTestListProvider, ITestListCache testListCache, ITestAdaptorFactory testAdaptorFactory)
|
||||
{
|
||||
m_InnerTestListProvider = innerTestListProvider;
|
||||
m_TestListCache = testListCache;
|
||||
m_TestAdaptorFactory = testAdaptorFactory;
|
||||
}
|
||||
|
||||
public IEnumerator<ITestAdaptor> GetTestListAsync(TestPlatform platform)
|
||||
{
|
||||
var testFromCache = m_TestListCache.GetTestFromCacheAsync(platform);
|
||||
while (testFromCache.MoveNext())
|
||||
{
|
||||
yield return null;
|
||||
}
|
||||
|
||||
|
||||
if (testFromCache.Current != null)
|
||||
{
|
||||
yield return testFromCache.Current;
|
||||
}
|
||||
else
|
||||
{
|
||||
var test = m_InnerTestListProvider.GetTestListAsync(platform);
|
||||
while (test.MoveNext())
|
||||
{
|
||||
yield return null;
|
||||
}
|
||||
|
||||
m_TestListCache.CacheTest(platform, test.Current);
|
||||
#if !UNITY_2023_2_OR_NEWER
|
||||
AnalyticsReporter.AnalyzeTestTreeAndReport(test.Current);
|
||||
#endif
|
||||
yield return m_TestAdaptorFactory.Create(test.Current);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 26f3e7301af463c4ca72fa98d59b429e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using UnityEngine.TestTools.Utils;
|
||||
|
||||
namespace UnityEditor.TestTools.TestRunner
|
||||
{
|
||||
internal class EditorAssembliesProxy : IEditorAssembliesProxy
|
||||
{
|
||||
public IAssemblyWrapper[] loadedAssemblies
|
||||
{
|
||||
get { return EditorAssemblies.loadedAssemblies.OrderBy(a => a.FullName).Select(x => new EditorAssemblyWrapper(x)).ToArray(); }
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f96d0ea807c081145a1170ed1b6d71e0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using UnityEditor;
|
||||
using UnityEngine.TestTools.Utils;
|
||||
|
||||
namespace UnityEditor.TestTools.TestRunner
|
||||
{
|
||||
internal class EditorAssemblyWrapper : AssemblyWrapper
|
||||
{
|
||||
public EditorAssemblyWrapper(Assembly assembly)
|
||||
: base(assembly) {}
|
||||
|
||||
public override AssemblyName[] GetReferencedAssemblies()
|
||||
{
|
||||
return Assembly.GetReferencedAssemblies();
|
||||
}
|
||||
|
||||
public override string Location { get { return Assembly.Location; } }
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 20cdb37e6fea6d946bbb84d2c923db85
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using UnityEditor.Scripting.ScriptCompilation;
|
||||
|
||||
namespace UnityEditor.TestTools.TestRunner
|
||||
{
|
||||
internal class EditorCompilationInterfaceProxy : IEditorCompilationInterfaceProxy
|
||||
{
|
||||
public ScriptAssembly[] GetAllEditorScriptAssemblies()
|
||||
{
|
||||
return EditorCompilationInterface.Instance.GetAllEditorScriptAssemblies(EditorCompilationInterface.GetAdditionalEditorScriptCompilationOptions());
|
||||
}
|
||||
|
||||
public PrecompiledAssembly[] GetAllPrecompiledAssemblies()
|
||||
{
|
||||
return EditorCompilationInterface.Instance.GetAllPrecompiledAssemblies();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c9b23632c77de204abfe8bf7168d48c0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,125 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using UnityEditor;
|
||||
using UnityEditor.Scripting.ScriptCompilation;
|
||||
using UnityEngine.TestTools;
|
||||
using UnityEngine.TestTools.Utils;
|
||||
|
||||
namespace UnityEditor.TestTools.TestRunner
|
||||
{
|
||||
internal class EditorLoadedTestAssemblyProvider : IEditorLoadedTestAssemblyProvider
|
||||
{
|
||||
private const string k_NunitAssemblyName = "nunit.framework";
|
||||
private const string k_TestRunnerAssemblyName = "UnityEngine.TestRunner";
|
||||
internal const string k_PerformanceTestingAssemblyName = "Unity.PerformanceTesting";
|
||||
|
||||
private readonly IEditorAssembliesProxy m_EditorAssembliesProxy;
|
||||
private readonly ScriptAssembly[] m_AllEditorScriptAssemblies;
|
||||
private readonly PrecompiledAssembly[] m_AllPrecompiledAssemblies;
|
||||
|
||||
public EditorLoadedTestAssemblyProvider(IEditorCompilationInterfaceProxy compilationInterfaceProxy, IEditorAssembliesProxy editorAssembliesProxy)
|
||||
{
|
||||
m_EditorAssembliesProxy = editorAssembliesProxy;
|
||||
m_AllEditorScriptAssemblies = compilationInterfaceProxy.GetAllEditorScriptAssemblies();
|
||||
m_AllPrecompiledAssemblies = compilationInterfaceProxy.GetAllPrecompiledAssemblies();
|
||||
}
|
||||
|
||||
public List<IAssemblyWrapper> GetAssembliesGroupedByType(TestPlatform mode)
|
||||
{
|
||||
var assemblies = GetAssembliesGroupedByTypeAsync(mode);
|
||||
while (assemblies.MoveNext())
|
||||
{
|
||||
}
|
||||
|
||||
return assemblies.Current.Where(pair => mode.IsFlagIncluded(pair.Key)).SelectMany(pair => pair.Value).ToList();
|
||||
}
|
||||
|
||||
public IEnumerator<IDictionary<TestPlatform, List<IAssemblyWrapper>>> GetAssembliesGroupedByTypeAsync(TestPlatform mode)
|
||||
{
|
||||
IAssemblyWrapper[] loadedAssemblies = m_EditorAssembliesProxy.loadedAssemblies;
|
||||
|
||||
IDictionary<TestPlatform, List<IAssemblyWrapper>> result = new Dictionary<TestPlatform, List<IAssemblyWrapper>>
|
||||
{
|
||||
{TestPlatform.EditMode, new List<IAssemblyWrapper>() },
|
||||
{TestPlatform.PlayMode, new List<IAssemblyWrapper>() }
|
||||
};
|
||||
var filteredAssemblies = FilterAssembliesWithTestReference(loadedAssemblies);
|
||||
|
||||
foreach (var loadedAssembly in filteredAssemblies)
|
||||
{
|
||||
var assemblyName = new FileInfo(loadedAssembly.Location).Name;
|
||||
var scriptAssemblies = m_AllEditorScriptAssemblies.Where(x => x.Filename == assemblyName).ToList();
|
||||
var precompiledAssemblies = m_AllPrecompiledAssemblies.Where(x => new FileInfo(x.Path).Name == assemblyName).ToList();
|
||||
if (scriptAssemblies.Count < 1 && precompiledAssemblies.Count < 1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var assemblyFlags = scriptAssemblies.Any() ? scriptAssemblies.Single().Flags : precompiledAssemblies.Single().Flags;
|
||||
var assemblyType = (assemblyFlags & AssemblyFlags.EditorOnly) == AssemblyFlags.EditorOnly ? TestPlatform.EditMode : TestPlatform.PlayMode;
|
||||
result[assemblyType].Add(loadedAssembly);
|
||||
yield return null;
|
||||
}
|
||||
|
||||
yield return result;
|
||||
}
|
||||
|
||||
private IAssemblyWrapper[] FilterAssembliesWithTestReference(IAssemblyWrapper[] loadedAssemblies)
|
||||
{
|
||||
var filteredResults = new Dictionary<IAssemblyWrapper, bool>();
|
||||
foreach (var assembly in loadedAssemblies)
|
||||
{
|
||||
FilterAssemblyForTestReference(assembly, loadedAssemblies, filteredResults, new Dictionary<IAssemblyWrapper, bool>());
|
||||
}
|
||||
|
||||
return filteredResults.Where(pair => pair.Value).Select(pair => pair.Key).ToArray();
|
||||
}
|
||||
|
||||
private void FilterAssemblyForTestReference(IAssemblyWrapper assemblyToFilter, IAssemblyWrapper[] loadedAssemblies,
|
||||
IDictionary<IAssemblyWrapper, bool> filterResults, IDictionary<IAssemblyWrapper, bool> resultsAlreadyAnalyzed)
|
||||
{
|
||||
if(resultsAlreadyAnalyzed.ContainsKey(assemblyToFilter))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
resultsAlreadyAnalyzed[assemblyToFilter] = true;
|
||||
|
||||
var references = assemblyToFilter.GetReferencedAssemblies();
|
||||
if (references.Any(IsTestReference))
|
||||
{
|
||||
filterResults[assemblyToFilter] = true;
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var reference in references)
|
||||
{
|
||||
var referencedAssembly = loadedAssemblies.FirstOrDefault(a => a.Name.Name == reference.Name);
|
||||
if (referencedAssembly == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
FilterAssemblyForTestReference(referencedAssembly, loadedAssemblies, filterResults, resultsAlreadyAnalyzed);
|
||||
|
||||
if (filterResults.ContainsKey(referencedAssembly) && filterResults[referencedAssembly])
|
||||
{
|
||||
filterResults[assemblyToFilter] = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
filterResults[assemblyToFilter] = false;
|
||||
}
|
||||
|
||||
private static bool IsTestReference(AssemblyName assemblyName)
|
||||
{
|
||||
return assemblyName.Name == k_NunitAssemblyName ||
|
||||
assemblyName.Name == k_TestRunnerAssemblyName ||
|
||||
assemblyName.Name == k_PerformanceTestingAssemblyName;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 033c884ba52437d49bc55935939ef1c6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,10 @@
|
||||
using System;
|
||||
using UnityEngine.TestTools.Utils;
|
||||
|
||||
namespace UnityEditor.TestTools.TestRunner
|
||||
{
|
||||
internal interface IEditorAssembliesProxy
|
||||
{
|
||||
IAssemblyWrapper[] loadedAssemblies { get; }
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 98808b11e78f6c84a841a6b4bc5a29d2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,11 @@
|
||||
using System;
|
||||
using UnityEditor.Scripting.ScriptCompilation;
|
||||
|
||||
namespace UnityEditor.TestTools.TestRunner
|
||||
{
|
||||
internal interface IEditorCompilationInterfaceProxy
|
||||
{
|
||||
ScriptAssembly[] GetAllEditorScriptAssemblies();
|
||||
PrecompiledAssembly[] GetAllPrecompiledAssemblies();
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 28c8fcb831e6e734a9f564bc4f495eba
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine.TestTools;
|
||||
using UnityEngine.TestTools.Utils;
|
||||
|
||||
namespace UnityEditor.TestTools.TestRunner
|
||||
{
|
||||
internal interface IEditorLoadedTestAssemblyProvider
|
||||
{
|
||||
List<IAssemblyWrapper> GetAssembliesGroupedByType(TestPlatform mode);
|
||||
IEnumerator<IDictionary<TestPlatform, List<IAssemblyWrapper>>> GetAssembliesGroupedByTypeAsync(TestPlatform mode);
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 936b6288befc460409cfdff3ac92fc95
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using NUnit.Framework.Interfaces;
|
||||
using UnityEditor.TestTools.TestRunner.Api;
|
||||
using UnityEngine.TestTools;
|
||||
|
||||
namespace UnityEditor.TestTools.TestRunner
|
||||
{
|
||||
internal interface ITestListCache
|
||||
{
|
||||
void CacheTest(TestPlatform platform, ITest test);
|
||||
IEnumerator<ITestAdaptor> GetTestFromCacheAsync(TestPlatform platform);
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a704c010bcdb1ec4a9f3417b3c393164
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using NUnit.Framework.Interfaces;
|
||||
using UnityEngine.TestTools;
|
||||
|
||||
namespace UnityEditor.TestTools.TestRunner
|
||||
{
|
||||
internal interface ITestListCacheData
|
||||
{
|
||||
List<TestPlatform> platforms { get; }
|
||||
List<ITest> cachedData { get; }
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7043e9a330ac2d84a80a965ada4589ad
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using NUnit.Framework.Interfaces;
|
||||
using UnityEngine.TestTools;
|
||||
|
||||
namespace UnityEditor.TestTools.TestRunner
|
||||
{
|
||||
internal interface ITestListProvider
|
||||
{
|
||||
IEnumerator<ITest> GetTestListAsync(TestPlatform platform);
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 64689f8b25eadac4da519e96f514b653
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,58 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using NUnit.Framework.Interfaces;
|
||||
using UnityEditor.Callbacks;
|
||||
using UnityEditor.TestTools.TestRunner.Api;
|
||||
using UnityEngine.TestRunner.TestLaunchers;
|
||||
using UnityEngine.TestTools;
|
||||
|
||||
namespace UnityEditor.TestTools.TestRunner
|
||||
{
|
||||
internal class TestListCache : ITestListCache
|
||||
{
|
||||
private readonly ITestAdaptorFactory m_TestAdaptorFactory;
|
||||
private readonly IRemoteTestResultDataFactory m_TestResultDataFactory;
|
||||
private readonly ITestListCacheData m_TestListCacheData;
|
||||
|
||||
public TestListCache(ITestAdaptorFactory testAdaptorFactory, IRemoteTestResultDataFactory testResultDataFactory, ITestListCacheData testListCacheData)
|
||||
{
|
||||
m_TestAdaptorFactory = testAdaptorFactory;
|
||||
m_TestResultDataFactory = testResultDataFactory;
|
||||
m_TestListCacheData = testListCacheData;
|
||||
}
|
||||
|
||||
public void CacheTest(TestPlatform platform, ITest test)
|
||||
{
|
||||
var index = m_TestListCacheData.platforms.IndexOf(platform);
|
||||
if (index < 0)
|
||||
{
|
||||
m_TestListCacheData.cachedData.Add(test);
|
||||
m_TestListCacheData.platforms.Add(platform);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_TestListCacheData.cachedData[index] = test;
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerator<ITestAdaptor> GetTestFromCacheAsync(TestPlatform platform)
|
||||
{
|
||||
var index = m_TestListCacheData.platforms.IndexOf(platform);
|
||||
if (index < 0)
|
||||
{
|
||||
yield return null;
|
||||
yield break;
|
||||
}
|
||||
|
||||
var testData = m_TestListCacheData.cachedData[index];
|
||||
yield return m_TestAdaptorFactory.Create(testData);
|
||||
}
|
||||
|
||||
[DidReloadScripts]
|
||||
private static void ScriptReloaded()
|
||||
{
|
||||
TestListCacheData.instance.cachedData.Clear();
|
||||
TestListCacheData.instance.platforms.Clear();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d685d97a1eb004f49afea0cc982ff728
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,27 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using NUnit.Framework.Interfaces;
|
||||
using UnityEngine;
|
||||
using UnityEngine.TestTools;
|
||||
|
||||
namespace UnityEditor.TestTools.TestRunner
|
||||
{
|
||||
internal class TestListCacheData : ScriptableSingleton<TestListCacheData>, ITestListCacheData
|
||||
{
|
||||
[SerializeField]
|
||||
private List<TestPlatform> m_Platforms = new List<TestPlatform>();
|
||||
|
||||
[SerializeField]
|
||||
private List<ITest> m_CachedData = new List<ITest>();
|
||||
|
||||
public List<TestPlatform> platforms
|
||||
{
|
||||
get { return m_Platforms; }
|
||||
}
|
||||
|
||||
public List<ITest> cachedData
|
||||
{
|
||||
get { return m_CachedData; }
|
||||
}
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user