A game about forced loneliness, made by TACStudios
1using System; 2using System.Collections; 3using UnityEditor; 4 5namespace UnityEngine.TestTools 6{ 7 /// <summary> 8 /// `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. 9 /// </summary> 10 public class RecompileScripts : IEditModeTestYieldInstruction 11 { 12 /// <summary> 13 /// Creates a new instance of the `RecompileScripts` yield instruction. 14 /// <example> 15 /// <code> 16 /// [UnitySetUp] 17 /// public IEnumerator SetUp() 18 /// { 19 /// using (var file = File.CreateText("Assets/temp/myScript.cs")) 20 /// { 21 /// file.Write("public class ATempClass { }"); 22 /// } 23 /// AssetDatabase.Refresh(); 24 /// yield return new RecompileScripts(); 25 /// } 26 /// </code> 27 /// </example> 28 /// </summary> 29 public RecompileScripts() : this(true) 30 { 31 } 32 /// <summary> 33 /// Creates a new instance of the `RecompileScripts` yield instruction. 34 /// </summary> 35 /// <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> 36 public RecompileScripts(bool expectScriptCompilation) : this(expectScriptCompilation, true) 37 { 38 } 39 40 /// <summary> 41 /// Creates a new instance of the `RecompileScripts` yield instruction. 42 /// </summary> 43 /// <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> 44 /// <param name="expectScriptCompilationSuccess">This parameter indicates if you expect a script compilation to succeed. If not succeeded then an exception will be thrown.</param> 45 public RecompileScripts(bool expectScriptCompilation, bool expectScriptCompilationSuccess) 46 { 47 ExpectScriptCompilation = expectScriptCompilation; 48 ExpectScriptCompilationSuccess = expectScriptCompilationSuccess; 49 ExpectDomainReload = true; 50 } 51 52 /// <summary> 53 /// Returns true if the instruction expects a domain reload to occur. 54 /// </summary> 55 public bool ExpectDomainReload { get; private set; } 56 /// <summary> 57 /// Returns true if the instruction expects the Unity Editor to be in **Play Mode**. 58 /// </summary> 59 public bool ExpectedPlaymodeState { get; } 60 /// <summary> 61 /// Indicates whether a script compilation is expected. 62 /// </summary> 63 public bool ExpectScriptCompilation { get; private set; } 64 /// <summary> 65 /// Indicates whether the expected script compilation is expected to succeed. 66 /// </summary> 67 public bool ExpectScriptCompilationSuccess { get; private set; } 68 69 /// <summary> 70 /// The current active instance of the RecompileScripts yield instruction. 71 /// </summary> 72 public static RecompileScripts Current { get; private set; } 73 74 /// <summary> 75 /// Perform the multi step instruction of triggering a recompilation of scripts and waiting for its completion. 76 /// </summary> 77 /// <returns>An IEnumerator with the async steps.</returns> 78 /// <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> 79 public IEnumerator Perform() 80 { 81 Current = this; 82 83 // We need to yield, to give the test runner a chance to prepare for the domain reload 84 // If the script compilation happens very fast, then EditModeRunner.MoveNextAndUpdateYieldObject will not have a chance to set m_CurrentYieldObject 85 // This really should be fixed in EditModeRunner.MoveNextAndUpdateYieldObject 86 yield return null; 87 88 AssetDatabase.Refresh(); 89 90 if (ExpectScriptCompilation && !EditorApplication.isCompiling) 91 { 92 Current = null; 93 throw new Exception("Editor does not need to recompile scripts"); 94 } 95 96 EditorApplication.UnlockReloadAssemblies(); 97 98 while (EditorApplication.isCompiling) 99 { 100 yield return null; 101 } 102 103 Current = null; 104 105 if (ExpectScriptCompilationSuccess && EditorUtility.scriptCompilationFailed) 106 { 107 EditorApplication.LockReloadAssemblies(); 108 throw new Exception("Script compilation failed"); 109 } 110 } 111 } 112}