A game about forced loneliness, made by TACStudios
1using System;
2using System.Linq;
3using UnityEditor.Callbacks;
4using UnityEditor.Scripting.ScriptCompilation;
5using UnityEditor.TestTools.TestRunner.Api;
6using UnityEditor.TestTools.TestRunner.GUI;
7using UnityEngine;
8
9namespace UnityEditor.TestTools.TestRunner
10{
11 /// <summary>
12 /// The TestRunnerWindow class is repsonsible for drawing the Test Runner window.
13 /// </summary>
14 [Serializable]
15 public class TestRunnerWindow : EditorWindow, IHasCustomMenu
16 {
17 private const string WindowTitle = "Test Runner";
18
19 internal static class Styles
20 {
21 public static GUIStyle info;
22 public static GUIStyle testList;
23
24 static Styles()
25 {
26 info = new GUIStyle("CN Message");
27 info.wordWrap = true;
28 info.stretchHeight = true;
29 info.margin.right = 15;
30
31 testList = new GUIStyle("CN Box");
32 testList.margin.top = 0;
33 testList.padding.left = 3;
34 }
35 }
36
37 private readonly GUIContent m_GUIHorizontalSplit = EditorGUIUtility.TrTextContent("Horizontal layout");
38 private readonly GUIContent m_GUIVerticalSplit = EditorGUIUtility.TrTextContent("Vertical layout");
39 private readonly GUIContent m_GUIDisablePlaymodeTestsRunner = EditorGUIUtility.TrTextContent("Disable playmode tests for all assemblies");
40 private readonly GUIContent m_GUIRunPlayModeTestAsEditModeTests = EditorGUIUtility.TrTextContent("Run playmode tests as editmode tests");
41
42 internal static TestRunnerWindow s_Instance;
43 private bool m_IsBuilding;
44 [NonSerialized]
45 private bool m_Enabled;
46 //internal TestFilterSettings filterSettings;
47
48 [SerializeField]
49 private SplitterState m_Spl = new SplitterState(new float[] { 75, 25 }, new[] { 32, 32 }, null);
50
51 private TestRunnerWindowSettings m_Settings;
52
53 private enum TestRunnerMenuLabels
54 {
55 EditMode = 0,
56 PlayMode,
57 Player
58 }
59 [SerializeField]
60 private TestRunnerMenuLabels m_TestTypeToolbarIndex = TestRunnerMenuLabels.EditMode;
61 internal TestListGUI m_SelectedTestTypes;
62 [SerializeField]
63 private TestListGUI[] m_TestListGUIs;
64
65 private ITestRunnerApi m_testRunnerApi;
66
67 private WindowResultUpdater m_WindowResultUpdater;
68
69 /// <summary>
70 /// Launches the Test Runner window.
71 /// </summary>
72 [MenuItem("Window/General/Test Runner", false, 201, false)]
73 public static void ShowWindow()
74 {
75 s_Instance = GetWindow<TestRunnerWindow>(WindowTitle);
76 s_Instance.Show();
77 }
78
79 static TestRunnerWindow()
80 {
81 InitBackgroundRunners();
82 }
83
84 private static void InitBackgroundRunners()
85 {
86 EditorApplication.playModeStateChanged -= OnPlayModeStateChanged;
87 EditorApplication.playModeStateChanged += OnPlayModeStateChanged;
88 }
89
90 [DidReloadScripts]
91 private static void CompilationCallback()
92 {
93 UpdateWindow();
94 }
95
96 private static void OnPlayModeStateChanged(PlayModeStateChange state)
97 {
98 if (s_Instance && state == PlayModeStateChange.EnteredEditMode)
99 {
100 var testListGUI = s_Instance.m_SelectedTestTypes;
101 if (testListGUI.HasTreeData())
102 {
103 //repaint message details after exit playmode
104 testListGUI.TestSelectionCallback(testListGUI.m_TestListState.selectedIDs.ToArray());
105 s_Instance.Repaint();
106 }
107 }
108 }
109
110 internal void OnDestroy()
111 {
112 EditorApplication.playModeStateChanged -= OnPlayModeStateChanged;
113 }
114
115 private void OnEnable()
116 {
117 s_Instance = this;
118 titleContent = new GUIContent(WindowTitle, "Test framework for running Edit mode and Play mode tests in Unity. Part of the com.unity.test-framework package.");
119 SelectTestListGUI(m_TestTypeToolbarIndex);
120
121 m_testRunnerApi = CreateInstance<TestRunnerApi>();
122 m_WindowResultUpdater = new WindowResultUpdater();
123 m_testRunnerApi.RegisterCallbacks(m_WindowResultUpdater);
124 }
125
126 private void Enable()
127 {
128 m_Settings = new TestRunnerWindowSettings("UnityEditor.PlaymodeTestsRunnerWindow");
129
130 if (m_SelectedTestTypes == null)
131 {
132 SelectTestListGUI(m_TestTypeToolbarIndex);
133 }
134
135 StartRetrieveTestList();
136 m_SelectedTestTypes.Reload();
137 m_Enabled = true;
138 }
139
140 private void SelectTestListGUI(TestRunnerMenuLabels testTypeToolbarIndex)
141 {
142 if (m_TestListGUIs == null)
143 {
144 m_TestListGUIs = new TestListGUI[]
145 {
146 new TestListGUI()
147 {
148 m_TestMode = TestMode.EditMode,
149 },
150 new TestListGUI()
151 {
152 m_TestMode = TestMode.PlayMode,
153 },
154 new TestListGUI()
155 {
156 m_TestMode = TestMode.PlayMode,
157 m_RunOnPlatform = true
158 }
159 };
160 }
161
162 m_TestListGUIs[0].m_TestMode = TestMode.EditMode;
163 m_TestListGUIs[0].m_RunOnPlatform = false;
164 m_TestListGUIs[1].m_TestMode = TestMode.PlayMode;
165 m_TestListGUIs[1].m_RunOnPlatform = false;
166 m_TestListGUIs[2].m_TestMode = TestMode.PlayMode;
167 m_TestListGUIs[2].m_RunOnPlatform = true;
168
169 m_SelectedTestTypes = m_TestListGUIs[(int)testTypeToolbarIndex];
170 }
171
172 private void StartRetrieveTestList()
173 {
174 var listToInit = m_SelectedTestTypes;
175 m_testRunnerApi.RetrieveTestList(listToInit.m_TestMode, rootTest =>
176 {
177 listToInit.Init(this, rootTest);
178 listToInit.Reload();
179 });
180 }
181
182 internal void OnGUI()
183 {
184 if (!m_Enabled)
185 {
186 Enable();
187 }
188
189 if (BuildPipeline.isBuildingPlayer)
190 {
191 m_IsBuilding = true;
192 }
193 else if (m_IsBuilding)
194 {
195 m_IsBuilding = false;
196 Repaint();
197 }
198
199 EditorGUILayout.BeginHorizontal();
200 GUILayout.FlexibleSpace();
201 var selectedIndex = m_TestTypeToolbarIndex;
202 m_TestTypeToolbarIndex = (TestRunnerMenuLabels)GUILayout.Toolbar((int)m_TestTypeToolbarIndex, Enum.GetNames(typeof(TestRunnerMenuLabels)), "LargeButton", UnityEngine.GUI.ToolbarButtonSize.FitToContents);
203 GUILayout.FlexibleSpace();
204 EditorGUILayout.EndHorizontal();
205
206 if (selectedIndex != m_TestTypeToolbarIndex)
207 {
208 SelectTestListGUI(m_TestTypeToolbarIndex);
209 StartRetrieveTestList();
210 }
211
212 EditorGUILayout.BeginVertical();
213 using (new EditorGUI.DisabledScope(EditorApplication.isPlayingOrWillChangePlaymode))
214 {
215 m_SelectedTestTypes.PrintHeadPanel();
216 }
217 EditorGUILayout.EndVertical();
218
219 if (m_Settings.verticalSplit)
220 SplitterGUILayout.BeginVerticalSplit(m_Spl);
221 else
222 SplitterGUILayout.BeginHorizontalSplit(m_Spl);
223
224 EditorGUILayout.BeginVertical();
225 EditorGUILayout.BeginVertical(Styles.testList);
226 m_SelectedTestTypes.RenderTestList();
227 EditorGUILayout.EndVertical();
228 EditorGUILayout.EndVertical();
229
230 m_SelectedTestTypes.RenderDetails(position.width);
231
232 if (m_Settings.verticalSplit)
233 SplitterGUILayout.EndVerticalSplit();
234 else
235 SplitterGUILayout.EndHorizontalSplit();
236
237 m_SelectedTestTypes.PrintProgressBar(position);
238
239 EditorGUILayout.BeginVertical();
240 using (new EditorGUI.DisabledScope(EditorApplication.isPlayingOrWillChangePlaymode))
241 {
242 m_SelectedTestTypes.PrintBottomPanel();
243 }
244 EditorGUILayout.EndVertical();
245 }
246
247 /// <summary>
248 /// Adds additional menu items to the Test Runner window.
249 /// </summary>
250 /// <param name="menu">The <see cref="GenericMenu"/></param>
251 public void AddItemsToMenu(GenericMenu menu)
252 {
253 menu.AddItem(m_GUIVerticalSplit, m_Settings.verticalSplit, m_Settings.ToggleVerticalSplit);
254 menu.AddItem(m_GUIHorizontalSplit, !m_Settings.verticalSplit, m_Settings.ToggleVerticalSplit);
255
256 menu.AddSeparator(null);
257
258 if (EditorPrefs.GetBool("InternalMode", false))
259 {
260 menu.AddItem(m_GUIRunPlayModeTestAsEditModeTests, PlayerSettings.runPlayModeTestAsEditModeTest, () =>
261 {
262 PlayerSettings.runPlayModeTestAsEditModeTest = !PlayerSettings.runPlayModeTestAsEditModeTest;
263 });
264 }
265
266 if (PlayerSettings.playModeTestRunnerEnabled)
267 {
268 PlayerSettings.playModeTestRunnerEnabled = false;
269 EditorUtility.DisplayDialog(m_GUIDisablePlaymodeTestsRunner.text, "You need to restart the editor now", "Ok");
270 }
271 }
272
273 internal void RebuildUIFilter()
274 {
275 if (m_SelectedTestTypes != null && m_SelectedTestTypes.HasTreeData())
276 {
277 m_SelectedTestTypes.RebuildUIFilter();
278 }
279 }
280
281 internal static void UpdateWindow()
282 {
283 if (s_Instance != null && s_Instance.m_SelectedTestTypes != null)
284 {
285 s_Instance.m_SelectedTestTypes.Repaint();
286 s_Instance.Repaint();
287 }
288 }
289 }
290}