This commit is contained in:
2025-01-17 13:10:42 +01:00
commit 4536213c91
15115 changed files with 1442174 additions and 0 deletions

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 51557afa652635743b264a309f0a5c60
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,13 @@
using System;
using System.Reflection;
namespace UnityEngine.TestTools.Utils
{
internal class AssemblyLoadProxy : IAssemblyLoadProxy
{
public IAssemblyWrapper Load(string assemblyString)
{
return new AssemblyWrapper(Assembly.Load(assemblyString));
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fb593906b7b6d824087dcaebf6c082e0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,33 @@
using System;
using System.Reflection;
namespace UnityEngine.TestTools.Utils
{
internal class AssemblyWrapper : IAssemblyWrapper
{
public AssemblyWrapper(Assembly assembly)
{
Assembly = assembly;
Name = assembly.GetName();
}
public Assembly Assembly { get; }
public AssemblyName Name { get; }
public virtual string Location
{
get
{
//Some platforms dont support this
throw new NotImplementedException();
}
}
public virtual AssemblyName[] GetReferencedAssemblies()
{
//Some platforms dont support this
throw new NotImplementedException();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2e3b9bbf2c1a3cd4f88883ca32882ec6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,9 @@
using System;
namespace UnityEngine.TestTools.Utils
{
internal interface IAssemblyLoadProxy
{
IAssemblyWrapper Load(string assemblyString);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 12dfd4bdbb5c8e6419432fbc54ef25d9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,13 @@
using System;
using System.Reflection;
namespace UnityEngine.TestTools.Utils
{
internal interface IAssemblyWrapper
{
Assembly Assembly { get; }
AssemblyName Name { get; }
string Location { get; }
AssemblyName[] GetReferencedAssemblies();
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1c5afe945b715e149a70113a4be7b32a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,9 @@
using System;
namespace UnityEngine.TestTools.Utils
{
internal interface IScriptingRuntimeProxy
{
string[] GetAllUserAssemblies();
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fe4aef60e4ace544c8430da8ef8acba2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,52 @@
using System;
using System.Collections.Generic;
using System.IO;
namespace UnityEngine.TestTools.Utils
{
internal class PlayerTestAssemblyProvider
{
private IAssemblyLoadProxy m_AssemblyLoadProxy;
private readonly List<string> m_AssembliesToLoad;
//Cached until domain reload
private static List<IAssemblyWrapper> m_LoadedAssemblies;
internal PlayerTestAssemblyProvider(IAssemblyLoadProxy assemblyLoadProxy, List<string> assembliesToLoad)
{
m_AssemblyLoadProxy = assemblyLoadProxy;
m_AssembliesToLoad = assembliesToLoad;
LoadAssemblies();
}
public List<IAssemblyWrapper> GetUserAssemblies()
{
return m_LoadedAssemblies;
}
private void LoadAssemblies()
{
if (m_LoadedAssemblies != null)
{
return;
}
m_LoadedAssemblies = new List<IAssemblyWrapper>();
foreach (var userAssembly in m_AssembliesToLoad)
{
IAssemblyWrapper a;
try
{
a = m_AssemblyLoadProxy.Load(userAssembly);
}
catch (FileNotFoundException)
{
continue;
}
if (a != null)
m_LoadedAssemblies.Add(a);
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 43a3aec217baa9644a7cf34b5f93fed9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,12 @@
using System;
namespace UnityEngine.TestTools.Utils
{
internal class ScriptingRuntimeProxy : IScriptingRuntimeProxy
{
public string[] GetAllUserAssemblies()
{
return ScriptingRuntime.GetAllUserAssemblies();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f3a361a6ad1aff14ba8f48976e94ad76
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,45 @@
using System;
using System.IO;
using System.Linq;
namespace UnityEngine.TestTools
{
internal static class AttributeHelper
{
internal static Type GetTargetClassFromName(string targetClassName, Type attributeInterface)
{
Type targetClass = null;
foreach (var assemblyName in ScriptingRuntime.GetAllUserAssemblies())
{
// we need to pass the assembly name without the .dll extension, so removing that first
var name = Path.GetFileNameWithoutExtension(assemblyName);
targetClass = Type.GetType(targetClassName + "," + name);
if (targetClass != null)
break;
}
if (targetClass == null)
{
Debug.LogWarningFormat("Class type not found: " + targetClassName);
return null;
}
ValidateTargetClass(targetClass, attributeInterface);
return targetClass;
}
private static void ValidateTargetClass(Type targetClass, Type attributeInterface)
{
var constructorInfos = targetClass.GetConstructors();
if (constructorInfos.All(constructor => constructor.GetParameters().Length != 0))
{
Debug.LogWarningFormat("{0} does not implement default constructor", targetClass.Name);
}
if (!attributeInterface.IsAssignableFrom(targetClass))
{
Debug.LogWarningFormat("{0} does not implement {1}", targetClass.Name, attributeInterface.Name);
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ae8ce3ffe04ac2c42945fd27e0291fc3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,81 @@
using System;
using System.Collections.Generic;
namespace UnityEngine.TestTools.Utils
{
/// <summary>
/// Use this class to compare two Color objects. ColorEqualityComparer.Instance has default calculation error value set to 0.01f. To set a test specific error value instantiate a comparer instance using the one argument constructor.
/// </summary>
public class ColorEqualityComparer : IEqualityComparer<Color>
{
private const float k_DefaultError = 0.01f;
private readonly float AllowedError;
private static readonly ColorEqualityComparer m_Instance = new ColorEqualityComparer();
/// <summary>
///A singleton instance of the comparer with a default error value set to 0.01f.
/// </summary>
public static ColorEqualityComparer Instance { get { return m_Instance; } }
private ColorEqualityComparer() : this(k_DefaultError)
{
}
/// <summary>
/// Creates an instance of the comparer with a custom error value.
/// </summary>
/// <param name="error">The custom error value.</param>
public ColorEqualityComparer(float error)
{
AllowedError = error;
}
/// <summary>
/// Compares the actual and expected Color objects for equality using <see cref="Utils.AreFloatsEqualAbsoluteError"/> to compare the RGB and Alpha attributes of Color. Returns true if expected and actual objects are equal otherwise, it returns false.
/// </summary>
/// <param name="expected">The expected Color value used to compare.</param>
/// <param name="actual">The actual Color value to test.</param>
/// <returns>True if actual and expected are equal, false otherwise</returns>
/// <example>
///<code>
/// [TestFixture]
/// public class ColorEqualityTest
/// {
/// [Test]
/// public void GivenColorsAreEqual_WithAllowedCalculationError()
/// {
/// // Using default error
/// var firstColor = new Color(0f, 0f, 0f, 0f);
/// var secondColor = new Color(0f, 0f, 0f, 0f);
///
/// Assert.That(firstColor, Is.EqualTo(secondColor).Using(ColorEqualityComparer.Instance));
///
/// // Allowed error 10e-5f
/// var comparer = new ColorEqualityComparer(10e-5f);
/// firstColor = new Color(0f, 0f, 0f, 1f);
/// secondColor = new Color(10e-6f, 0f, 0f, 1f);
///
/// Assert.That(firstColor, Is.EqualTo(secondColor).Using(comparer));
/// }
/// }
/// </code>
/// </example>
public bool Equals(Color expected, Color actual)
{
return Utils.AreFloatsEqualAbsoluteError(expected.r, actual.r, AllowedError) &&
Utils.AreFloatsEqualAbsoluteError(expected.g, actual.g, AllowedError) &&
Utils.AreFloatsEqualAbsoluteError(expected.b, actual.b, AllowedError) &&
Utils.AreFloatsEqualAbsoluteError(expected.a, actual.a, AllowedError);
}
/// <summary>
/// Serves as the default hash function.
/// </summary>
/// <param name="color">A not null Color object.</param>
/// <returns>Returns 0.</returns>
public int GetHashCode(Color color)
{
return 0;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d6105bc8cf5ce544487daca4cbc62583
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,70 @@
using System;
using System.Collections;
using NUnit.Framework.Internal;
using UnityEngine.TestRunner.NUnitExtensions.Runner;
using UnityEngine.TestTools.TestRunner;
namespace UnityEngine.TestTools.Utils
{
internal class CoroutineRunner
{
private bool m_Running;
private readonly MonoBehaviour m_Controller;
private readonly UnityTestExecutionContext m_Context;
private IEnumerator m_TestCoroutine;
public CoroutineRunner(MonoBehaviour playmodeTestsController, UnityTestExecutionContext context)
{
m_Controller = playmodeTestsController;
m_Context = context;
}
public IEnumerator HandleEnumerableTest(IEnumerator testEnumerator)
{
do
{
if (!m_Running)
{
m_Running = true;
m_TestCoroutine = ExMethod(WrapEnumeratorForChecks(testEnumerator));
m_Controller.StartCoroutine(m_TestCoroutine);
}
if (m_Context.ExecutionStatus == TestExecutionStatus.StopRequested || m_Context.ExecutionStatus == TestExecutionStatus.AbortRequested)
{
StopAllRunningCoroutines();
yield break;
}
yield return null;
}
while (m_Running);
}
private void StopAllRunningCoroutines()
{
if (m_TestCoroutine != null)
{
m_Controller.StopCoroutine(m_TestCoroutine);
}
}
private IEnumerator ExMethod(IEnumerator e)
{
yield return m_Controller.StartCoroutine(e);
m_Running = false;
}
private IEnumerator WrapEnumeratorForChecks(IEnumerator e)
{
while (e.MoveNext())
{
if (Application.isBatchMode && e.Current is WaitForEndOfFrame)
{
m_Running = false;
throw new Exception("UnityTest yielded WaitForEndOfFrame, which is not evoked in batchmode.");
}
yield return e.Current;
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 24a158219395ebf44a60547b97784ddc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,75 @@
using System;
using System.Collections.Generic;
namespace UnityEngine.TestTools.Utils
{
/// <summary>
/// Use this class to compare two float values for equality with NUnit constraints. Use FloatEqualityComparer.Instance comparer to have the default error value set to 0.0001f. For any other error, use the one argument constructor to create a comparer.
/// </summary>
public class FloatEqualityComparer : IEqualityComparer<float>
{
private const float k_DefaultError = 0.0001f;
private readonly float AllowedError;
private static readonly FloatEqualityComparer m_Instance = new FloatEqualityComparer();
/// <summary>
///A singleton instance of the comparer with a default error value set to 0.0001f.
/// </summary>
public static FloatEqualityComparer Instance { get { return m_Instance; } }
private FloatEqualityComparer() : this(k_DefaultError) {}
/// <summary>
/// Initializes an instance of a FloatEqualityComparer with a custom error value instead of the default 0.0001f.
/// </summary>
/// <param name="allowedError">The custom error value</param>
public FloatEqualityComparer(float allowedError)
{
AllowedError = allowedError;
}
/// <summary>
/// Compares the actual and expected float values for equality using <see cref="Utils.AreFloatsEqual"/>.
/// </summary>
/// <param name="expected">The expected float value used to compare.</param>
/// <param name="actual">The actual float value to test.</param>
/// <returns>True if the values are equals, false otherwise.</returns>
/// <example>
/// <code>
/// [TestFixture]
/// public class FloatsTest
///{
/// [Test]
/// public void VerifyThat_TwoFloatsAreEqual()
/// {
/// var comparer = new FloatEqualityComparer(10e-6f);
/// var actual = -0.00009f;
/// var expected = 0.00009f;
///
/// Assert.That(actual, Is.EqualTo(expected).Using(comparer));
///
/// // Default relative error 0.0001f
/// actual = 10e-8f;
/// expected = 0f;
///
/// Assert.That(actual, Is.EqualTo(expected).Using(FloatEqualityComparer.Instance));
/// }
///}
/// </code>
/// </example>
public bool Equals(float expected, float actual)
{
return Utils.AreFloatsEqual(expected, actual, AllowedError);
}
/// <summary>
/// Serves as the default hash function.
/// </summary>
/// <param name="value">A not null float number.</param>
/// <returns>Returns 0.</returns>
public int GetHashCode(float value)
{
return 0;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: af5042802f06c804c8abddd544b77a4a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,130 @@
using System;
using System.Collections;
using NUnit.Framework.Interfaces;
namespace UnityEngine.TestTools
{
/// <summary>
/// An attribute can implement this interface to provide actions to execute before setup and after teardown of tests.
/// </summary>
/// <example>
/// ## IOuterUnityTestAction Example
/// <code>
/// <![CDATA[
/// using System.Collections;
/// using NUnit.Framework;
/// using NUnit.Framework.Interfaces;
/// using UnityEngine;
/// using UnityEngine.TestTools;
///
/// public class MyTestClass
/// {
/// [UnityTest, MyOuterActionAttribute]
/// public IEnumerator MyTestInsidePlaymode()
/// {
/// Assert.IsTrue(Application.isPlaying);
/// yield return null;
/// }
/// }
///
/// public class MyOuterActionAttribute : NUnitAttribute, IOuterUnityTestAction
/// {
/// public IEnumerator BeforeTest(ITest test)
/// {
/// yield return new EnterPlayMode();
/// }
///
/// public IEnumerator AfterTest(ITest test)
/// {
/// yield return new ExitPlayMode();
/// }
/// }
/// ]]>
/// </code>
/// </example>
/// <example>
/// ## Test actions with domain reload example
/// <code>
/// <![CDATA[
/// using NUnit.Framework.Interfaces;
///
///
/// public class TestActionOnSuiteAttribute : NUnitAttribute, ITestAction
/// {
/// public void BeforeTest(ITest test)
/// {
/// Debug.Log("TestAction OnSuite BeforeTest");
/// }
///
/// public void AfterTest(ITest test)
/// {
/// }
///
/// public ActionTargets Targets { get { return ActionTargets.Suite; } }
/// }
///
/// public class TestActionOnTestAttribute : NUnitAttribute, ITestAction
/// {
/// public void BeforeTest(ITest test)
/// {
/// Debug.Log("TestAction OnTest BeforeTest");
/// }
///
/// public void AfterTest(ITest test)
/// {
/// Debug.Log("TestAction OnTest AfterTest");
/// }
///
/// public ActionTargets Targets { get { return ActionTargets.Test; } }
/// }
///
/// public class OuterTestAttribute : NUnitAttribute, IOuterUnityTestAction
/// {
/// public IEnumerator BeforeTest(ITest test)
/// {
/// Debug.Log("OuterTestAttribute BeforeTest");
/// yield return null;
/// }
///
/// public IEnumerator AfterTest(ITest test)
/// {
/// Debug.Log("OuterTestAttribute AfterTest");
/// yield return null;
/// }
/// }
///
/// [TestActionOnSuite]
/// public class ActionOrderTestBase
/// {
/// [Test, OuterTest, TestActionOnTest]
/// public void UnitTest()
/// {
/// Debug.Log("Test");
/// }
///
/// [UnityTest, OuterTest, TestActionOnTest]
/// public IEnumerator UnityTestWithDomainReload()
/// {
/// Log("Test part 1");
/// yield return new EnterPlayMode();
/// //Domain reload
/// yield return new ExitPlayMode();
/// Log("Test part 2");
/// }
/// }
/// ]]>
/// </code>
/// </example>
public interface IOuterUnityTestAction
{
/// <summary>Executed before each test is run</summary>
/// <param name="test">The test that is going to be run.</param>
/// <returns>Enumerable collection of actions to perform before test setup.</returns>
IEnumerator BeforeTest(ITest test);
/// <summary>Executed after each test is run</summary>
/// <param name="test">The test that has just been run.</param>
/// <returns>Enumerable collection of actions to perform after test teardown.</returns>
IEnumerator AfterTest(ITest test);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b9c2a6302985d3846b7b9f6fd9e2da9a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,15 @@
using System;
namespace UnityEngine.TestTools
{
/// <summary>
/// Implement this interface if you want to define a set of actions to execute as a post-build step. Cleanup runs right away for a standalone test run, but only after all the tests run within the Editor.
/// </summary>
public interface IPostBuildCleanup
{
/// <summary>
/// Implement this method to specify actions that should run as a post-build cleanup step.
/// </summary>
void Cleanup();
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ff67c526455160f4690a44f74dee4cbe
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,62 @@
using System;
namespace UnityEngine.TestTools
{
/// <summary>
/// Implement this interface if you want to define a set of actions to run as a pre-build step.
/// </summary>
public interface IPrebuildSetup
{
/// <summary>
/// Implement this method to call actions automatically before the build process.
/// </summary>
/// <example>
/// <code>
/// [TestFixture]
/// public class CreateSpriteTest : IPrebuildSetup
/// {
/// Texture2D m_Texture;
/// Sprite m_Sprite;
///
/// public void Setup()
/// {
/// #if UNITY_EDITOR
/// var spritePath = "Assets/Resources/Circle.png";
///
/// var ti = UnityEditor.AssetImporter.GetAtPath(spritePath) as UnityEditor.TextureImporter;
///
/// ti.textureCompression = UnityEditor.TextureImporterCompression.Uncompressed;
///
/// ti.SaveAndReimport();
/// #endif
/// }
///
/// [SetUp]
/// public void SetUpTest()
/// {
/// m_Texture = Resources.Load&lt;Texture2D&gt;("Circle");
/// }
///
/// [Test]
/// public void WhenNullTextureIsPassed_CreateShouldReturnNullSprite()
/// {
/// // Check with Valid Texture.
///
/// LogAssert.Expect(LogType.Log, "Circle Sprite Created");
///
/// Sprite.Create(m_Texture, new Rect(0, 0, m_Texture.width, m_Texture.height), new Vector2(0.5f, 0.5f));
///
/// Debug.Log("Circle Sprite Created");
///
/// // Check with NULL Texture. Should return NULL Sprite.
/// m_Sprite = Sprite.Create(null, new Rect(0, 0, m_Texture.width, m_Texture.height), new Vector2(0.5f, 0.5f));
///
/// Assert.That(m_Sprite, Is.Null, "Sprite created with null texture should be null");
/// }
/// }
/// </code>
/// > **Tip**: Use `#if UNITY_EDITOR` if you want to access Editor only APIs, but the setup/cleanup is inside a **Play Mode** assembly.
/// </example>
void Setup();
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: acc16f0c684508f44813662a300c574b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,32 @@
using System;
using NUnit.Framework.Interfaces;
namespace UnityEngine.TestRunner
{
/// <summary>
/// Interface for getting callsbacks on test progress directly from NUnit. This is available both in the editor and directly in the runtime. It is registered by using <see cref="TestRunCallbackAttribute"/>.
/// </summary>
public interface ITestRunCallback
{
/// <summary>
/// A callback invoked when a test run is started.
/// </summary>
/// <param name="testsToRun">The full loaded test tree.</param>
void RunStarted(ITest testsToRun);
/// <summary>
/// A callback invoked when a test run is finished.
/// </summary>
/// <param name="testResults">The result of the test run.</param>
void RunFinished(ITestResult testResults);
/// <summary>
/// A callback invoked when each individual node of the test tree has started executing.
/// </summary>
/// <param name="test">The test node currently executed.</param>
void TestStarted(ITest test);
/// <summary>
/// A callback invoked when each individual node of the test tree has finished executing.
/// </summary>
/// <param name="result">The result of the test tree node after it had been executed.</param>
void TestFinished(ITestResult result);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 38d0b8a87b967304da08a2ae9b955066
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: ce8da628f68c7594b8b9a597fa52db7b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,13 @@
using System;
namespace UnityEngine.TestTools
{
/// <summary>
/// An interface implemented by a MonoBehaviour test.
/// </summary>
public interface IMonoBehaviourTest
{
/// <summary>True when the test is considered finished.</summary>
bool IsTestFinished {get; }
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a002d3737b873954395b7cf862873ab8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,65 @@
using System;
namespace UnityEngine.TestTools
{
/// <summary>
/// This is a wrapper that allows running tests on MonoBehaviour scripts. Inherits from <see cref="CustomYieldInstruction"/> `MonoBehaviourTest` is a [coroutine](https://docs.unity3d.com/ScriptReference/Coroutine.html) and a helper for writing MonoBehaviour tests.
/// Yield a `MonoBehaviourTest` when using the `UnityTest` attribute to instantiate the `MonoBehaviour` you wish to test and wait for it to finish running. Implement the `IMonoBehaviourTest` interface on the `MonoBehaviour` to state when the test completes.
/// </summary>
/// <typeparam name="T">A MonoBehaviour component created for the test and attached to the tests [GameObject](https://docs.unity3d.com/ScriptReference/GameObject.html).</typeparam>
public class MonoBehaviourTest<T> : CustomYieldInstruction where T : MonoBehaviour, IMonoBehaviourTest
{
/// <summary>
/// A MonoBehaviour component created for the test and attached to the test's [GameObject](https://docs.unity3d.com/ScriptReference/GameObject.html).
/// </summary>
public T component { get; }
/// <summary>
/// A `GameObject` created as a container for the test component.
/// </summary>
public GameObject gameObject { get { return component.gameObject; } }
/// <summary>
/// Initializes and returns an instance of MonoBehaviourTest.
/// </summary>
/// <param name="dontDestroyOnLoad"></param>
/// <example>
/// <code>
/// [UnityTest]
/// public IEnumerator MonoBehaviourTest_Works()
/// {
/// yield return new MonoBehaviourTest&lt;MyMonoBehaviourTest&gt;();
/// }
///
/// public class MyMonoBehaviourTest : MonoBehaviour, IMonoBehaviourTest
/// {
/// private int frameCount;
/// public bool IsTestFinished
/// {
/// get { return frameCount &gt; 10; }
/// }
///
/// void Update()
/// {
/// frameCount++;
/// }
/// }
/// </code>
/// </example>
public MonoBehaviourTest(bool dontDestroyOnLoad = true)
{
var go = new GameObject("MonoBehaviourTest: " + typeof(T).FullName);
component = go.AddComponent<T>();
if (dontDestroyOnLoad)
{
Object.DontDestroyOnLoad(go);
}
}
/// <summary>
/// (Inherited) Returns `true`` if the test is not finished yet, which keeps the coroutine suspended
/// </summary>
public override bool keepWaiting
{
get { return !component.IsTestFinished; }
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 164c9b1458eaab743a4b45c37a4d720d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,31 @@
using System;
namespace UnityEngine.TestTools
{
/// <summary>
/// PostBuildCleanup attributes run if the respective test or test class is in the current test run. The test is included either by running all tests or setting a [filter](https://docs.unity3d.com/Packages/com.unity.test-framework@1.1/manual/workflow-create-test.html#filters) that includes the test. If multiple tests reference the same pre-built setup or post-build cleanup, then it only runs once.
/// </summary>
[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method)]
public class PostBuildCleanupAttribute : Attribute
{
/// <summary>
/// Initializes and returns an instance of PostBuildCleanupAttribute by type.
/// </summary>
/// <param name="targetClass">The type of the target class.</param>
public PostBuildCleanupAttribute(Type targetClass)
{
TargetClass = targetClass;
}
/// <summary>
/// Initializes and returns an instance of PostBuildCleanupAttribute by class name.
/// </summary>
/// <param name="targetClassName">The name of the target class.</param>
public PostBuildCleanupAttribute(string targetClassName)
{
TargetClass = AttributeHelper.GetTargetClassFromName(targetClassName, typeof(IPostBuildCleanup));
}
internal Type TargetClass { get; private set; }
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 621fd19bcb071b64aa1d68f0271aa780
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,75 @@
using System;
namespace UnityEngine.TestTools
{
/// <summary>
/// PrebuildSetup attribute run if the test or test class is in the current test run. The test is included either by running all tests or setting a filter that includes the test. If multiple tests reference the same pre-built setup or post-build cleanup, then it only runs once.
/// </summary>
[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method)]
public class PrebuildSetupAttribute : Attribute
{
/// <summary>
/// Initializes and returns an instance of PrebuildSetupAttribute by type.
/// </summary>
/// <param name="targetClass">The type of the target class.</param>
public PrebuildSetupAttribute(Type targetClass)
{
TargetClass = targetClass;
}
/// <summary>
///
/// </summary>
/// <param name="targetClassName"></param>
/// <example>
/// <code>
/// [TestFixture]
/// public class CreateSpriteTest : IPrebuildSetup
/// {
/// Texture2D m_Texture;
/// Sprite m_Sprite;
///
/// public void Setup()
/// {
///
/// #if UNITY_EDITOR
///
/// var spritePath = "Assets/Resources/Circle.png";
/// var ti = UnityEditor.AssetImporter.GetAtPath(spritePath) as UnityEditor.TextureImporter;
/// ti.textureCompression = UnityEditor.TextureImporterCompression.Uncompressed;
/// ti.SaveAndReimport();
///
/// #endif
/// }
///
/// [SetUp]
/// public void SetUpTest()
/// {
/// m_Texture = Resources.Load&lt;Texture2D&gt;("Circle");
/// }
///
/// [Test]
/// public void WhenNullTextureIsPassed_CreateShouldReturnNullSprite()
/// {
///
/// // Check with Valid Texture.
/// LogAssert.Expect(LogType.Log, "Circle Sprite Created");
/// Sprite.Create(m_Texture, new Rect(0, 0, m_Texture.width, m_Texture.height), new Vector2(0.5f, 0.5f));
/// Debug.Log("Circle Sprite Created");
///
/// // Check with NULL Texture. Should return NULL Sprite.
/// m_Sprite = Sprite.Create(null, new Rect(0, 0, m_Texture.width, m_Texture.heig`t), new Vector2(0.5f, 0.5f));
/// Assert.That(m_Sprite, Is.Null, "Sprite created with null texture should be null");
/// }
/// }
/// </code>
/// Tip: Use `#if UNITY_EDITOR` if you want to access Editor only APIs, but the setup/cleanup is inside a **Play Mode** assembly.
/// </example>
public PrebuildSetupAttribute(string targetClassName)
{
TargetClass = AttributeHelper.GetTargetClassFromName(targetClassName, typeof(IPrebuildSetup));
}
internal Type TargetClass { get; private set; }
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d1b7ce919aa8864409412e809073cf96
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,81 @@
using System;
using System.Collections.Generic;
namespace UnityEngine.TestTools.Utils
{
/// <summary>
/// Use this utility to compare two Quaternion objects for equality
/// with NUnit assertion constraints.
/// Use the static instance QuaternionEqualityComparer.Instance
/// to have the default calculation error value set to 0.00001f.
/// For any other custom error value, use the one argument constructor.
/// </summary>
public class QuaternionEqualityComparer : IEqualityComparer<Quaternion>
{
private const float k_DefaultError = 0.00001f;
private readonly float AllowedError;
private static readonly QuaternionEqualityComparer m_Instance = new QuaternionEqualityComparer();
/// <summary>
///A comparer instance with the default error value 0.00001f.
/// </summary>
public static QuaternionEqualityComparer Instance { get { return m_Instance; } }
private QuaternionEqualityComparer() : this(k_DefaultError) {}
/// <summary>
/// Creates an instance of the comparer with a custom allowed error value.
/// </summary>
/// <param name="allowedError">Describes the custom allowed error value</param>
public QuaternionEqualityComparer(float allowedError)
{
AllowedError = allowedError;
}
/// <summary>
/// Compares the actual and expected Quaternion objects
/// for equality using the <see cref="Quaternion.Dot "/> method.
/// </summary>
/// <param name="expected">Expected Quaternion value used for comparison</param>
/// <param name="actual">Actual Quaternion value to test</param>
/// <returns>True if the quaternion are equals, false otherwise.</returns>
/// <example>
/// The following example shows how to verify if two Quaternion are equals
/// <code>
/// [TestFixture]
/// public class QuaternionTest
/// {
/// [Test]
/// public void VerifyThat_TwoQuaternionsAreEqual()
/// {
/// var actual = new Quaternion(10f, 0f, 0f, 0f);
/// var expected = new Quaternion(1f, 10f, 0f, 0f);
/// var comparer = new QuaternionEqualityComparer(10e-6f);
///
/// Assert.That(actual, Is.EqualTo(expected).Using(comparer));
///
/// //Using default error 0.00001f
/// actual = new Quaternion(10f, 0f, 0.1f, 0f);
/// expected = new Quaternion(1f, 10f, 0.1f, 0f);
///
/// Assert.That(actual, Is.EqualTo(expected).Using(QuaternionEqualityComparer.Instance));
/// }
/// }
/// </code>
/// </example>
public bool Equals(Quaternion expected, Quaternion actual)
{
return Mathf.Abs(Quaternion.Dot(expected, actual)) > (1.0f - AllowedError);
}
/// <summary>
/// Serves as the default hash function.
/// </summary>
/// <param name="quaternion">A not null Quaternion</param>
/// <returns>Returns 0</returns>
public int GetHashCode(Quaternion quaternion)
{
return 0;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3b28913f21577de429da928d6d05219f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,44 @@
using System;
using System.Linq;
using System.Text;
namespace UnityEngine.TestTools.Utils
{
internal static class StackTraceFilter
{
private static readonly string[] s_FilteredLogMessages =
{
@"UnityEngine.DebugLogHandler:Internal_Log",
@"UnityEngine.DebugLogHandler:Log",
@"UnityEngine.Logger:Log",
@"UnityEngine.Debug"
};
private static readonly string[] s_LastMessages =
{
@"System.Reflection.MonoMethod:InternalInvoke(Object, Object[], Exception&)",
@"UnityEditor.TestTools.TestRunner.EditModeRunner:InvokeDelegator"
};
public static string Filter(string inputStackTrace)
{
int idx;
foreach (var lastMessage in s_LastMessages)
{
idx = inputStackTrace.IndexOf(lastMessage);
if (idx != -1)
inputStackTrace = inputStackTrace.Substring(0, idx);
}
var inputStackTraceLines = inputStackTrace.Split('\n');
var result = new StringBuilder();
foreach (var line in inputStackTraceLines)
{
if (s_FilteredLogMessages.Any(s => line.StartsWith(s)))
continue;
result.AppendLine(line);
}
return result.ToString();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fc748d99f1f0d484a811a566fc7915ec
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,75 @@
using System;
using UnityEngine.Scripting;
namespace UnityEngine.TestRunner
{
/// <summary>
/// An assembly level attribute that indicates that a given type implementing <see cref = "ITestRunCallback"/> should be subscribed to updates on the test progress. You can invoke the callbacks with [NUnit](http://www.nunit.org/) `ITest` and `ITestResult` classes.
///
/// At the `RunStarted` and `RunFinished` methods, the test and test results are for the whole test tree. These methods invoke at each node in the test tree; first with the whole test assembly, then with the test class, and last with the test method.
///
/// From these callbacks, it's possible to read the partial or the full results, and to save the XML version of the result for further processing or continuous integration.
/// </summary>
/// <example>
/// <code>
/// <![CDATA[
/// using NUnit.Framework.Interfaces;
/// using UnityEngine;
/// using UnityEngine.TestRunner;
///
/// [assembly:TestRunCallback(typeof(TestListener))]
///
/// public class TestListener : ITestRunCallback
/// {
/// public void RunStarted(ITest testsToRun)
/// {
///
/// }
///
/// public void RunFinished(ITestResult testResults)
/// {
/// Debug.Log($"Run finished with result {testResults.ResultState}.");
/// }
///
/// public void TestStarted(ITest test)
/// {
///
/// }
///
/// public void TestFinished(ITestResult result)
/// {
///
/// }
///}
/// ]]>
/// </code>
/// > Note: The `TestRunCallback` does not need any references to the `UnityEditor` namespace and can run in standalone Players on the Player side.
/// </example>
[AttributeUsage(AttributeTargets.Assembly)]
public class TestRunCallbackAttribute : Attribute
{
private Type m_Type;
/// <summary>
/// Constructs a new instance of the <see cref="TestRunCallbackAttribute"/> class.
/// </summary>
/// <param name="type">A target type that implements <see cref="ITestRunCallback"/>.</param>
/// <exception cref="ArgumentException">Throws an ArgumentException if the provided type does not implement <see cref="ITestRunCallback"/>.</exception>
public TestRunCallbackAttribute(Type type)
{
var interfaceType = typeof(ITestRunCallback);
if (!interfaceType.IsAssignableFrom(type))
{
throw new ArgumentException(string.Format(
"Type {2} provided to {0} does not implement {1}. If the stripping level is set to high, the implementing class should have the {3}.",
GetType().Name, interfaceType.Name, type.Name, typeof(PreserveAttribute).Name));
}
m_Type = type;
}
internal ITestRunCallback ConstructCallback()
{
return Activator.CreateInstance(m_Type) as ITestRunCallback;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 76b3a3296de548f48b0c3d088fb4b490
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,60 @@
using System;
using System.Linq;
using NUnit.Framework.Interfaces;
using UnityEngine.TestTools.TestRunner;
namespace UnityEngine.TestRunner.Utils
{
internal class TestRunCallbackListener : ScriptableObject, ITestRunnerListener
{
private ITestRunCallback[] m_Callbacks;
public void RunStarted(ITest testsToRun)
{
InvokeAllCallbacks(callback => callback.RunStarted(testsToRun));
}
private static ITestRunCallback[] GetAllCallbacks()
{
var allAssemblies = AppDomain.CurrentDomain.GetAssemblies();
allAssemblies = allAssemblies.Where(x => x.GetReferencedAssemblies().Any(z => z.Name == "UnityEngine.TestRunner")).ToArray();
var attributes = allAssemblies.SelectMany(assembly => assembly.GetCustomAttributes(typeof(TestRunCallbackAttribute), true).OfType<TestRunCallbackAttribute>()).ToArray();
return attributes.Select(attribute => attribute.ConstructCallback()).ToArray();
}
private void InvokeAllCallbacks(Action<ITestRunCallback> invoker)
{
if (m_Callbacks == null)
{
m_Callbacks = GetAllCallbacks();
}
foreach (var testRunCallback in m_Callbacks)
{
try
{
invoker(testRunCallback);
}
catch (Exception e)
{
Debug.LogException(e);
throw;
}
}
}
public void RunFinished(ITestResult testResults)
{
InvokeAllCallbacks(callback => callback.RunFinished(testResults));
}
public void TestStarted(ITest test)
{
InvokeAllCallbacks(callback => callback.TestStarted(test));
}
public void TestFinished(ITestResult result)
{
InvokeAllCallbacks(callback => callback.TestFinished(result));
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 68f09f0f82599b5448579854e622a4c1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,94 @@
using System;
namespace UnityEngine.TestTools.Utils
{
/// <summary>
/// This contains test utility functions for float value comparison and creating primitives.
/// </summary>
public static class Utils
{
/// <summary>
/// Relative epsilon comparison of two float values for equality.
/// The relative error is the absolute error divided by the magnitude of the exact value.
/// </summary>
/// <param name="expected">The expected float value used to compare.</param>
/// <param name="actual">The actual float value to test.</param>
/// <param name="epsilon"> Epsilon is the relative error to be used in relative epsilon comparison.</param>
/// <returns>Returns true if the actual value is equivalent to the expected value.</returns>
/// <example>
/// <code>
/// [TestFixture]
/// class UtilsTests
/// {
/// [Test]
/// public void CheckThat_FloatsAreEqual()
/// {
/// float expected = 10e-8f;
/// float actual = 0f;
/// float allowedRelativeError = 10e-6f;
///
/// Assert.That(Utils.AreFloatsEqual(expected, actual, allowedRelativeError), Is.True);
/// }
/// }
/// </code>
/// </example>
public static bool AreFloatsEqual(float expected, float actual, float epsilon)
{
// special case for infinity
if (expected == Mathf.Infinity || actual == Mathf.Infinity || expected == Mathf.NegativeInfinity || actual == Mathf.NegativeInfinity)
return expected == actual;
// we cover both relative and absolute tolerance with this check
// which is better than just relative in case of small (in abs value) args
// please note that "usually" approximation is used [i.e. abs(x)+abs(y)+1]
// but we speak about test code so we dont care that much about performance
// but we do care about checks being more precise
return Math.Abs(actual - expected) <= epsilon * Mathf.Max(Mathf.Max(Mathf.Abs(actual), Mathf.Abs(expected)), 1.0f);
}
/// <summary>
/// Compares two floating point numbers for equality under the given absolute tolerance.
/// </summary>
/// <param name="expected">The expected float value used to compare.</param>
/// <param name="actual">The actual float value to test.</param>
/// <param name="allowedAbsoluteError">AllowedAbsoluteError is the permitted error tolerance.</param>
/// <returns> Returns true if the actual value is equivalent to the expected value under the given tolerance.
/// </returns>
/// <example>
/// <code>
/// [TestFixture]
/// class UtilsTests
/// {
/// [Test]
/// public void CheckThat_FloatsAreAbsoluteEqual()
/// {
/// float expected = 0f;
/// float actual = 10e-6f;
/// float error = 10e-5f;
///
/// Assert.That(Utils.AreFloatsEqualAbsoluteError(expected, actual, error), Is.True);
/// }
/// }
/// </code>
/// </example>
public static bool AreFloatsEqualAbsoluteError(float expected, float actual, float allowedAbsoluteError)
{
return Math.Abs(actual - expected) <= allowedAbsoluteError;
}
/// <summary>
/// Analogous to GameObject.CreatePrimitive, but creates a primitive mesh renderer with fast shader instead of a default builtin shader.
/// Optimized for testing performance.
/// </summary>
/// <returns>A GameObject with primitive mesh renderer and collider.</returns>
/// <param name="type">The type of primitive object to create.</param>
public static GameObject CreatePrimitive(PrimitiveType type)
{
var prim = GameObject.CreatePrimitive(type);
var renderer = prim.GetComponent<Renderer>();
if (renderer)
renderer.sharedMaterial = new Material(Shader.Find("VertexLit"));
return prim;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9502550ba4785e3499d6c9251fa2114b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

Some files were not shown because too many files have changed in this diff Show More