An easy to use Unity 3D library for creating illustrated Interactive Fiction games and more.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

227 lines
8.9 KiB

using System;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;
using UnityEditor.Callbacks;
namespace UnityTest
{
[Serializable]
public partial class UnitTestView : EditorWindow, IHasCustomMenu
{
private static UnitTestView s_Instance;
private static readonly IUnitTestEngine k_TestEngine = new NUnitTestEngine();
[SerializeField] private List<UnitTestResult> m_ResultList = new List<UnitTestResult>();
[SerializeField] private List<string> m_FoldMarkers = new List<string>();
[SerializeField] private List<UnitTestRendererLine> m_SelectedLines = new List<UnitTestRendererLine>();
UnitTestRendererLine m_TestLines;
private TestFilterSettings m_FilterSettings;
#region runner steering vars
private Vector2 m_TestListScroll, m_TestInfoScroll;
private float m_HorizontalSplitBarPosition = 200;
private float m_VerticalSplitBarPosition = 300;
#endregion
private UnitTestsRunnerSettings m_Settings;
#region GUI Contents
private readonly GUIContent m_GUIRunSelectedTestsIcon = new GUIContent("Run Selected", "Run selected tests");
private readonly GUIContent m_GUIRunAllTestsIcon = new GUIContent("Run All", "Run all tests");
private readonly GUIContent m_GUIRerunFailedTestsIcon = new GUIContent("Rerun Failed", "Rerun failed tests");
private readonly GUIContent m_GUIRunOnRecompile = new GUIContent("Run on recompile", "Run all tests after recompilation");
private readonly GUIContent m_GUIShowDetailsBelowTests = new GUIContent("Show details below tests", "Show run details below test list");
private readonly GUIContent m_GUIRunTestsOnNewScene = new GUIContent("Run tests on a new scene", "Run tests on a new scene");
private readonly GUIContent m_GUIAutoSaveSceneBeforeRun = new GUIContent("Autosave scene", "The runner will automatically save the current scene changes before it starts");
#endregion
public UnitTestView()
{
m_ResultList.Clear();
}
public void OnEnable()
{
titleContent = new GUIContent("Unit Tests");
s_Instance = this;
m_Settings = ProjectSettingsBase.Load<UnitTestsRunnerSettings>();
m_FilterSettings = new TestFilterSettings("UnityTest.UnitTestView");
RefreshTests();
}
[DidReloadScripts]
public static void OnDidReloadScripts()
{
if (s_Instance != null && s_Instance.m_Settings.runOnRecompilation)
{
s_Instance.RunTests();
s_Instance.Repaint();
}
}
public void OnDestroy()
{
s_Instance = null;
}
public void OnGUI()
{
EditorGUILayout.BeginVertical();
EditorGUILayout.BeginHorizontal(EditorStyles.toolbar);
if (GUILayout.Button(m_GUIRunAllTestsIcon, EditorStyles.toolbarButton))
{
RunTests();
GUIUtility.ExitGUI();
}
EditorGUI.BeginDisabledGroup(!m_TestLines.IsAnySelected);
if (GUILayout.Button(m_GUIRunSelectedTestsIcon, EditorStyles.toolbarButton))
{
m_TestLines.RunSelectedTests();
}
EditorGUI.EndDisabledGroup();
if (GUILayout.Button(m_GUIRerunFailedTestsIcon, EditorStyles.toolbarButton))
{
m_TestLines.RunTests(m_ResultList.Where(result => result.IsFailure || result.IsError).Select(l => l.FullName).ToArray());
}
GUILayout.FlexibleSpace();
m_FilterSettings.OnGUI ();
EditorGUILayout.EndHorizontal();
if (m_Settings.horizontalSplit)
EditorGUILayout.BeginVertical();
else
EditorGUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
RenderTestList();
RenderTestInfo();
if (m_Settings.horizontalSplit)
EditorGUILayout.EndVertical();
else
EditorGUILayout.EndHorizontal();
EditorGUILayout.EndVertical();
}
private void RenderTestList()
{
EditorGUILayout.BeginVertical(Styles.testList);
m_TestListScroll = EditorGUILayout.BeginScrollView(m_TestListScroll,
GUILayout.ExpandWidth(true),
GUILayout.MaxWidth(2000));
if (m_TestLines != null)
{
if (m_TestLines.Render(m_FilterSettings.BuildRenderingOptions())) Repaint();
}
EditorGUILayout.EndScrollView();
EditorGUILayout.EndVertical();
}
private void RenderTestInfo()
{
var ctrlId = GUIUtility.GetControlID(FocusType.Passive);
var rect = GUILayoutUtility.GetLastRect();
if (m_Settings.horizontalSplit)
{
rect.y = rect.height + rect.y - 1;
rect.height = 3;
}
else
{
rect.x = rect.width + rect.x - 1;
rect.width = 3;
}
EditorGUIUtility.AddCursorRect(rect, m_Settings.horizontalSplit ? MouseCursor.ResizeVertical : MouseCursor.ResizeHorizontal);
var e = Event.current;
switch (e.type)
{
case EventType.MouseDown:
if (GUIUtility.hotControl == 0 && rect.Contains(e.mousePosition))
GUIUtility.hotControl = ctrlId;
break;
case EventType.MouseDrag:
if (GUIUtility.hotControl == ctrlId)
{
m_HorizontalSplitBarPosition -= e.delta.y;
if (m_HorizontalSplitBarPosition < 20) m_HorizontalSplitBarPosition = 20;
m_VerticalSplitBarPosition -= e.delta.x;
if (m_VerticalSplitBarPosition < 20) m_VerticalSplitBarPosition = 20;
Repaint();
}
break;
case EventType.MouseUp:
if (GUIUtility.hotControl == ctrlId)
GUIUtility.hotControl = 0;
break;
}
m_TestInfoScroll = EditorGUILayout.BeginScrollView(m_TestInfoScroll, m_Settings.horizontalSplit
? GUILayout.MinHeight(m_HorizontalSplitBarPosition)
: GUILayout.Width(m_VerticalSplitBarPosition));
var text = "";
if (m_SelectedLines.Any())
{
text = m_SelectedLines.First().GetResultText();
}
var resultTextSize = Styles.info.CalcSize(new GUIContent(text));
EditorGUILayout.SelectableLabel(text, Styles.info,
GUILayout.ExpandHeight(true),
GUILayout.ExpandWidth(true),
GUILayout.MinWidth(resultTextSize.x),
GUILayout.MinHeight(resultTextSize.y));
EditorGUILayout.EndScrollView();
}
private void ToggleRunOnRecompilation()
{
m_Settings.runOnRecompilation = !m_Settings.runOnRecompilation;
}
public void AddItemsToMenu (GenericMenu menu)
{
menu.AddItem(m_GUIRunOnRecompile, m_Settings.runOnRecompilation, ToggleRunOnRecompilation);
menu.AddItem(m_GUIRunTestsOnNewScene, m_Settings.runTestOnANewScene, m_Settings.ToggleRunTestOnANewScene);
if(!m_Settings.runTestOnANewScene)
menu.AddDisabledItem(m_GUIAutoSaveSceneBeforeRun);
else
menu.AddItem(m_GUIAutoSaveSceneBeforeRun, m_Settings.autoSaveSceneBeforeRun, m_Settings.ToggleAutoSaveSceneBeforeRun);
menu.AddItem(m_GUIShowDetailsBelowTests, m_Settings.horizontalSplit, m_Settings.ToggleHorizontalSplit);
}
private void RefreshTests()
{
UnitTestResult[] newResults;
m_TestLines = k_TestEngine.GetTests(out newResults, out m_FilterSettings.AvailableCategories);
foreach (var newResult in newResults)
{
var result = m_ResultList.Where(t => t.Test == newResult.Test && t.FullName == newResult.FullName).ToArray();
if (result.Count() != 1) continue;
newResult.Update(result.Single(), true);
}
UnitTestRendererLine.SelectedLines = m_SelectedLines;
UnitTestRendererLine.RunTest = RunTests;
GroupLine.FoldMarkers = m_FoldMarkers;
TestLine.GetUnitTestResult = FindTestResult;
m_ResultList = new List<UnitTestResult>(newResults);
m_FilterSettings.UpdateCounters(m_ResultList.Cast<ITestResult>());
Repaint();
}
}
}