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.

161 lines
6.0 KiB

using System;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;
using Object = UnityEngine.Object;
namespace UnityTest
{
public abstract class IntegrationTestRendererBase : IComparable<IntegrationTestRendererBase>
{
public static Action<IList<ITestComponent>> RunTest;
protected static bool s_Refresh;
private static readonly GUIContent k_GUIRunSelected = new GUIContent("Run Selected");
private static readonly GUIContent k_GUIRun = new GUIContent("Run");
private static readonly GUIContent k_GUIDelete = new GUIContent("Delete");
private static readonly GUIContent k_GUIDeleteSelected = new GUIContent("Delete selected");
protected static GUIContent s_GUITimeoutIcon = new GUIContent(Icons.StopwatchImg, "Timeout");
protected GameObject m_GameObject;
public TestComponent test;
private readonly string m_Name;
protected IntegrationTestRendererBase(GameObject gameObject)
{
test = gameObject.GetComponent(typeof(TestComponent)) as TestComponent;
if (test == null) throw new ArgumentException("Provided GameObject is not a test object");
m_GameObject = gameObject;
m_Name = test.Name;
}
public int CompareTo(IntegrationTestRendererBase other)
{
return test.CompareTo(other.test);
}
public bool Render(RenderingOptions options)
{
s_Refresh = false;
EditorGUIUtility.SetIconSize(new Vector2(15, 15));
Render(0, options);
EditorGUIUtility.SetIconSize(Vector2.zero);
return s_Refresh;
}
protected internal virtual void Render(int indend, RenderingOptions options)
{
if (!IsVisible(options)) return;
EditorGUILayout.BeginHorizontal();
GUILayout.Space(indend * 10);
var tempColor = GUI.color;
if (m_IsRunning)
{
var frame = Mathf.Abs(Mathf.Cos(Time.realtimeSinceStartup * 4)) * 0.6f + 0.4f;
GUI.color = new Color(1, 1, 1, frame);
}
var isSelected = Selection.gameObjects.Contains(m_GameObject);
var value = GetResult();
var icon = GetIconForResult(value);
var label = new GUIContent(m_Name, icon);
var labelRect = GUILayoutUtility.GetRect(label, EditorStyles.label, GUILayout.ExpandWidth(true), GUILayout.Height(18));
OnLeftMouseButtonClick(labelRect);
OnContextClick(labelRect);
DrawLine(labelRect, label, isSelected, options);
if (m_IsRunning) GUI.color = tempColor;
EditorGUILayout.EndHorizontal();
}
protected void OnSelect()
{
if (!Event.current.control && !Event.current.command)
{
Selection.objects = new Object[0];
GUIUtility.keyboardControl = 0;
}
if ((Event.current.control || Event.current.command) && Selection.gameObjects.Contains(test.gameObject))
Selection.objects = Selection.gameObjects.Where(o => o != test.gameObject).ToArray();
else
Selection.objects = Selection.gameObjects.Concat(new[] { test.gameObject }).ToArray();
}
protected void OnLeftMouseButtonClick(Rect rect)
{
if (rect.Contains(Event.current.mousePosition) && Event.current.type == EventType.mouseDown && Event.current.button == 0)
{
rect.width = 20;
if (rect.Contains(Event.current.mousePosition)) return;
Event.current.Use();
OnSelect();
}
}
protected void OnContextClick(Rect rect)
{
if (rect.Contains(Event.current.mousePosition) && Event.current.type == EventType.ContextClick)
{
DrawContextMenu(test);
}
}
public static void DrawContextMenu(TestComponent testComponent)
{
if (EditorApplication.isPlayingOrWillChangePlaymode) return;
var selectedTests = Selection.gameObjects.Where(go => go.GetComponent(typeof(TestComponent)));
var manySelected = selectedTests.Count() > 1;
var m = new GenericMenu();
if (manySelected)
{
// var testsToRun
m.AddItem(k_GUIRunSelected, false, data => RunTest(selectedTests.Select(o => o.GetComponent(typeof(TestComponent))).Cast<ITestComponent>().ToList()), null);
}
m.AddItem(k_GUIRun, false, data => RunTest(new[] { testComponent }), null);
m.AddSeparator("");
m.AddItem(manySelected ? k_GUIDeleteSelected : k_GUIDelete, false, data => RemoveTests(selectedTests.ToArray()), null);
m.ShowAsContext();
}
private static void RemoveTests(GameObject[] testsToDelete)
{
foreach (var t in testsToDelete)
{
Undo.DestroyObjectImmediate(t);
}
}
public static Texture GetIconForResult(TestResult.ResultType resultState)
{
switch (resultState)
{
case TestResult.ResultType.Success:
return Icons.SuccessImg;
case TestResult.ResultType.Timeout:
case TestResult.ResultType.Failed:
case TestResult.ResultType.FailedException:
return Icons.FailImg;
case TestResult.ResultType.Ignored:
return Icons.IgnoreImg;
default:
return Icons.UnknownImg;
}
}
protected internal bool m_IsRunning;
protected internal abstract void DrawLine(Rect rect, GUIContent label, bool isSelected, RenderingOptions options);
protected internal abstract TestResult.ResultType GetResult();
protected internal abstract bool IsVisible(RenderingOptions options);
public abstract bool SetCurrentTest(TestComponent tc);
}
}