Initial Commit
This commit is contained in:
parent
53eb92e9af
commit
270ab7d11f
15341 changed files with 700234 additions and 0 deletions
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 5d7f0d6acfced954682a89e7002c04d9
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,186 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using NUnit.Framework.Interfaces;
|
||||
using NUnit.Framework.Internal;
|
||||
using UnityEditor.SceneManagement;
|
||||
using UnityEngine;
|
||||
using UnityEngine.TestTools.TestRunner;
|
||||
|
||||
namespace UnityEditor.TestTools.TestRunner
|
||||
{
|
||||
internal class EditModeRunnerCallback : ScriptableObject, ITestRunnerListener
|
||||
{
|
||||
private EditModeLauncherContextSettings m_Settings;
|
||||
public SceneSetup[] previousSceneSetup;
|
||||
public EditModeRunner runner;
|
||||
|
||||
private bool m_Canceled;
|
||||
private ITest m_CurrentTest;
|
||||
private int m_TotalTests;
|
||||
|
||||
[SerializeField]
|
||||
private List<string> m_PendingTests;
|
||||
[SerializeField]
|
||||
private string m_LastCountedTestName;
|
||||
[SerializeField]
|
||||
private bool m_RunRestarted;
|
||||
|
||||
public void OnDestroy()
|
||||
{
|
||||
CleanUp();
|
||||
}
|
||||
|
||||
public void RunStarted(ITest testsToRun)
|
||||
{
|
||||
Setup();
|
||||
if (m_PendingTests == null)
|
||||
{
|
||||
m_PendingTests = GetTestsExpectedToRun(testsToRun, runner.GetFilter());
|
||||
m_TotalTests = m_PendingTests.Count;
|
||||
}
|
||||
}
|
||||
|
||||
public void OnEnable()
|
||||
{
|
||||
if (m_RunRestarted)
|
||||
{
|
||||
Setup();
|
||||
}
|
||||
}
|
||||
|
||||
private void Setup()
|
||||
{
|
||||
m_Settings = new EditModeLauncherContextSettings();
|
||||
Application.logMessageReceivedThreaded += LogReceived;
|
||||
EditorApplication.playModeStateChanged += WaitForExitPlaymode;
|
||||
EditorApplication.update += DisplayProgressBar;
|
||||
AssemblyReloadEvents.beforeAssemblyReload += BeforeAssemblyReload;
|
||||
}
|
||||
|
||||
private void BeforeAssemblyReload()
|
||||
{
|
||||
if (m_CurrentTest != null)
|
||||
{
|
||||
m_LastCountedTestName = m_CurrentTest.FullName;
|
||||
m_RunRestarted = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void DisplayProgressBar()
|
||||
{
|
||||
if (m_CurrentTest == null)
|
||||
return;
|
||||
if (!m_Canceled && EditorUtility.DisplayCancelableProgressBar("Test Runner", "Running test " + m_CurrentTest.Name, Math.Min(1.0f, (float)(m_TotalTests - m_PendingTests.Count) / m_TotalTests)))
|
||||
{
|
||||
EditorApplication.update -= DisplayProgressBar;
|
||||
m_Canceled = true;
|
||||
EditorUtility.ClearProgressBar();
|
||||
runner.OnRunCancel();
|
||||
}
|
||||
}
|
||||
|
||||
private static void LogReceived(string message, string stacktrace, LogType type)
|
||||
{
|
||||
if (TestContext.Out != null)
|
||||
TestContext.Out.WriteLine(message);
|
||||
}
|
||||
|
||||
private static void WaitForExitPlaymode(PlayModeStateChange state)
|
||||
{
|
||||
if (state == PlayModeStateChange.EnteredEditMode)
|
||||
{
|
||||
EditorApplication.playModeStateChanged -= WaitForExitPlaymode;
|
||||
//because logMessage is reset on Enter EditMode
|
||||
//we remove and add the callback
|
||||
//because Unity
|
||||
Application.logMessageReceivedThreaded -= LogReceived;
|
||||
Application.logMessageReceivedThreaded += LogReceived;
|
||||
}
|
||||
}
|
||||
|
||||
public void RunFinished(ITestResult result)
|
||||
{
|
||||
if (previousSceneSetup != null && previousSceneSetup.Length > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
EditorSceneManager.RestoreSceneManagerSetup(previousSceneSetup);
|
||||
}
|
||||
catch (ArgumentException e)
|
||||
{
|
||||
Debug.LogWarning(e.Message);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var obj in FindObjectsOfType<GameObject>())
|
||||
{
|
||||
if (obj != null && obj.transform.parent != null && (obj.transform.parent.hideFlags & HideFlags.DontSaveInEditor) == HideFlags.DontSaveInEditor && obj.transform.parent.gameObject != null)
|
||||
{
|
||||
DestroyImmediate(obj.transform.parent.gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
EditorSceneManager.NewScene(NewSceneSetup.DefaultGameObjects, NewSceneMode.Single);
|
||||
}
|
||||
CleanUp();
|
||||
}
|
||||
|
||||
private void CleanUp()
|
||||
{
|
||||
m_CurrentTest = null;
|
||||
EditorUtility.ClearProgressBar();
|
||||
if (m_Settings != null)
|
||||
{
|
||||
m_Settings.Dispose();
|
||||
}
|
||||
Application.logMessageReceivedThreaded -= LogReceived;
|
||||
EditorApplication.update -= DisplayProgressBar;
|
||||
}
|
||||
|
||||
public void TestStarted(ITest test)
|
||||
{
|
||||
if (test.IsSuite || !(test is TestMethod))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_CurrentTest = test;
|
||||
|
||||
if (m_RunRestarted)
|
||||
{
|
||||
if (test.FullName == m_LastCountedTestName)
|
||||
m_RunRestarted = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void TestFinished(ITestResult result)
|
||||
{
|
||||
if (result.Test is TestMethod)
|
||||
{
|
||||
m_PendingTests.Remove(result.Test.FullName);
|
||||
}
|
||||
}
|
||||
|
||||
private static List<string> GetTestsExpectedToRun(ITest test, ITestFilter filter)
|
||||
{
|
||||
var expectedTests = new List<string>();
|
||||
|
||||
if (filter.Pass(test))
|
||||
{
|
||||
if (test.IsSuite)
|
||||
{
|
||||
expectedTests.AddRange(test.Tests.SelectMany(subTest => GetTestsExpectedToRun(subTest, filter)));
|
||||
}
|
||||
else
|
||||
{
|
||||
expectedTests.Add(test.FullName);
|
||||
}
|
||||
}
|
||||
|
||||
return expectedTests;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: cc456ba93311a3a43ad896449fee9868
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,86 @@
|
|||
using UnityEditor.TestTools.TestRunner.Api;
|
||||
using UnityEditor.TestTools.TestRunner.CommandLineTest;
|
||||
using UnityEditor.TestTools.TestRunner.GUI;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.TestTools.TestRunner
|
||||
{
|
||||
internal class RerunCallback : ScriptableObject, ICallbacks
|
||||
{
|
||||
public static bool useMockRunFilter = false;
|
||||
public static UITestRunnerFilter mockRunFilter = null;
|
||||
|
||||
public void RunFinished(ITestResultAdaptor result)
|
||||
{
|
||||
if (RerunCallbackData.instance.runFilters == null || RerunCallbackData.instance.runFilters.Length == 0)
|
||||
RerunCallbackData.instance.runFilters = new[] {new UITestRunnerFilter()};
|
||||
|
||||
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)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 34d30300ba8eb4959a74ac1f8f413c8d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,15 @@
|
|||
using UnityEditor.TestTools.TestRunner.Api;
|
||||
using UnityEditor.TestTools.TestRunner.GUI;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.TestTools.TestRunner
|
||||
{
|
||||
internal class RerunCallbackData : ScriptableSingleton<RerunCallbackData>
|
||||
{
|
||||
[SerializeField]
|
||||
internal UITestRunnerFilter[] runFilters;
|
||||
|
||||
[SerializeField]
|
||||
internal TestMode testMode;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 5be0e972cb9434b7797b1d37dcd127c3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,17 @@
|
|||
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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 9cb48d7d0e6784c81ad36cdbfe8e4b6b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,37 @@
|
|||
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)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: d44e6804bc58be84ea71a619b468f150
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,59 @@
|
|||
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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 6d468ee3657be7a43a2ef2178ec14239
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,11 @@
|
|||
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,32 @@
|
|||
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,447 @@
|
|||
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]
|
||||
private EnumerableTestState m_EnumerableTestState;
|
||||
|
||||
[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_EnumerableTestState == null)
|
||||
{
|
||||
m_EnumerableTestState = CreateInstance<EnumerableTestState>();
|
||||
}
|
||||
context.EnumerableTestState = m_EnumerableTestState;
|
||||
|
||||
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.ToRuntimeTestRunnerFilter(RunningSynchronously).BuildNUnitFilter()).ToArray());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: c9219e99d466b7741a057132d1994f35
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,14 @@
|
|||
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,181 @@
|
|||
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 (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,51 @@
|
|||
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,111 @@
|
|||
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,48 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor.TestTools.TestRunner.Api;
|
||||
using UnityEngine.TestRunner.NUnitExtensions;
|
||||
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;
|
||||
}
|
||||
|
||||
test.Current.ParseForNameDuplicates();
|
||||
m_TestListCache.CacheTest(platform, test.Current);
|
||||
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,13 @@
|
|||
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,18 @@
|
|||
using System.Reflection;
|
||||
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,17 @@
|
|||
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,120 @@
|
|||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
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);
|
||||
}
|
||||
|
||||
return filteredResults.Where(pair => pair.Value).Select(pair => pair.Key).ToArray();
|
||||
}
|
||||
|
||||
private void FilterAssemblyForTestReference(IAssemblyWrapper assemblyToFilter, IAssemblyWrapper[] loadedAssemblies, IDictionary<IAssemblyWrapper, bool> filterResults)
|
||||
{
|
||||
if (filterResults.ContainsKey(assemblyToFilter))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if (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,9 @@
|
|||
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,10 @@
|
|||
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,12 @@
|
|||
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,13 @@
|
|||
using System.Collections.Generic;
|
||||
using NUnit.Framework.Interfaces;
|
||||
using UnityEditor.TestTools.TestRunner.Api;
|
||||
using UnityEngine.TestTools;
|
||||
|
||||
namespace UnityEditor.TestTools.TestRunner
|
||||
{
|
||||
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.Collections.Generic;
|
||||
using NUnit.Framework.Interfaces;
|
||||
using UnityEngine.TestRunner.TestLaunchers;
|
||||
using UnityEngine.TestTools;
|
||||
|
||||
namespace UnityEditor.TestTools.TestRunner
|
||||
{
|
||||
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,11 @@
|
|||
using System.Collections.Generic;
|
||||
using NUnit.Framework.Interfaces;
|
||||
using UnityEngine.TestTools;
|
||||
|
||||
namespace UnityEditor.TestTools.TestRunner
|
||||
{
|
||||
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,56 @@
|
|||
using System.Collections.Generic;
|
||||
using NUnit.Framework.Interfaces;
|
||||
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);
|
||||
}
|
||||
|
||||
[Callbacks.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.Collections.Generic;
|
||||
using NUnit.Framework.Interfaces;
|
||||
using UnityEngine;
|
||||
using UnityEngine.TestRunner.TestLaunchers;
|
||||
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; }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: f1b6399349763114d9361bc6dfcd025b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,36 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor.TestTools.TestRunner.Api;
|
||||
using UnityEngine.TestTools;
|
||||
|
||||
namespace UnityEditor.TestTools.TestRunner
|
||||
{
|
||||
internal class TestListJob
|
||||
{
|
||||
private CachingTestListProvider m_TestListProvider;
|
||||
private TestPlatform m_Platform;
|
||||
private Action<ITestAdaptor> m_Callback;
|
||||
private IEnumerator<ITestAdaptor> m_ResultEnumerator;
|
||||
public TestListJob(CachingTestListProvider testListProvider, TestPlatform platform, Action<ITestAdaptor> callback)
|
||||
{
|
||||
m_TestListProvider = testListProvider;
|
||||
m_Platform = platform;
|
||||
m_Callback = callback;
|
||||
}
|
||||
|
||||
public void Start()
|
||||
{
|
||||
m_ResultEnumerator = m_TestListProvider.GetTestListAsync(m_Platform);
|
||||
EditorApplication.update += EditorUpdate;
|
||||
}
|
||||
|
||||
private void EditorUpdate()
|
||||
{
|
||||
if (!m_ResultEnumerator.MoveNext())
|
||||
{
|
||||
m_Callback(m_ResultEnumerator.Current);
|
||||
EditorApplication.update -= EditorUpdate;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: dec9066d4afefe444be0dad3f137730d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,42 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NUnit.Framework.Interfaces;
|
||||
using UnityEngine.TestTools;
|
||||
using UnityEngine.TestTools.NUnitExtensions;
|
||||
|
||||
namespace UnityEditor.TestTools.TestRunner
|
||||
{
|
||||
internal class TestListProvider : ITestListProvider
|
||||
{
|
||||
private readonly EditorLoadedTestAssemblyProvider m_AssemblyProvider;
|
||||
private readonly UnityTestAssemblyBuilder m_AssemblyBuilder;
|
||||
|
||||
public TestListProvider(EditorLoadedTestAssemblyProvider assemblyProvider, UnityTestAssemblyBuilder assemblyBuilder)
|
||||
{
|
||||
m_AssemblyProvider = assemblyProvider;
|
||||
m_AssemblyBuilder = assemblyBuilder;
|
||||
}
|
||||
|
||||
public IEnumerator<ITest> GetTestListAsync(TestPlatform platform)
|
||||
{
|
||||
var assembliesTask = m_AssemblyProvider.GetAssembliesGroupedByTypeAsync(platform);
|
||||
while (assembliesTask.MoveNext())
|
||||
{
|
||||
yield return null;
|
||||
}
|
||||
|
||||
var assemblies = assembliesTask.Current.Where(pair => platform.IsFlagIncluded(pair.Key))
|
||||
.SelectMany(pair => pair.Value.Select(assemblyInfo => Tuple.Create(assemblyInfo.Assembly, pair.Key))).ToArray();
|
||||
|
||||
var settings = UnityTestAssemblyBuilder.GetNUnitTestBuilderSettings(platform);
|
||||
var test = m_AssemblyBuilder.BuildAsync(assemblies.Select(a => a.Item1).ToArray(), assemblies.Select(a => a.Item2).ToArray(), settings);
|
||||
while (test.MoveNext())
|
||||
{
|
||||
yield return null;
|
||||
}
|
||||
|
||||
yield return test.Current;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: f15cbb987069826429540d0ea0937442
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Loading…
Add table
Add a link
Reference in a new issue