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.
/// </summary>
/// <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>
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");
}
}
}