RecompileScripts.cs
4.82 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
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");
}
}
}
}