Browse Source

Added Unity Test Tools asset

The test framework and tests will not be included in the published
Fungus unitypackage.
master
chrisgregan 10 years ago
parent
commit
a84706f2e1
  1. 9
      Assets/UnityTestTools.meta
  2. 5
      Assets/UnityTestTools/Assertions.meta
  3. 379
      Assets/UnityTestTools/Assertions/AssertionComponent.cs
  4. 8
      Assets/UnityTestTools/Assertions/AssertionComponent.cs.meta
  5. 24
      Assets/UnityTestTools/Assertions/AssertionException.cs
  6. 8
      Assets/UnityTestTools/Assertions/AssertionException.cs.meta
  7. 42
      Assets/UnityTestTools/Assertions/Assertions.cs
  8. 8
      Assets/UnityTestTools/Assertions/Assertions.cs.meta
  9. 36
      Assets/UnityTestTools/Assertions/CheckMethod.cs
  10. 8
      Assets/UnityTestTools/Assertions/CheckMethod.cs.meta
  11. 5
      Assets/UnityTestTools/Assertions/Comparers.meta
  12. 121
      Assets/UnityTestTools/Assertions/Comparers/ActionBase.cs
  13. 8
      Assets/UnityTestTools/Assertions/Comparers/ActionBase.cs.meta
  14. 14
      Assets/UnityTestTools/Assertions/Comparers/BoolComparer.cs
  15. 8
      Assets/UnityTestTools/Assertions/Comparers/BoolComparer.cs.meta
  16. 29
      Assets/UnityTestTools/Assertions/Comparers/ColliderComparer.cs
  17. 8
      Assets/UnityTestTools/Assertions/Comparers/ColliderComparer.cs.meta
  18. 145
      Assets/UnityTestTools/Assertions/Comparers/ComparerBase.cs
  19. 8
      Assets/UnityTestTools/Assertions/Comparers/ComparerBase.cs.meta
  20. 40
      Assets/UnityTestTools/Assertions/Comparers/FloatComparer.cs
  21. 8
      Assets/UnityTestTools/Assertions/Comparers/FloatComparer.cs.meta
  22. 22
      Assets/UnityTestTools/Assertions/Comparers/GeneralComparer.cs
  23. 8
      Assets/UnityTestTools/Assertions/Comparers/GeneralComparer.cs.meta
  24. 41
      Assets/UnityTestTools/Assertions/Comparers/IntComparer.cs
  25. 8
      Assets/UnityTestTools/Assertions/Comparers/IntComparer.cs.meta
  26. 31
      Assets/UnityTestTools/Assertions/Comparers/IsRenderedByCamera.cs
  27. 8
      Assets/UnityTestTools/Assertions/Comparers/IsRenderedByCamera.cs.meta
  28. 42
      Assets/UnityTestTools/Assertions/Comparers/StringComparer.cs
  29. 8
      Assets/UnityTestTools/Assertions/Comparers/StringComparer.cs.meta
  30. 26
      Assets/UnityTestTools/Assertions/Comparers/TransformComparer.cs
  31. 8
      Assets/UnityTestTools/Assertions/Comparers/TransformComparer.cs.meta
  32. 20
      Assets/UnityTestTools/Assertions/Comparers/ValueDoesNotChange.cs
  33. 8
      Assets/UnityTestTools/Assertions/Comparers/ValueDoesNotChange.cs.meta
  34. 36
      Assets/UnityTestTools/Assertions/Comparers/Vector2Comparer.cs
  35. 8
      Assets/UnityTestTools/Assertions/Comparers/Vector2Comparer.cs.meta
  36. 32
      Assets/UnityTestTools/Assertions/Comparers/Vector3Comparer.cs
  37. 8
      Assets/UnityTestTools/Assertions/Comparers/Vector3Comparer.cs.meta
  38. 38
      Assets/UnityTestTools/Assertions/Comparers/Vector4Comparer.cs
  39. 8
      Assets/UnityTestTools/Assertions/Comparers/Vector4Comparer.cs.meta
  40. 18
      Assets/UnityTestTools/Assertions/Comparers/VectorComparerBase.cs
  41. 8
      Assets/UnityTestTools/Assertions/Comparers/VectorComparerBase.cs.meta
  42. 5
      Assets/UnityTestTools/Assertions/Editor.meta
  43. 212
      Assets/UnityTestTools/Assertions/Editor/AssertionComponentEditor.cs
  44. 8
      Assets/UnityTestTools/Assertions/Editor/AssertionComponentEditor.cs.meta
  45. 194
      Assets/UnityTestTools/Assertions/Editor/AssertionExplorerWindow.cs
  46. 8
      Assets/UnityTestTools/Assertions/Editor/AssertionExplorerWindow.cs.meta
  47. 251
      Assets/UnityTestTools/Assertions/Editor/AssertionListRenderer.cs
  48. 8
      Assets/UnityTestTools/Assertions/Editor/AssertionListRenderer.cs.meta
  49. 25
      Assets/UnityTestTools/Assertions/Editor/AssertionStripper.cs
  50. 8
      Assets/UnityTestTools/Assertions/Editor/AssertionStripper.cs.meta
  51. 78
      Assets/UnityTestTools/Assertions/Editor/DropDownControl.cs
  52. 8
      Assets/UnityTestTools/Assertions/Editor/DropDownControl.cs.meta
  53. 20
      Assets/UnityTestTools/Assertions/Editor/GroupByComparerRenderer.cs
  54. 8
      Assets/UnityTestTools/Assertions/Editor/GroupByComparerRenderer.cs.meta
  55. 31
      Assets/UnityTestTools/Assertions/Editor/GroupByExecutionMethodRenderer.cs
  56. 8
      Assets/UnityTestTools/Assertions/Editor/GroupByExecutionMethodRenderer.cs.meta
  57. 34
      Assets/UnityTestTools/Assertions/Editor/GroupByGORenderer.cs
  58. 8
      Assets/UnityTestTools/Assertions/Editor/GroupByGORenderer.cs.meta
  59. 20
      Assets/UnityTestTools/Assertions/Editor/GroupByNothingRenderer.cs
  60. 8
      Assets/UnityTestTools/Assertions/Editor/GroupByNothingRenderer.cs.meta
  61. 29
      Assets/UnityTestTools/Assertions/Editor/GroupByTestsRenderer.cs
  62. 8
      Assets/UnityTestTools/Assertions/Editor/GroupByTestsRenderer.cs.meta
  63. 207
      Assets/UnityTestTools/Assertions/Editor/PropertyPathSelector.cs
  64. 8
      Assets/UnityTestTools/Assertions/Editor/PropertyPathSelector.cs.meta
  65. 188
      Assets/UnityTestTools/Assertions/Editor/PropertyResolver.cs
  66. 8
      Assets/UnityTestTools/Assertions/Editor/PropertyResolver.cs.meta
  67. 14
      Assets/UnityTestTools/Assertions/InvalidPathException.cs
  68. 8
      Assets/UnityTestTools/Assertions/InvalidPathException.cs.meta
  69. 208
      Assets/UnityTestTools/Assertions/MemberResolver.cs
  70. 8
      Assets/UnityTestTools/Assertions/MemberResolver.cs.meta
  71. 5
      Assets/UnityTestTools/Common.meta
  72. 4
      Assets/UnityTestTools/Common/Editor.meta
  73. 57
      Assets/UnityTestTools/Common/Editor/Icons.cs
  74. 8
      Assets/UnityTestTools/Common/Editor/Icons.cs.meta
  75. 39
      Assets/UnityTestTools/Common/Editor/ProjectSettingsBase.cs
  76. 8
      Assets/UnityTestTools/Common/Editor/ProjectSettingsBase.cs.meta
  77. 5
      Assets/UnityTestTools/Common/Editor/ResultWriter.meta
  78. 173
      Assets/UnityTestTools/Common/Editor/ResultWriter/ResultSummarizer.cs
  79. 8
      Assets/UnityTestTools/Common/Editor/ResultWriter/ResultSummarizer.cs.meta
  80. 62
      Assets/UnityTestTools/Common/Editor/ResultWriter/StackTraceFilter.cs
  81. 8
      Assets/UnityTestTools/Common/Editor/ResultWriter/StackTraceFilter.cs.meta
  82. 303
      Assets/UnityTestTools/Common/Editor/ResultWriter/XmlResultWriter.cs
  83. 8
      Assets/UnityTestTools/Common/Editor/ResultWriter/XmlResultWriter.cs.meta
  84. 47
      Assets/UnityTestTools/Common/Editor/Styles.cs
  85. 8
      Assets/UnityTestTools/Common/Editor/Styles.cs.meta
  86. 104
      Assets/UnityTestTools/Common/Editor/TestFilterSettings.cs
  87. 8
      Assets/UnityTestTools/Common/Editor/TestFilterSettings.cs.meta
  88. 4
      Assets/UnityTestTools/Common/Editor/icons.meta
  89. BIN
      Assets/UnityTestTools/Common/Editor/icons/failed.png
  90. 35
      Assets/UnityTestTools/Common/Editor/icons/failed.png.meta
  91. BIN
      Assets/UnityTestTools/Common/Editor/icons/ignored.png
  92. 35
      Assets/UnityTestTools/Common/Editor/icons/ignored.png.meta
  93. BIN
      Assets/UnityTestTools/Common/Editor/icons/inconclusive.png
  94. 35
      Assets/UnityTestTools/Common/Editor/icons/inconclusive.png.meta
  95. BIN
      Assets/UnityTestTools/Common/Editor/icons/normal.png
  96. 35
      Assets/UnityTestTools/Common/Editor/icons/normal.png.meta
  97. BIN
      Assets/UnityTestTools/Common/Editor/icons/passed.png
  98. 35
      Assets/UnityTestTools/Common/Editor/icons/passed.png.meta
  99. BIN
      Assets/UnityTestTools/Common/Editor/icons/stopwatch.png
  100. 35
      Assets/UnityTestTools/Common/Editor/icons/stopwatch.png.meta
  101. Some files were not shown because too many files have changed in this diff Show More

9
Assets/UnityTestTools.meta

@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 5c8e5d66ff19140a1bf3cfdc3955859c
folderAsset: yes
timeCreated: 1438859672
licenseType: Free
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

5
Assets/UnityTestTools/Assertions.meta

@ -0,0 +1,5 @@
fileFormatVersion: 2
guid: b27b28700d3365146808b6e082748201
folderAsset: yes
DefaultImporter:
userData:

379
Assets/UnityTestTools/Assertions/AssertionComponent.cs

@ -0,0 +1,379 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using UnityEngine;
using Debug = UnityEngine.Debug;
using Object = UnityEngine.Object;
namespace UnityTest
{
[Serializable]
public class AssertionComponent : MonoBehaviour, IAssertionComponentConfigurator
{
[SerializeField] public float checkAfterTime = 1f;
[SerializeField] public bool repeatCheckTime = true;
[SerializeField] public float repeatEveryTime = 1f;
[SerializeField] public int checkAfterFrames = 1;
[SerializeField] public bool repeatCheckFrame = true;
[SerializeField] public int repeatEveryFrame = 1;
[SerializeField] public bool hasFailed;
[SerializeField] public CheckMethod checkMethods = CheckMethod.Start;
[SerializeField] private ActionBase m_ActionBase;
[SerializeField] public int checksPerformed = 0;
private int m_CheckOnFrame;
private string m_CreatedInFilePath = "";
private int m_CreatedInFileLine = -1;
public ActionBase Action
{
get { return m_ActionBase; }
set
{
m_ActionBase = value;
m_ActionBase.go = gameObject;
}
}
public Object GetFailureReferenceObject()
{
#if UNITY_EDITOR
if (!string.IsNullOrEmpty(m_CreatedInFilePath))
{
return UnityEditor.AssetDatabase.LoadAssetAtPath(m_CreatedInFilePath, typeof(Object));
}
#endif
return this;
}
public string GetCreationLocation()
{
if (!string.IsNullOrEmpty(m_CreatedInFilePath))
{
var idx = m_CreatedInFilePath.LastIndexOf("\\") + 1;
return string.Format("{0}, line {1} ({2})", m_CreatedInFilePath.Substring(idx), m_CreatedInFileLine, m_CreatedInFilePath);
}
return "";
}
public void Awake()
{
if (!Debug.isDebugBuild)
Destroy(this);
OnComponentCopy();
}
public void OnValidate()
{
if (Application.isEditor)
OnComponentCopy();
}
private void OnComponentCopy()
{
if (m_ActionBase == null) return;
var oldActionList = Resources.FindObjectsOfTypeAll(typeof(AssertionComponent)).Where(o => ((AssertionComponent)o).m_ActionBase == m_ActionBase && o != this);
// if it's not a copy but a new component don't do anything
if (!oldActionList.Any()) return;
if (oldActionList.Count() > 1)
Debug.LogWarning("More than one refence to comparer found. This shouldn't happen");
var oldAction = oldActionList.First() as AssertionComponent;
m_ActionBase = oldAction.m_ActionBase.CreateCopy(oldAction.gameObject, gameObject);
}
public void Start()
{
CheckAssertionFor(CheckMethod.Start);
if (IsCheckMethodSelected(CheckMethod.AfterPeriodOfTime))
{
StartCoroutine("CheckPeriodically");
}
if (IsCheckMethodSelected(CheckMethod.Update))
{
m_CheckOnFrame = Time.frameCount + checkAfterFrames;
}
}
public IEnumerator CheckPeriodically()
{
yield return new WaitForSeconds(checkAfterTime);
CheckAssertionFor(CheckMethod.AfterPeriodOfTime);
while (repeatCheckTime)
{
yield return new WaitForSeconds(repeatEveryTime);
CheckAssertionFor(CheckMethod.AfterPeriodOfTime);
}
}
public bool ShouldCheckOnFrame()
{
if (Time.frameCount > m_CheckOnFrame)
{
if (repeatCheckFrame)
m_CheckOnFrame += repeatEveryFrame;
else
m_CheckOnFrame = Int32.MaxValue;
return true;
}
return false;
}
public void OnDisable()
{
CheckAssertionFor(CheckMethod.OnDisable);
}
public void OnEnable()
{
CheckAssertionFor(CheckMethod.OnEnable);
}
public void OnDestroy()
{
CheckAssertionFor(CheckMethod.OnDestroy);
}
public void Update()
{
if (IsCheckMethodSelected(CheckMethod.Update) && ShouldCheckOnFrame())
{
CheckAssertionFor(CheckMethod.Update);
}
}
public void FixedUpdate()
{
CheckAssertionFor(CheckMethod.FixedUpdate);
}
public void LateUpdate()
{
CheckAssertionFor(CheckMethod.LateUpdate);
}
public void OnControllerColliderHit()
{
CheckAssertionFor(CheckMethod.OnControllerColliderHit);
}
public void OnParticleCollision()
{
CheckAssertionFor(CheckMethod.OnParticleCollision);
}
public void OnJointBreak()
{
CheckAssertionFor(CheckMethod.OnJointBreak);
}
public void OnBecameInvisible()
{
CheckAssertionFor(CheckMethod.OnBecameInvisible);
}
public void OnBecameVisible()
{
CheckAssertionFor(CheckMethod.OnBecameVisible);
}
public void OnTriggerEnter()
{
CheckAssertionFor(CheckMethod.OnTriggerEnter);
}
public void OnTriggerExit()
{
CheckAssertionFor(CheckMethod.OnTriggerExit);
}
public void OnTriggerStay()
{
CheckAssertionFor(CheckMethod.OnTriggerStay);
}
public void OnCollisionEnter()
{
CheckAssertionFor(CheckMethod.OnCollisionEnter);
}
public void OnCollisionExit()
{
CheckAssertionFor(CheckMethod.OnCollisionExit);
}
public void OnCollisionStay()
{
CheckAssertionFor(CheckMethod.OnCollisionStay);
}
public void OnTriggerEnter2D()
{
CheckAssertionFor(CheckMethod.OnTriggerEnter2D);
}
public void OnTriggerExit2D()
{
CheckAssertionFor(CheckMethod.OnTriggerExit2D);
}
public void OnTriggerStay2D()
{
CheckAssertionFor(CheckMethod.OnTriggerStay2D);
}
public void OnCollisionEnter2D()
{
CheckAssertionFor(CheckMethod.OnCollisionEnter2D);
}
public void OnCollisionExit2D()
{
CheckAssertionFor(CheckMethod.OnCollisionExit2D);
}
public void OnCollisionStay2D()
{
CheckAssertionFor(CheckMethod.OnCollisionStay2D);
}
private void CheckAssertionFor(CheckMethod checkMethod)
{
if (IsCheckMethodSelected(checkMethod))
{
Assertions.CheckAssertions(this);
}
}
public bool IsCheckMethodSelected(CheckMethod method)
{
return method == (checkMethods & method);
}
#region Assertion Component create methods
public static T Create<T>(CheckMethod checkOnMethods, GameObject gameObject, string propertyPath) where T : ActionBase
{
IAssertionComponentConfigurator configurator;
return Create<T>(out configurator, checkOnMethods, gameObject, propertyPath);
}
public static T Create<T>(out IAssertionComponentConfigurator configurator, CheckMethod checkOnMethods, GameObject gameObject, string propertyPath) where T : ActionBase
{
return CreateAssertionComponent<T>(out configurator, checkOnMethods, gameObject, propertyPath);
}
public static T Create<T>(CheckMethod checkOnMethods, GameObject gameObject, string propertyPath, GameObject gameObject2, string propertyPath2) where T : ComparerBase
{
IAssertionComponentConfigurator configurator;
return Create<T>(out configurator, checkOnMethods, gameObject, propertyPath, gameObject2, propertyPath2);
}
public static T Create<T>(out IAssertionComponentConfigurator configurator, CheckMethod checkOnMethods, GameObject gameObject, string propertyPath, GameObject gameObject2, string propertyPath2) where T : ComparerBase
{
var comparer = CreateAssertionComponent<T>(out configurator, checkOnMethods, gameObject, propertyPath);
comparer.compareToType = ComparerBase.CompareToType.CompareToObject;
comparer.other = gameObject2;
comparer.otherPropertyPath = propertyPath2;
return comparer;
}
public static T Create<T>(CheckMethod checkOnMethods, GameObject gameObject, string propertyPath, object constValue) where T : ComparerBase
{
IAssertionComponentConfigurator configurator;
return Create<T>(out configurator, checkOnMethods, gameObject, propertyPath, constValue);
}
public static T Create<T>(out IAssertionComponentConfigurator configurator, CheckMethod checkOnMethods, GameObject gameObject, string propertyPath, object constValue) where T : ComparerBase
{
var comparer = CreateAssertionComponent<T>(out configurator, checkOnMethods, gameObject, propertyPath);
if (constValue == null)
{
comparer.compareToType = ComparerBase.CompareToType.CompareToNull;
return comparer;
}
comparer.compareToType = ComparerBase.CompareToType.CompareToConstantValue;
comparer.ConstValue = constValue;
return comparer;
}
private static T CreateAssertionComponent<T>(out IAssertionComponentConfigurator configurator, CheckMethod checkOnMethods, GameObject gameObject, string propertyPath) where T : ActionBase
{
var ac = gameObject.AddComponent<AssertionComponent>();
ac.checkMethods = checkOnMethods;
var comparer = ScriptableObject.CreateInstance<T>();
ac.Action = comparer;
ac.Action.go = gameObject;
ac.Action.thisPropertyPath = propertyPath;
configurator = ac;
#if !UNITY_METRO
var stackTrace = new StackTrace(true);
var thisFileName = stackTrace.GetFrame(0).GetFileName();
for (int i = 1; i < stackTrace.FrameCount; i++)
{
var stackFrame = stackTrace.GetFrame(i);
if (stackFrame.GetFileName() != thisFileName)
{
string filePath = stackFrame.GetFileName().Substring(Application.dataPath.Length - "Assets".Length);
ac.m_CreatedInFilePath = filePath;
ac.m_CreatedInFileLine = stackFrame.GetFileLineNumber();
break;
}
}
#endif // if !UNITY_METRO
return comparer;
}
#endregion
#region AssertionComponentConfigurator
public int UpdateCheckStartOnFrame { set { checkAfterFrames = value; } }
public int UpdateCheckRepeatFrequency { set { repeatEveryFrame = value; } }
public bool UpdateCheckRepeat { set { repeatCheckFrame = value; } }
public float TimeCheckStartAfter { set { checkAfterTime = value; } }
public float TimeCheckRepeatFrequency { set { repeatEveryTime = value; } }
public bool TimeCheckRepeat { set { repeatCheckTime = value; } }
public AssertionComponent Component { get { return this; } }
#endregion
}
public interface IAssertionComponentConfigurator
{
/// <summary>
/// If the assertion is evaluated in Update, after how many frame should the evaluation start. Deafult is 1 (first frame)
/// </summary>
int UpdateCheckStartOnFrame { set; }
/// <summary>
/// If the assertion is evaluated in Update and UpdateCheckRepeat is true, how many frame should pass between evaluations
/// </summary>
int UpdateCheckRepeatFrequency { set; }
/// <summary>
/// If the assertion is evaluated in Update, should the evaluation be repeated after UpdateCheckRepeatFrequency frames
/// </summary>
bool UpdateCheckRepeat { set; }
/// <summary>
/// If the assertion is evaluated after a period of time, after how many seconds the first evaluation should be done
/// </summary>
float TimeCheckStartAfter { set; }
/// <summary>
/// If the assertion is evaluated after a period of time and TimeCheckRepeat is true, after how many seconds should the next evaluation happen
/// </summary>
float TimeCheckRepeatFrequency { set; }
/// <summary>
/// If the assertion is evaluated after a period, should the evaluation happen again after TimeCheckRepeatFrequency seconds
/// </summary>
bool TimeCheckRepeat { set; }
AssertionComponent Component { get; }
}
}

8
Assets/UnityTestTools/Assertions/AssertionComponent.cs.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 8bafa54482a87ac4cbd7ff1bfd1ac93a
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

24
Assets/UnityTestTools/Assertions/AssertionException.cs

@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using UnityEngine;
namespace UnityTest
{
public class AssertionException : Exception
{
private readonly AssertionComponent m_Assertion;
public AssertionException(AssertionComponent assertion) : base(assertion.Action.GetFailureMessage())
{
m_Assertion = assertion;
}
public override string StackTrace
{
get
{
return "Created in " + m_Assertion.GetCreationLocation();
}
}
}
}

8
Assets/UnityTestTools/Assertions/AssertionException.cs.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: ef3769ab00d50bc4fbb05a9a91c741d9
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

42
Assets/UnityTestTools/Assertions/Assertions.cs

@ -0,0 +1,42 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using Object = UnityEngine.Object;
namespace UnityTest
{
public static class Assertions
{
public static void CheckAssertions()
{
var assertions = Object.FindObjectsOfType(typeof(AssertionComponent)) as AssertionComponent[];
CheckAssertions(assertions);
}
public static void CheckAssertions(AssertionComponent assertion)
{
CheckAssertions(new[] {assertion});
}
public static void CheckAssertions(GameObject gameObject)
{
CheckAssertions(gameObject.GetComponents<AssertionComponent>());
}
public static void CheckAssertions(AssertionComponent[] assertions)
{
if (!Debug.isDebugBuild)
return;
foreach (var assertion in assertions)
{
assertion.checksPerformed++;
var result = assertion.Action.Compare();
if (!result)
{
assertion.hasFailed = true;
assertion.Action.Fail(assertion);
}
}
}
}
}

8
Assets/UnityTestTools/Assertions/Assertions.cs.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 85280dad1e618c143bd3fb07a197b469
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

36
Assets/UnityTestTools/Assertions/CheckMethod.cs

@ -0,0 +1,36 @@
using System;
using System.Collections.Generic;
using UnityEngine;
namespace UnityTest
{
[Flags]
public enum CheckMethod
{
AfterPeriodOfTime = 1 << 0,
Start = 1 << 1,
Update = 1 << 2,
FixedUpdate = 1 << 3,
LateUpdate = 1 << 4,
OnDestroy = 1 << 5,
OnEnable = 1 << 6,
OnDisable = 1 << 7,
OnControllerColliderHit = 1 << 8,
OnParticleCollision = 1 << 9,
OnJointBreak = 1 << 10,
OnBecameInvisible = 1 << 11,
OnBecameVisible = 1 << 12,
OnTriggerEnter = 1 << 13,
OnTriggerExit = 1 << 14,
OnTriggerStay = 1 << 15,
OnCollisionEnter = 1 << 16,
OnCollisionExit = 1 << 17,
OnCollisionStay = 1 << 18,
OnTriggerEnter2D = 1 << 19,
OnTriggerExit2D = 1 << 20,
OnTriggerStay2D = 1 << 21,
OnCollisionEnter2D = 1 << 22,
OnCollisionExit2D = 1 << 23,
OnCollisionStay2D = 1 << 24,
}
}

8
Assets/UnityTestTools/Assertions/CheckMethod.cs.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: cbb75d1643c5a55439f8861a827f411b
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

5
Assets/UnityTestTools/Assertions/Comparers.meta

@ -0,0 +1,5 @@
fileFormatVersion: 2
guid: bb9e10c25f478c84f826ea85b03ec179
folderAsset: yes
DefaultImporter:
userData:

121
Assets/UnityTestTools/Assertions/Comparers/ActionBase.cs

@ -0,0 +1,121 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEngine;
namespace UnityTest
{
public abstract class ActionBase : ScriptableObject
{
public GameObject go;
protected object m_ObjVal;
private MemberResolver m_MemberResolver;
public string thisPropertyPath = "";
public virtual Type[] GetAccepatbleTypesForA()
{
return null;
}
public virtual int GetDepthOfSearch() { return 2; }
public virtual string[] GetExcludedFieldNames()
{
return new string[] { };
}
public bool Compare()
{
if (m_MemberResolver == null)
m_MemberResolver = new MemberResolver(go, thisPropertyPath);
m_ObjVal = m_MemberResolver.GetValue(UseCache);
var result = Compare(m_ObjVal);
return result;
}
protected abstract bool Compare(object objVal);
virtual protected bool UseCache { get { return false; } }
public virtual Type GetParameterType() { return typeof(object); }
public virtual string GetConfigurationDescription()
{
string result = "";
#if !UNITY_METRO
foreach (var prop in GetType().GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)
.Where(info => info.FieldType.IsSerializable))
{
var value = prop.GetValue(this);
if (value is double)
value = ((double)value).ToString("0.########");
if (value is float)
value = ((float)value).ToString("0.########");
result += value + " ";
}
#endif // if !UNITY_METRO
return result;
}
IEnumerable<FieldInfo> GetFields(Type type)
{
#if !UNITY_METRO
return type.GetFields(BindingFlags.Public | BindingFlags.Instance);
#else
return null;
#endif
}
public ActionBase CreateCopy(GameObject oldGameObject, GameObject newGameObject)
{
#if !UNITY_METRO
var newObj = CreateInstance(GetType()) as ActionBase;
#else
var newObj = (ActionBase) this.MemberwiseClone();
#endif
var fields = GetFields(GetType());
foreach (var field in fields)
{
var value = field.GetValue(this);
if (value is GameObject)
{
if (value as GameObject == oldGameObject)
value = newGameObject;
}
field.SetValue(newObj, value);
}
return newObj;
}
public virtual void Fail(AssertionComponent assertion)
{
Debug.LogException(new AssertionException(assertion), assertion.GetFailureReferenceObject());
}
public virtual string GetFailureMessage()
{
return GetType().Name + " assertion failed.\n(" + go + ")." + thisPropertyPath + " failed. Value: " + m_ObjVal;
}
}
public abstract class ActionBaseGeneric<T> : ActionBase
{
protected override bool Compare(object objVal)
{
return Compare((T)objVal);
}
protected abstract bool Compare(T objVal);
public override Type[] GetAccepatbleTypesForA()
{
return new[] { typeof(T) };
}
public override Type GetParameterType()
{
return typeof(T);
}
protected override bool UseCache { get { return true; } }
}
}

8
Assets/UnityTestTools/Assertions/Comparers/ActionBase.cs.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: b4995756bd539804e8143ff1e730f806
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

14
Assets/UnityTestTools/Assertions/Comparers/BoolComparer.cs

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using UnityEngine;
namespace UnityTest
{
public class BoolComparer : ComparerBaseGeneric<bool>
{
protected override bool Compare(bool a, bool b)
{
return a == b;
}
}
}

8
Assets/UnityTestTools/Assertions/Comparers/BoolComparer.cs.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 2586c8e41f35d2f4fadde53020bf4207
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

29
Assets/UnityTestTools/Assertions/Comparers/ColliderComparer.cs

@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using UnityEngine;
namespace UnityTest
{
public class ColliderComparer : ComparerBaseGeneric<Bounds>
{
public enum CompareType
{
Intersects,
DoesNotIntersect
};
public CompareType compareType;
protected override bool Compare(Bounds a, Bounds b)
{
switch (compareType)
{
case CompareType.Intersects:
return a.Intersects(b);
case CompareType.DoesNotIntersect:
return !a.Intersects(b);
}
throw new Exception();
}
}
}

8
Assets/UnityTestTools/Assertions/Comparers/ColliderComparer.cs.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 4eff45b2ac4067b469d7994298341db6
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

145
Assets/UnityTestTools/Assertions/Comparers/ComparerBase.cs

@ -0,0 +1,145 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using Object = System.Object;
namespace UnityTest
{
public abstract class ComparerBase : ActionBase
{
public enum CompareToType
{
CompareToObject,
CompareToConstantValue,
CompareToNull
}
public CompareToType compareToType = CompareToType.CompareToObject;
public GameObject other;
protected object m_ObjOtherVal;
public string otherPropertyPath = "";
private MemberResolver m_MemberResolverB;
protected abstract bool Compare(object a, object b);
protected override bool Compare(object objValue)
{
if (compareToType == CompareToType.CompareToConstantValue)
{
m_ObjOtherVal = ConstValue;
}
else if (compareToType == CompareToType.CompareToNull)
{
m_ObjOtherVal = null;
}
else
{
if (other == null)
m_ObjOtherVal = null;
else
{
if (m_MemberResolverB == null)
m_MemberResolverB = new MemberResolver(other, otherPropertyPath);
m_ObjOtherVal = m_MemberResolverB.GetValue(UseCache);
}
}
return Compare(objValue, m_ObjOtherVal);
}
public virtual Type[] GetAccepatbleTypesForB()
{
return null;
}
#region Const value
public virtual object ConstValue { get; set; }
public virtual object GetDefaultConstValue()
{
throw new NotImplementedException();
}
#endregion
public override string GetFailureMessage()
{
var message = GetType().Name + " assertion failed.\n" + go.name + "." + thisPropertyPath + " " + compareToType;
switch (compareToType)
{
case CompareToType.CompareToObject:
message += " (" + other + ")." + otherPropertyPath + " failed.";
break;
case CompareToType.CompareToConstantValue:
message += " " + ConstValue + " failed.";
break;
case CompareToType.CompareToNull:
message += " failed.";
break;
}
message += " Expected: " + m_ObjOtherVal + " Actual: " + m_ObjVal;
return message;
}
}
[Serializable]
public abstract class ComparerBaseGeneric<T> : ComparerBaseGeneric<T, T>
{
}
[Serializable]
public abstract class ComparerBaseGeneric<T1, T2> : ComparerBase
{
public T2 constantValueGeneric = default(T2);
public override Object ConstValue
{
get
{
return constantValueGeneric;
}
set
{
constantValueGeneric = (T2)value;
}
}
public override Object GetDefaultConstValue()
{
return default(T2);
}
static bool IsValueType(Type type)
{
#if !UNITY_METRO
return type.IsValueType;
#else
return false;
#endif
}
protected override bool Compare(object a, object b)
{
var type = typeof(T2);
if (b == null && IsValueType(type))
{
throw new ArgumentException("Null was passed to a value-type argument");
}
return Compare((T1)a, (T2)b);
}
protected abstract bool Compare(T1 a, T2 b);
public override Type[] GetAccepatbleTypesForA()
{
return new[] { typeof(T1) };
}
public override Type[] GetAccepatbleTypesForB()
{
return new[] {typeof(T2)};
}
protected override bool UseCache { get { return true; } }
}
}

8
Assets/UnityTestTools/Assertions/Comparers/ComparerBase.cs.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: c86508f389d643b40b6e1d7dcc1d4df2
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

40
Assets/UnityTestTools/Assertions/Comparers/FloatComparer.cs

@ -0,0 +1,40 @@
using System;
using System.Collections.Generic;
using UnityEngine;
namespace UnityTest
{
public class FloatComparer : ComparerBaseGeneric<float>
{
public enum CompareTypes
{
Equal,
NotEqual,
Greater,
Less
}
public CompareTypes compareTypes;
public double floatingPointError = 0.0001f;
protected override bool Compare(float a, float b)
{
switch (compareTypes)
{
case CompareTypes.Equal:
return Math.Abs(a - b) < floatingPointError;
case CompareTypes.NotEqual:
return Math.Abs(a - b) > floatingPointError;
case CompareTypes.Greater:
return a > b;
case CompareTypes.Less:
return a < b;
}
throw new Exception();
}
public override int GetDepthOfSearch()
{
return 3;
}
}
}

8
Assets/UnityTestTools/Assertions/Comparers/FloatComparer.cs.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: a4928c6c2b973874c8d4e6c9a69bb5b4
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

22
Assets/UnityTestTools/Assertions/Comparers/GeneralComparer.cs

@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using UnityEngine;
namespace UnityTest
{
public class GeneralComparer : ComparerBase
{
public enum CompareType { AEqualsB, ANotEqualsB }
public CompareType compareType;
protected override bool Compare(object a, object b)
{
if (compareType == CompareType.AEqualsB)
return a.Equals(b);
if (compareType == CompareType.ANotEqualsB)
return !a.Equals(b);
throw new Exception();
}
}
}

8
Assets/UnityTestTools/Assertions/Comparers/GeneralComparer.cs.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 902961c69f102f4409c29b9e54258701
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

41
Assets/UnityTestTools/Assertions/Comparers/IntComparer.cs

@ -0,0 +1,41 @@
using System;
using System.Collections.Generic;
using UnityEngine;
namespace UnityTest
{
public class IntComparer : ComparerBaseGeneric<int>
{
public enum CompareType
{
Equal,
NotEqual,
Greater,
GreaterOrEqual,
Less,
LessOrEqual
};
public CompareType compareType;
protected override bool Compare(int a, int b)
{
switch (compareType)
{
case CompareType.Equal:
return a == b;
case CompareType.NotEqual:
return a != b;
case CompareType.Greater:
return a > b;
case CompareType.GreaterOrEqual:
return a >= b;
case CompareType.Less:
return a < b;
case CompareType.LessOrEqual:
return a <= b;
}
throw new Exception();
}
}
}

8
Assets/UnityTestTools/Assertions/Comparers/IntComparer.cs.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: da4a3a521c5c1494aae123742ca5c8f5
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

31
Assets/UnityTestTools/Assertions/Comparers/IsRenderedByCamera.cs

@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using UnityEngine;
namespace UnityTest
{
public class IsRenderedByCamera : ComparerBaseGeneric<Renderer, Camera>
{
public enum CompareType
{
IsVisible,
IsNotVisible,
};
public CompareType compareType;
protected override bool Compare(Renderer renderer, Camera camera)
{
var planes = GeometryUtility.CalculateFrustumPlanes(camera);
var isVisible = GeometryUtility.TestPlanesAABB(planes, renderer.bounds);
switch (compareType)
{
case CompareType.IsVisible:
return isVisible;
case CompareType.IsNotVisible:
return !isVisible;
}
throw new Exception();
}
}
}

8
Assets/UnityTestTools/Assertions/Comparers/IsRenderedByCamera.cs.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 8d45a1674f5e2e04485eafef922fac41
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

42
Assets/UnityTestTools/Assertions/Comparers/StringComparer.cs

@ -0,0 +1,42 @@
using System;
using System.Collections.Generic;
using UnityEngine;
namespace UnityTest
{
public class StringComparer : ComparerBaseGeneric<string>
{
public enum CompareType
{
Equal,
NotEqual,
Shorter,
Longer
}
public CompareType compareType;
public StringComparison comparisonType = StringComparison.Ordinal;
public bool ignoreCase = false;
protected override bool Compare(string a, string b)
{
if (ignoreCase)
{
a = a.ToLower();
b = b.ToLower();
}
switch (compareType)
{
case CompareType.Equal:
return String.Compare(a, b, comparisonType) == 0;
case CompareType.NotEqual:
return String.Compare(a, b, comparisonType) != 0;
case CompareType.Longer:
return String.Compare(a, b, comparisonType) > 0;
case CompareType.Shorter:
return String.Compare(a, b, comparisonType) < 0;
}
throw new Exception();
}
}
}

8
Assets/UnityTestTools/Assertions/Comparers/StringComparer.cs.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 58783f051e477fd4e93b42ec7a43bb64
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

26
Assets/UnityTestTools/Assertions/Comparers/TransformComparer.cs

@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using UnityEngine;
namespace UnityTest
{
public class TransformComparer : ComparerBaseGeneric<Transform>
{
public enum CompareType { Equals, NotEquals }
public CompareType compareType;
protected override bool Compare(Transform a, Transform b)
{
if (compareType == CompareType.Equals)
{
return a.position == b.position;
}
if (compareType == CompareType.NotEquals)
{
return a.position != b.position;
}
throw new Exception();
}
}
}

8
Assets/UnityTestTools/Assertions/Comparers/TransformComparer.cs.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 927f2d7e4f63632448b2a63d480e601a
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

20
Assets/UnityTestTools/Assertions/Comparers/ValueDoesNotChange.cs

@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using UnityEngine;
namespace UnityTest
{
public class ValueDoesNotChange : ActionBase
{
private object m_Value;
protected override bool Compare(object a)
{
if (m_Value == null)
m_Value = a;
if (!m_Value.Equals(a))
return false;
return true;
}
}
}

8
Assets/UnityTestTools/Assertions/Comparers/ValueDoesNotChange.cs.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 9d6d16a58a17940419a1dcbff3c60ca5
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

36
Assets/UnityTestTools/Assertions/Comparers/Vector2Comparer.cs

@ -0,0 +1,36 @@
using System;
using System.Collections.Generic;
using UnityEngine;
namespace UnityTest
{
public class Vector2Comparer : VectorComparerBase<Vector2>
{
public enum CompareType
{
MagnitudeEquals,
MagnitudeNotEquals
}
public CompareType compareType;
public float floatingPointError = 0.0001f;
protected override bool Compare(Vector2 a, Vector2 b)
{
switch (compareType)
{
case CompareType.MagnitudeEquals:
return AreVectorMagnitudeEqual(a.magnitude,
b.magnitude, floatingPointError);
case CompareType.MagnitudeNotEquals:
return !AreVectorMagnitudeEqual(a.magnitude,
b.magnitude, floatingPointError);
}
throw new Exception();
}
public override int GetDepthOfSearch()
{
return 3;
}
}
}

8
Assets/UnityTestTools/Assertions/Comparers/Vector2Comparer.cs.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: a713db190443e814f8254a5a59014ec4
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

32
Assets/UnityTestTools/Assertions/Comparers/Vector3Comparer.cs

@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using UnityEngine;
namespace UnityTest
{
public class Vector3Comparer : VectorComparerBase<Vector3>
{
public enum CompareType
{
MagnitudeEquals,
MagnitudeNotEquals
}
public CompareType compareType;
public double floatingPointError = 0.0001f;
protected override bool Compare(Vector3 a, Vector3 b)
{
switch (compareType)
{
case CompareType.MagnitudeEquals:
return AreVectorMagnitudeEqual(a.magnitude,
b.magnitude, floatingPointError);
case CompareType.MagnitudeNotEquals:
return !AreVectorMagnitudeEqual(a.magnitude,
b.magnitude, floatingPointError);
}
throw new Exception();
}
}
}

8
Assets/UnityTestTools/Assertions/Comparers/Vector3Comparer.cs.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 6febd2d5046657040b3da98b7010ee29
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

38
Assets/UnityTestTools/Assertions/Comparers/Vector4Comparer.cs

@ -0,0 +1,38 @@
using System;
using System.Collections.Generic;
using UnityEngine;
namespace UnityTest
{
public class Vector4Comparer : VectorComparerBase<Vector4>
{
public enum CompareType
{
MagnitudeEquals,
MagnitudeNotEquals
}
public CompareType compareType;
public double floatingPointError;
protected override bool Compare(Vector4 a, Vector4 b)
{
switch (compareType)
{
case CompareType.MagnitudeEquals:
return AreVectorMagnitudeEqual(a.magnitude,
b.magnitude,
floatingPointError);
case CompareType.MagnitudeNotEquals:
return !AreVectorMagnitudeEqual(a.magnitude,
b.magnitude,
floatingPointError);
}
throw new Exception();
}
public override int GetDepthOfSearch()
{
return 3;
}
}
}

8
Assets/UnityTestTools/Assertions/Comparers/Vector4Comparer.cs.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 383a85a79f164d04b8a56b0ff4e04cb7
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

18
Assets/UnityTestTools/Assertions/Comparers/VectorComparerBase.cs

@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using UnityEngine;
namespace UnityTest
{
public abstract class VectorComparerBase<T> : ComparerBaseGeneric<T>
{
protected bool AreVectorMagnitudeEqual(float a, float b, double floatingPointError)
{
if (Math.Abs(a) < floatingPointError && Math.Abs(b) < floatingPointError)
return true;
if (Math.Abs(a - b) < floatingPointError)
return true;
return false;
}
}
}

8
Assets/UnityTestTools/Assertions/Comparers/VectorComparerBase.cs.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 7b35a237804d5eb42bd8c4e67568ae24
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

5
Assets/UnityTestTools/Assertions/Editor.meta

@ -0,0 +1,5 @@
fileFormatVersion: 2
guid: a28bb39b4fb20514990895d9cb4eaea9
folderAsset: yes
DefaultImporter:
userData:

212
Assets/UnityTestTools/Assertions/Editor/AssertionComponentEditor.cs

@ -0,0 +1,212 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEditor;
using UnityEngine;
namespace UnityTest
{
[CustomEditor(typeof(AssertionComponent))]
public class AssertionComponentEditor : Editor
{
private readonly DropDownControl<Type> m_ComparerDropDown = new DropDownControl<Type>();
private readonly PropertyPathSelector m_ThisPathSelector = new PropertyPathSelector("Compare");
private readonly PropertyPathSelector m_OtherPathSelector = new PropertyPathSelector("Compare to");
#region GUI Contents
private readonly GUIContent m_GUICheckAfterTimeGuiContent = new GUIContent("Check after (seconds)", "After how many seconds the assertion should be checked");
private readonly GUIContent m_GUIRepeatCheckTimeGuiContent = new GUIContent("Repeat check", "Should the check be repeated.");
private readonly GUIContent m_GUIRepeatEveryTimeGuiContent = new GUIContent("Frequency of repetitions", "How often should the check be done");
private readonly GUIContent m_GUICheckAfterFramesGuiContent = new GUIContent("Check after (frames)", "After how many frames the assertion should be checked");
private readonly GUIContent m_GUIRepeatCheckFrameGuiContent = new GUIContent("Repeat check", "Should the check be repeated.");
#endregion
public AssertionComponentEditor()
{
m_ComparerDropDown.convertForButtonLabel = type => type.Name;
m_ComparerDropDown.convertForGUIContent = type => type.Name;
m_ComparerDropDown.ignoreConvertForGUIContent = types => false;
m_ComparerDropDown.tooltip = "Comparer that will be used to compare values and determine the result of assertion.";
}
public override void OnInspectorGUI()
{
var script = (AssertionComponent)target;
EditorGUILayout.BeginHorizontal();
var obj = DrawComparerSelection(script);
script.checkMethods = (CheckMethod)EditorGUILayout.EnumMaskField(script.checkMethods,
EditorStyles.popup,
GUILayout.ExpandWidth(false));
EditorGUILayout.EndHorizontal();
if (script.IsCheckMethodSelected(CheckMethod.AfterPeriodOfTime))
{
DrawOptionsForAfterPeriodOfTime(script);
}
if (script.IsCheckMethodSelected(CheckMethod.Update))
{
DrawOptionsForOnUpdate(script);
}
if (obj)
{
EditorGUILayout.Space();
m_ThisPathSelector.Draw(script.Action.go, script.Action,
script.Action.thisPropertyPath, script.Action.GetAccepatbleTypesForA(),
go =>
{
script.Action.go = go;
AssertionExplorerWindow.Reload();
},
s =>
{
script.Action.thisPropertyPath = s;
AssertionExplorerWindow.Reload();
});
EditorGUILayout.Space();
DrawCustomFields(script);
EditorGUILayout.Space();
if (script.Action is ComparerBase)
{
DrawCompareToType(script.Action as ComparerBase);
}
}
}
private void DrawOptionsForAfterPeriodOfTime(AssertionComponent script)
{
EditorGUILayout.Space();
script.checkAfterTime = EditorGUILayout.FloatField(m_GUICheckAfterTimeGuiContent,
script.checkAfterTime);
if (script.checkAfterTime < 0)
script.checkAfterTime = 0;
script.repeatCheckTime = EditorGUILayout.Toggle(m_GUIRepeatCheckTimeGuiContent,
script.repeatCheckTime);
if (script.repeatCheckTime)
{
script.repeatEveryTime = EditorGUILayout.FloatField(m_GUIRepeatEveryTimeGuiContent,
script.repeatEveryTime);
if (script.repeatEveryTime < 0)
script.repeatEveryTime = 0;
}
}
private void DrawOptionsForOnUpdate(AssertionComponent script)
{
EditorGUILayout.Space();
script.checkAfterFrames = EditorGUILayout.IntField(m_GUICheckAfterFramesGuiContent,
script.checkAfterFrames);
if (script.checkAfterFrames < 1)
script.checkAfterFrames = 1;
script.repeatCheckFrame = EditorGUILayout.Toggle(m_GUIRepeatCheckFrameGuiContent,
script.repeatCheckFrame);
if (script.repeatCheckFrame)
{
script.repeatEveryFrame = EditorGUILayout.IntField(m_GUIRepeatEveryTimeGuiContent,
script.repeatEveryFrame);
if (script.repeatEveryFrame < 1)
script.repeatEveryFrame = 1;
}
}
private void DrawCompareToType(ComparerBase comparer)
{
comparer.compareToType = (ComparerBase.CompareToType)EditorGUILayout.EnumPopup("Compare to type",
comparer.compareToType,
EditorStyles.popup);
if (comparer.compareToType == ComparerBase.CompareToType.CompareToConstantValue)
{
try
{
DrawConstCompareField(comparer);
}
catch (NotImplementedException)
{
Debug.LogWarning("This comparer can't compare to static value");
comparer.compareToType = ComparerBase.CompareToType.CompareToObject;
}
}
else if (comparer.compareToType == ComparerBase.CompareToType.CompareToObject)
{
DrawObjectCompareField(comparer);
}
}
private void DrawObjectCompareField(ComparerBase comparer)
{
m_OtherPathSelector.Draw(comparer.other, comparer,
comparer.otherPropertyPath, comparer.GetAccepatbleTypesForB(),
go =>
{
comparer.other = go;
AssertionExplorerWindow.Reload();
},
s =>
{
comparer.otherPropertyPath = s;
AssertionExplorerWindow.Reload();
}
);
}
private void DrawConstCompareField(ComparerBase comparer)
{
if (comparer.ConstValue == null)
{
comparer.ConstValue = comparer.GetDefaultConstValue();
}
var so = new SerializedObject(comparer);
var sp = so.FindProperty("constantValueGeneric");
if (sp != null)
{
EditorGUILayout.PropertyField(sp, new GUIContent("Constant"), true);
so.ApplyModifiedProperties();
}
}
private bool DrawComparerSelection(AssertionComponent script)
{
var types = typeof(ActionBase).Assembly.GetTypes();
var allComparers = types.Where(type => type.IsSubclassOf(typeof(ActionBase)) && !type.IsAbstract).ToArray();
if (script.Action == null)
script.Action = (ActionBase)CreateInstance(allComparers.First());
m_ComparerDropDown.Draw(script.Action.GetType(), allComparers,
type =>
{
if (script.Action == null || script.Action.GetType().Name != type.Name)
{
script.Action = (ActionBase)CreateInstance(type);
AssertionExplorerWindow.Reload();
}
});
return script.Action != null;
}
private void DrawCustomFields(AssertionComponent script)
{
foreach (var prop in script.Action.GetType().GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly))
{
var so = new SerializedObject(script.Action);
var sp = so.FindProperty(prop.Name);
if (sp != null)
{
EditorGUILayout.PropertyField(sp, true);
so.ApplyModifiedProperties();
}
}
}
}
}

8
Assets/UnityTestTools/Assertions/Editor/AssertionComponentEditor.cs.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: fd1cabf2c45d0a8489635607a6048621
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

194
Assets/UnityTestTools/Assertions/Editor/AssertionExplorerWindow.cs

@ -0,0 +1,194 @@
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;
#if UNITY_METRO
#warning Assertion component is not supported on Windows Store apps
#endif
namespace UnityTest
{
[Serializable]
public class AssertionExplorerWindow : EditorWindow
{
private List<AssertionComponent> m_AllAssertions = new List<AssertionComponent>();
[SerializeField]
private string m_FilterText = "";
[SerializeField]
private FilterType m_FilterType;
[SerializeField]
private List<string> m_FoldMarkers = new List<string>();
[SerializeField]
private GroupByType m_GroupBy;
[SerializeField]
private Vector2 m_ScrollPosition = Vector2.zero;
private DateTime m_NextReload = DateTime.Now;
[SerializeField]
private static bool s_ShouldReload;
[SerializeField]
private ShowType m_ShowType;
public AssertionExplorerWindow()
{
titleContent = new GUIContent("Assertion Explorer");
}
public void OnDidOpenScene()
{
ReloadAssertionList();
}
public void OnFocus()
{
ReloadAssertionList();
}
private void ReloadAssertionList()
{
m_NextReload = DateTime.Now.AddSeconds(1);
s_ShouldReload = true;
}
public void OnHierarchyChange()
{
ReloadAssertionList();
}
public void OnInspectorUpdate()
{
if (s_ShouldReload && m_NextReload < DateTime.Now)
{
s_ShouldReload = false;
m_AllAssertions = new List<AssertionComponent>((AssertionComponent[])Resources.FindObjectsOfTypeAll(typeof(AssertionComponent)));
Repaint();
}
}
public void OnGUI()
{
DrawMenuPanel();
m_ScrollPosition = EditorGUILayout.BeginScrollView(m_ScrollPosition);
if (m_AllAssertions != null)
GetResultRendere().Render(FilterResults(m_AllAssertions, m_FilterText.ToLower()), m_FoldMarkers);
EditorGUILayout.EndScrollView();
}
private IEnumerable<AssertionComponent> FilterResults(List<AssertionComponent> assertionComponents, string text)
{
if (m_ShowType == ShowType.ShowDisabled)
assertionComponents = assertionComponents.Where(c => !c.enabled).ToList();
else if (m_ShowType == ShowType.ShowEnabled)
assertionComponents = assertionComponents.Where(c => c.enabled).ToList();
if (string.IsNullOrEmpty(text))
return assertionComponents;
switch (m_FilterType)
{
case FilterType.ComparerName:
return assertionComponents.Where(c => c.Action.GetType().Name.ToLower().Contains(text));
case FilterType.AttachedGameObject:
return assertionComponents.Where(c => c.gameObject.name.ToLower().Contains(text));
case FilterType.FirstComparedGameObjectPath:
return assertionComponents.Where(c => c.Action.thisPropertyPath.ToLower().Contains(text));
case FilterType.FirstComparedGameObject:
return assertionComponents.Where(c => c.Action.go != null
&& c.Action.go.name.ToLower().Contains(text));
case FilterType.SecondComparedGameObjectPath:
return assertionComponents.Where(c =>
c.Action is ComparerBase
&& (c.Action as ComparerBase).otherPropertyPath.ToLower().Contains(text));
case FilterType.SecondComparedGameObject:
return assertionComponents.Where(c =>
c.Action is ComparerBase
&& (c.Action as ComparerBase).other != null
&& (c.Action as ComparerBase).other.name.ToLower().Contains(text));
default:
return assertionComponents;
}
}
private readonly IListRenderer m_GroupByComparerRenderer = new GroupByComparerRenderer();
private readonly IListRenderer m_GroupByExecutionMethodRenderer = new GroupByExecutionMethodRenderer();
private readonly IListRenderer m_GroupByGoRenderer = new GroupByGoRenderer();
private readonly IListRenderer m_GroupByTestsRenderer = new GroupByTestsRenderer();
private readonly IListRenderer m_GroupByNothingRenderer = new GroupByNothingRenderer();
private IListRenderer GetResultRendere()
{
switch (m_GroupBy)
{
case GroupByType.Comparer:
return m_GroupByComparerRenderer;
case GroupByType.ExecutionMethod:
return m_GroupByExecutionMethodRenderer;
case GroupByType.GameObjects:
return m_GroupByGoRenderer;
case GroupByType.Tests:
return m_GroupByTestsRenderer;
default:
return m_GroupByNothingRenderer;
}
}
private void DrawMenuPanel()
{
EditorGUILayout.BeginHorizontal(EditorStyles.toolbar);
EditorGUILayout.LabelField("Group by:", Styles.toolbarLabel, GUILayout.MaxWidth(60));
m_GroupBy = (GroupByType)EditorGUILayout.EnumPopup(m_GroupBy, EditorStyles.toolbarPopup, GUILayout.MaxWidth(150));
GUILayout.FlexibleSpace();
m_ShowType = (ShowType)EditorGUILayout.EnumPopup(m_ShowType, EditorStyles.toolbarPopup, GUILayout.MaxWidth(100));
EditorGUILayout.LabelField("Filter by:", Styles.toolbarLabel, GUILayout.MaxWidth(50));
m_FilterType = (FilterType)EditorGUILayout.EnumPopup(m_FilterType, EditorStyles.toolbarPopup, GUILayout.MaxWidth(100));
m_FilterText = GUILayout.TextField(m_FilterText, "ToolbarSeachTextField", GUILayout.MaxWidth(100));
if (GUILayout.Button(GUIContent.none, string.IsNullOrEmpty(m_FilterText) ? "ToolbarSeachCancelButtonEmpty" : "ToolbarSeachCancelButton", GUILayout.ExpandWidth(false)))
m_FilterText = "";
EditorGUILayout.EndHorizontal();
}
[MenuItem("Unity Test Tools/Assertion Explorer")]
public static AssertionExplorerWindow ShowWindow()
{
var w = GetWindow(typeof(AssertionExplorerWindow));
w.Show();
return w as AssertionExplorerWindow;
}
private enum FilterType
{
ComparerName,
FirstComparedGameObject,
FirstComparedGameObjectPath,
SecondComparedGameObject,
SecondComparedGameObjectPath,
AttachedGameObject
}
private enum ShowType
{
ShowAll,
ShowEnabled,
ShowDisabled
}
private enum GroupByType
{
Nothing,
Comparer,
GameObjects,
ExecutionMethod,
Tests
}
public static void Reload()
{
s_ShouldReload = true;
}
}
}

8
Assets/UnityTestTools/Assertions/Editor/AssertionExplorerWindow.cs.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 1a1e855053e7e2f46ace1dc93f2036f2
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

251
Assets/UnityTestTools/Assertions/Editor/AssertionListRenderer.cs

@ -0,0 +1,251 @@
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;
namespace UnityTest
{
public interface IListRenderer
{
void Render(IEnumerable<AssertionComponent> allAssertions, List<string> foldMarkers);
}
public abstract class AssertionListRenderer<T> : IListRenderer
{
private static class Styles
{
public static readonly GUIStyle redLabel;
static Styles()
{
redLabel = new GUIStyle(EditorStyles.label);
redLabel.normal.textColor = Color.red;
}
}
public void Render(IEnumerable<AssertionComponent> allAssertions, List<string> foldMarkers)
{
foreach (var grouping in GroupResult(allAssertions))
{
var key = GetStringKey(grouping.Key);
bool isFolded = foldMarkers.Contains(key);
if (key != "")
{
EditorGUILayout.BeginHorizontal();
EditorGUI.BeginChangeCheck();
isFolded = PrintFoldout(isFolded,
grouping.Key);
if (EditorGUI.EndChangeCheck())
{
if (isFolded)
foldMarkers.Add(key);
else
foldMarkers.Remove(key);
}
EditorGUILayout.EndHorizontal();
if (isFolded)
continue;
}
foreach (var assertionComponent in grouping)
{
EditorGUILayout.BeginVertical();
EditorGUILayout.BeginHorizontal();
if (key != "")
GUILayout.Space(15);
var assertionKey = assertionComponent.GetHashCode().ToString();
bool isDetailsFolded = foldMarkers.Contains(assertionKey);
EditorGUI.BeginChangeCheck();
if (GUILayout.Button("",
EditorStyles.foldout,
GUILayout.Width(15)))
{
isDetailsFolded = !isDetailsFolded;
}
if (EditorGUI.EndChangeCheck())
{
if (isDetailsFolded)
foldMarkers.Add(assertionKey);
else
foldMarkers.Remove(assertionKey);
}
PrintFoldedAssertionLine(assertionComponent);
EditorGUILayout.EndHorizontal();
if (isDetailsFolded)
{
EditorGUILayout.BeginHorizontal();
if (key != "")
GUILayout.Space(15);
PrintAssertionLineDetails(assertionComponent);
EditorGUILayout.EndHorizontal();
}
GUILayout.Box("", new[] {GUILayout.ExpandWidth(true), GUILayout.Height(1)});
EditorGUILayout.EndVertical();
}
}
}
protected abstract IEnumerable<IGrouping<T, AssertionComponent>> GroupResult(IEnumerable<AssertionComponent> assertionComponents);
protected virtual string GetStringKey(T key)
{
return key.GetHashCode().ToString();
}
protected virtual bool PrintFoldout(bool isFolded, T key)
{
var content = new GUIContent(GetFoldoutDisplayName(key));
var size = EditorStyles.foldout.CalcSize(content);
var rect = GUILayoutUtility.GetRect(content,
EditorStyles.foldout,
GUILayout.MaxWidth(size.x));
var res = EditorGUI.Foldout(rect,
!isFolded,
content,
true);
return !res;
}
protected virtual string GetFoldoutDisplayName(T key)
{
return key.ToString();
}
protected virtual void PrintFoldedAssertionLine(AssertionComponent assertionComponent)
{
EditorGUILayout.BeginHorizontal();
EditorGUILayout.BeginVertical(GUILayout.MaxWidth(300));
EditorGUILayout.BeginHorizontal(GUILayout.MaxWidth(300));
PrintPath(assertionComponent.Action.go,
assertionComponent.Action.thisPropertyPath);
EditorGUILayout.EndHorizontal();
EditorGUILayout.EndVertical();
EditorGUILayout.BeginVertical(GUILayout.MaxWidth(250));
var labelStr = assertionComponent.Action.GetType().Name;
var labelStr2 = assertionComponent.Action.GetConfigurationDescription();
if (labelStr2 != "")
labelStr += "( " + labelStr2 + ")";
EditorGUILayout.LabelField(labelStr);
EditorGUILayout.EndVertical();
if (assertionComponent.Action is ComparerBase)
{
var comparer = assertionComponent.Action as ComparerBase;
var otherStrVal = "(no value selected)";
EditorGUILayout.BeginVertical();
EditorGUILayout.BeginHorizontal(GUILayout.MaxWidth(300));
switch (comparer.compareToType)
{
case ComparerBase.CompareToType.CompareToObject:
if (comparer.other != null)
{
PrintPath(comparer.other,
comparer.otherPropertyPath);
}
else
{
EditorGUILayout.LabelField(otherStrVal,
Styles.redLabel);
}
break;
case ComparerBase.CompareToType.CompareToConstantValue:
otherStrVal = comparer.ConstValue.ToString();
EditorGUILayout.LabelField(otherStrVal);
break;
case ComparerBase.CompareToType.CompareToNull:
otherStrVal = "null";
EditorGUILayout.LabelField(otherStrVal);
break;
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.EndVertical();
}
else
{
EditorGUILayout.LabelField("");
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.Space();
}
protected virtual void PrintAssertionLineDetails(AssertionComponent assertionComponent)
{
EditorGUILayout.BeginHorizontal();
EditorGUILayout.BeginVertical(GUILayout.MaxWidth(320));
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField("Attached to",
GUILayout.Width(70));
var sss = EditorStyles.objectField.CalcSize(new GUIContent(assertionComponent.gameObject.name));
EditorGUILayout.ObjectField(assertionComponent.gameObject,
typeof(GameObject),
true,
GUILayout.Width(sss.x));
EditorGUILayout.EndHorizontal();
EditorGUILayout.EndVertical();
EditorGUILayout.BeginVertical(GUILayout.MaxWidth(250));
EditorGUILayout.EnumMaskField(assertionComponent.checkMethods,
EditorStyles.popup,
GUILayout.MaxWidth(150));
EditorGUILayout.EndVertical();
EditorGUILayout.BeginVertical();
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField("Disabled",
GUILayout.Width(55));
assertionComponent.enabled = !EditorGUILayout.Toggle(!assertionComponent.enabled,
GUILayout.Width(15));
EditorGUILayout.EndHorizontal();
EditorGUILayout.EndVertical();
EditorGUILayout.EndHorizontal();
}
private void PrintPath(GameObject go, string propertyPath)
{
string contentString = "";
GUIStyle styleThisPath = EditorStyles.label;
if (go != null)
{
var sss = EditorStyles.objectField.CalcSize(new GUIContent(go.name));
EditorGUILayout.ObjectField(
go,
typeof(GameObject),
true,
GUILayout.Width(sss.x));
if (!string.IsNullOrEmpty(propertyPath))
contentString = "." + propertyPath;
}
else
{
contentString = "(no value selected)";
styleThisPath = Styles.redLabel;
}
var content = new GUIContent(contentString,
contentString);
var rect = GUILayoutUtility.GetRect(content,
EditorStyles.label,
GUILayout.MaxWidth(200));
EditorGUI.LabelField(rect,
content,
styleThisPath);
}
}
}

8
Assets/UnityTestTools/Assertions/Editor/AssertionListRenderer.cs.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: d83c02fb0f220344da42a8213ed36cb5
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

25
Assets/UnityTestTools/Assertions/Editor/AssertionStripper.cs

@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using UnityEditor.Callbacks;
using UnityEngine;
using UnityTest;
using Object = UnityEngine.Object;
public class AssertionStripper
{
[PostProcessScene]
public static void OnPostprocessScene()
{
if (Debug.isDebugBuild) return;
RemoveAssertionsFromGameObjects();
}
private static void RemoveAssertionsFromGameObjects()
{
var allAssertions = Resources.FindObjectsOfTypeAll(typeof(AssertionComponent)) as AssertionComponent[];
foreach (var assertion in allAssertions)
{
Object.DestroyImmediate(assertion);
}
}
}

8
Assets/UnityTestTools/Assertions/Editor/AssertionStripper.cs.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 95c9cd9570a6fba4198b6e4f15e11e5e
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

78
Assets/UnityTestTools/Assertions/Editor/DropDownControl.cs

@ -0,0 +1,78 @@
using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
namespace UnityTest
{
[Serializable]
internal class DropDownControl<T>
{
private readonly GUILayoutOption[] m_ButtonLayoutOptions = { GUILayout.ExpandWidth(true) };
public Func<T, string> convertForButtonLabel = s => s.ToString();
public Func<T, string> convertForGUIContent = s => s.ToString();
public Func<T[], bool> ignoreConvertForGUIContent = t => t.Length <= 40;
public Action<T> printContextMenu = null;
public string tooltip = "";
private object m_SelectedValue;
public void Draw(T selected, T[] options, Action<T> onValueSelected)
{
Draw(null,
selected,
options,
onValueSelected);
}
public void Draw(string label, T selected, T[] options, Action<T> onValueSelected)
{
Draw(label, selected, () => options, onValueSelected);
}
public void Draw(string label, T selected, Func<T[]> loadOptions, Action<T> onValueSelected)
{
if (!string.IsNullOrEmpty(label))
EditorGUILayout.BeginHorizontal();
var guiContent = new GUIContent(label);
var labelSize = EditorStyles.label.CalcSize(guiContent);
if (!string.IsNullOrEmpty(label))
GUILayout.Label(label, EditorStyles.label, GUILayout.Width(labelSize.x));
if (GUILayout.Button(new GUIContent(convertForButtonLabel(selected), tooltip),
EditorStyles.popup, m_ButtonLayoutOptions))
{
if (Event.current.button == 0)
{
PrintMenu(loadOptions());
}
else if (printContextMenu != null && Event.current.button == 1)
printContextMenu(selected);
}
if (m_SelectedValue != null)
{
onValueSelected((T)m_SelectedValue);
m_SelectedValue = null;
}
if (!string.IsNullOrEmpty(label))
EditorGUILayout.EndHorizontal();
}
public void PrintMenu(T[] options)
{
var menu = new GenericMenu();
foreach (var s in options)
{
var localS = s;
menu.AddItem(new GUIContent((ignoreConvertForGUIContent(options) ? localS.ToString() : convertForGUIContent(localS))),
false,
() => { m_SelectedValue = localS; }
);
}
menu.ShowAsContext();
}
}
}

8
Assets/UnityTestTools/Assertions/Editor/DropDownControl.cs.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 83ec3ed09f8f2f34ea7483e055f6d76d
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

20
Assets/UnityTestTools/Assertions/Editor/GroupByComparerRenderer.cs

@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace UnityTest
{
public class GroupByComparerRenderer : AssertionListRenderer<Type>
{
protected override IEnumerable<IGrouping<Type, AssertionComponent>> GroupResult(IEnumerable<AssertionComponent> assertionComponents)
{
return assertionComponents.GroupBy(c => c.Action.GetType());
}
protected override string GetStringKey(Type key)
{
return key.Name;
}
}
}

8
Assets/UnityTestTools/Assertions/Editor/GroupByComparerRenderer.cs.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: efab536803bd0154a8a7dc78e8767ad9
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

31
Assets/UnityTestTools/Assertions/Editor/GroupByExecutionMethodRenderer.cs

@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace UnityTest
{
public class GroupByExecutionMethodRenderer : AssertionListRenderer<CheckMethod>
{
protected override IEnumerable<IGrouping<CheckMethod, AssertionComponent>> GroupResult(IEnumerable<AssertionComponent> assertionComponents)
{
var enumVals = Enum.GetValues(typeof(CheckMethod)).Cast<CheckMethod>();
var pairs = new List<CheckFunctionAssertionPair>();
foreach (var checkMethod in enumVals)
{
var components = assertionComponents.Where(c => (c.checkMethods & checkMethod) == checkMethod);
var componentPairs = components.Select(a => new CheckFunctionAssertionPair {checkMethod = checkMethod, assertionComponent = a});
pairs.AddRange(componentPairs);
}
return pairs.GroupBy(pair => pair.checkMethod,
pair => pair.assertionComponent);
}
private class CheckFunctionAssertionPair
{
public AssertionComponent assertionComponent;
public CheckMethod checkMethod;
}
}
}

8
Assets/UnityTestTools/Assertions/Editor/GroupByExecutionMethodRenderer.cs.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 97340abf816b1424fa835a4f26bbdc78
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

34
Assets/UnityTestTools/Assertions/Editor/GroupByGORenderer.cs

@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;
namespace UnityTest
{
public class GroupByGoRenderer : AssertionListRenderer<GameObject>
{
protected override IEnumerable<IGrouping<GameObject, AssertionComponent>> GroupResult(IEnumerable<AssertionComponent> assertionComponents)
{
return assertionComponents.GroupBy(c => c.gameObject);
}
protected override bool PrintFoldout(bool isFolded, GameObject key)
{
isFolded = base.PrintFoldout(isFolded,
key);
EditorGUILayout.ObjectField(key,
typeof(GameObject),
true,
GUILayout.ExpandWidth(false));
return isFolded;
}
protected override string GetFoldoutDisplayName(GameObject key)
{
return key.name;
}
}
}

8
Assets/UnityTestTools/Assertions/Editor/GroupByGORenderer.cs.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: cb824de9146b42343a985aaf63beffd1
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

20
Assets/UnityTestTools/Assertions/Editor/GroupByNothingRenderer.cs

@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace UnityTest
{
public class GroupByNothingRenderer : AssertionListRenderer<string>
{
protected override IEnumerable<IGrouping<string, AssertionComponent>> GroupResult(IEnumerable<AssertionComponent> assertionComponents)
{
return assertionComponents.GroupBy(c => "");
}
protected override string GetStringKey(string key)
{
return "";
}
}
}

8
Assets/UnityTestTools/Assertions/Editor/GroupByNothingRenderer.cs.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 33bf96aa461ea1d478bb757c52f51c95
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

29
Assets/UnityTestTools/Assertions/Editor/GroupByTestsRenderer.cs

@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace UnityTest
{
public class GroupByTestsRenderer : AssertionListRenderer<GameObject>
{
protected override IEnumerable<IGrouping<GameObject, AssertionComponent>> GroupResult(IEnumerable<AssertionComponent> assertionComponents)
{
return assertionComponents.GroupBy(c =>
{
var temp = c.transform;
while (temp != null)
{
if (temp.GetComponent("TestComponent") != null) return c.gameObject;
temp = temp.parent.transform;
}
return null;
});
}
protected override string GetFoldoutDisplayName(GameObject key)
{
return key.name;
}
}
}

8
Assets/UnityTestTools/Assertions/Editor/GroupByTestsRenderer.cs.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 5e577f31e55208b4d8a1774b958e6ed5
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

207
Assets/UnityTestTools/Assertions/Editor/PropertyPathSelector.cs

@ -0,0 +1,207 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEditor;
using UnityEngine;
namespace UnityTest
{
public class PropertyPathSelector
{
private readonly DropDownControl<string> m_ThisDropDown = new DropDownControl<string>();
private readonly Func<string, string> m_ReplaceDotWithSlashAndAddGoGroup = s => s.Replace('.', '/');
private readonly string m_Name;
private bool m_FocusBackToEdit;
private SelectedPathError m_Error;
public PropertyPathSelector(string name)
{
m_Name = name;
m_ThisDropDown.convertForGUIContent = m_ReplaceDotWithSlashAndAddGoGroup;
m_ThisDropDown.tooltip = "Select the path to the value you want to use for comparison.";
}
public void Draw(GameObject go, ActionBase comparer, string propertPath, Type[] accepatbleTypes, Action<GameObject> onSelectedGo, Action<string> onSelectedPath)
{
var newGo = (GameObject)EditorGUILayout.ObjectField(m_Name, go, typeof(GameObject), true);
if (newGo != go)
onSelectedGo(newGo);
if (go != null)
{
var newPath = DrawListOfMethods(go, comparer, propertPath, accepatbleTypes, m_ThisDropDown);
if (newPath != propertPath)
onSelectedPath(newPath);
}
}
private string DrawListOfMethods(GameObject go, ActionBase comparer, string propertPath, Type[] accepatbleTypes, DropDownControl<string> dropDown)
{
string result = propertPath;
if (accepatbleTypes == null)
{
result = DrawManualPropertyEditField(go, propertPath, accepatbleTypes, dropDown);
}
else
{
bool isPropertyOrFieldFound = true;
if (string.IsNullOrEmpty(result))
{
var options = GetFieldsAndProperties(go, comparer, result, accepatbleTypes);
isPropertyOrFieldFound = options.Any();
if (isPropertyOrFieldFound)
{
result = options.First();
}
}
if (isPropertyOrFieldFound)
{
dropDown.Draw(go.name + '.', result,
() =>
{
try
{
var options = GetFieldsAndProperties(go, comparer, result, accepatbleTypes);
return options.ToArray();
}
catch (Exception)
{
Debug.LogWarning("An exception was thrown while resolving a property list. Resetting property path.");
result = "";
return new string[0];
}
}, s => result = s);
}
else
{
result = DrawManualPropertyEditField(go, propertPath, accepatbleTypes, dropDown);
}
}
return result;
}
private static List<string> GetFieldsAndProperties(GameObject go, ActionBase comparer, string extendPath, Type[] accepatbleTypes)
{
var propertyResolver = new PropertyResolver {AllowedTypes = accepatbleTypes, ExcludedFieldNames = comparer.GetExcludedFieldNames()};
var options = propertyResolver.GetFieldsAndPropertiesFromGameObject(go, comparer.GetDepthOfSearch(), extendPath).ToList();
options.Sort((x, y) =>
{
if (char.IsLower(x[0]))
return -1;
if (char.IsLower(y[0]))
return 1;
return x.CompareTo(y);
});
return options;
}
private string DrawManualPropertyEditField(GameObject go, string propertPath, Type[] acceptableTypes, DropDownControl<string> dropDown)
{
var propertyResolver = new PropertyResolver { AllowedTypes = acceptableTypes };
IList<string> list;
var loadProps = new Func<string[]>(() =>
{
try
{
list = propertyResolver.GetFieldsAndPropertiesUnderPath(go, propertPath);
}
catch (ArgumentException)
{
list = propertyResolver.GetFieldsAndPropertiesUnderPath(go, "");
}
return list.ToArray();
});
EditorGUILayout.BeginHorizontal();
var labelSize = EditorStyles.label.CalcSize(new GUIContent(go.name + '.'));
GUILayout.Label(go.name + (propertPath.Length > 0 ? "." : ""), EditorStyles.label, GUILayout.Width(labelSize.x));
string btnName = "hintBtn";
if (GUI.GetNameOfFocusedControl() == btnName
&& Event.current.type == EventType.KeyDown
&& Event.current.keyCode == KeyCode.DownArrow)
{
Event.current.Use();
dropDown.PrintMenu(loadProps());
GUI.FocusControl("");
m_FocusBackToEdit = true;
}
EditorGUI.BeginChangeCheck();
GUI.SetNextControlName(btnName);
var result = GUILayout.TextField(propertPath, EditorStyles.textField);
if (EditorGUI.EndChangeCheck())
{
m_Error = DoesPropertyExist(go, result);
}
if (m_FocusBackToEdit)
{
m_FocusBackToEdit = false;
GUI.FocusControl(btnName);
}
if (GUILayout.Button("Clear", EditorStyles.miniButton, GUILayout.Width(38)))
{
result = "";
GUI.FocusControl(null);
m_FocusBackToEdit = true;
m_Error = DoesPropertyExist(go, result);
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
GUILayout.Label("", GUILayout.Width(labelSize.x));
dropDown.Draw("", result ?? "", loadProps, s =>
{
result = s;
GUI.FocusControl(null);
m_FocusBackToEdit = true;
m_Error = DoesPropertyExist(go, result);
});
EditorGUILayout.EndHorizontal();
switch (m_Error)
{
case SelectedPathError.InvalidPath:
EditorGUILayout.HelpBox("This property does not exist", MessageType.Error);
break;
case SelectedPathError.MissingComponent:
EditorGUILayout.HelpBox("This property or field is not attached or set. It will fail unless it will be attached before the check is perfomed.", MessageType.Warning);
break;
}
return result;
}
private SelectedPathError DoesPropertyExist(GameObject go, string propertPath)
{
try
{
object obj;
if (MemberResolver.TryGetValue(go, propertPath, out obj))
return SelectedPathError.None;
return SelectedPathError.InvalidPath;
}
catch (TargetInvocationException e)
{
if (e.InnerException is MissingComponentException)
return SelectedPathError.MissingComponent;
throw;
}
}
private enum SelectedPathError
{
None,
MissingComponent,
InvalidPath
}
}
}

8
Assets/UnityTestTools/Assertions/Editor/PropertyPathSelector.cs.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 6619da1897737044080bdb8bc60eff87
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

188
Assets/UnityTestTools/Assertions/Editor/PropertyResolver.cs

@ -0,0 +1,188 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
using UnityEngine;
namespace UnityTest
{
[Serializable]
public class PropertyResolver
{
public string[] ExcludedFieldNames { get; set; }
public Type[] ExcludedTypes { get; set; }
public Type[] AllowedTypes { get; set; }
public PropertyResolver()
{
ExcludedFieldNames = new string[] { };
ExcludedTypes = new Type[] { };
AllowedTypes = new Type[] { };
}
public IList<string> GetFieldsAndPropertiesUnderPath(GameObject go, string propertPath)
{
propertPath = propertPath.Trim();
if (!PropertyPathIsValid(propertPath))
{
throw new ArgumentException("Incorrect property path: " + propertPath);
}
var idx = propertPath.LastIndexOf('.');
if (idx < 0)
{
var components = GetFieldsAndPropertiesFromGameObject(go, 2, null);
return components;
}
var propertyToSearch = propertPath;
Type type;
if (MemberResolver.TryGetMemberType(go, propertyToSearch, out type))
{
idx = propertPath.Length - 1;
}
else
{
propertyToSearch = propertPath.Substring(0, idx);
if (!MemberResolver.TryGetMemberType(go, propertyToSearch, out type))
{
var components = GetFieldsAndPropertiesFromGameObject(go, 2, null);
return components.Where(s => s.StartsWith(propertPath.Substring(idx + 1))).ToArray();
}
}
var resultList = new List<string>();
var path = "";
if (propertyToSearch.EndsWith("."))
propertyToSearch = propertyToSearch.Substring(0, propertyToSearch.Length - 1);
foreach (var c in propertyToSearch)
{
if (c == '.')
resultList.Add(path);
path += c;
}
resultList.Add(path);
foreach (var prop in type.GetProperties().Where(info => info.GetIndexParameters().Length == 0))
{
if (prop.Name.StartsWith(propertPath.Substring(idx + 1)))
resultList.Add(propertyToSearch + "." + prop.Name);
}
foreach (var prop in type.GetFields())
{
if (prop.Name.StartsWith(propertPath.Substring(idx + 1)))
resultList.Add(propertyToSearch + "." + prop.Name);
}
return resultList.ToArray();
}
internal bool PropertyPathIsValid(string propertPath)
{
if (propertPath.StartsWith("."))
return false;
if (propertPath.IndexOf("..") >= 0)
return false;
if (Regex.IsMatch(propertPath, @"\s"))
return false;
return true;
}
public IList<string> GetFieldsAndPropertiesFromGameObject(GameObject gameObject, int depthOfSearch, string extendPath)
{
if (depthOfSearch < 1) throw new ArgumentOutOfRangeException("depthOfSearch has to be greater than 0");
var goVals = GetPropertiesAndFieldsFromType(typeof(GameObject),
depthOfSearch - 1).Select(s => "gameObject." + s);
var result = new List<string>();
if (AllowedTypes == null || !AllowedTypes.Any() || AllowedTypes.Contains(typeof(GameObject)))
result.Add("gameObject");
result.AddRange(goVals);
foreach (var componentType in GetAllComponents(gameObject))
{
if (AllowedTypes == null || !AllowedTypes.Any() || AllowedTypes.Any(t => t.IsAssignableFrom(componentType)))
result.Add(componentType.Name);
if (depthOfSearch > 1)
{
var vals = GetPropertiesAndFieldsFromType(componentType, depthOfSearch - 1);
var valsFullName = vals.Select(s => componentType.Name + "." + s);
result.AddRange(valsFullName);
}
}
if (!string.IsNullOrEmpty(extendPath))
{
var memberResolver = new MemberResolver(gameObject, extendPath);
var pathType = memberResolver.GetMemberType();
var vals = GetPropertiesAndFieldsFromType(pathType, depthOfSearch - 1);
var valsFullName = vals.Select(s => extendPath + "." + s);
result.AddRange(valsFullName);
}
return result;
}
private string[] GetPropertiesAndFieldsFromType(Type type, int level)
{
level--;
var result = new List<string>();
var fields = new List<MemberInfo>();
fields.AddRange(type.GetFields().Where(f => !Attribute.IsDefined(f, typeof(ObsoleteAttribute))).ToArray());
fields.AddRange(type.GetProperties().Where(info => info.GetIndexParameters().Length == 0 && !Attribute.IsDefined(info, typeof(ObsoleteAttribute))).ToArray());
foreach (var member in fields)
{
var memberType = GetMemberFieldType(member);
var memberTypeName = memberType.Name;
if (AllowedTypes == null
|| !AllowedTypes.Any()
|| (AllowedTypes.Any(t => t.IsAssignableFrom(memberType)) && !ExcludedFieldNames.Contains(memberTypeName)))
{
result.Add(member.Name);
}
if (level > 0 && IsTypeOrNameNotExcluded(memberType, memberTypeName))
{
var vals = GetPropertiesAndFieldsFromType(memberType, level);
var valsFullName = vals.Select(s => member.Name + "." + s);
result.AddRange(valsFullName);
}
}
return result.ToArray();
}
private Type GetMemberFieldType(MemberInfo info)
{
if (info.MemberType == MemberTypes.Property)
return (info as PropertyInfo).PropertyType;
if (info.MemberType == MemberTypes.Field)
return (info as FieldInfo).FieldType;
throw new Exception("Only properties and fields are allowed");
}
internal Type[] GetAllComponents(GameObject gameObject)
{
var result = new List<Type>();
var components = gameObject.GetComponents(typeof(Component));
foreach (var component in components)
{
var componentType = component.GetType();
if (IsTypeOrNameNotExcluded(componentType, null))
{
result.Add(componentType);
}
}
return result.ToArray();
}
private bool IsTypeOrNameNotExcluded(Type memberType, string memberTypeName)
{
return !ExcludedTypes.Contains(memberType) && !ExcludedFieldNames.Contains(memberTypeName);
}
}
}

8
Assets/UnityTestTools/Assertions/Editor/PropertyResolver.cs.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: bbbd193a27920d9478c2a766a7291d72
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

14
Assets/UnityTestTools/Assertions/InvalidPathException.cs

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using UnityEngine;
namespace UnityTest
{
public class InvalidPathException : Exception
{
public InvalidPathException(string path)
: base("Invalid path part " + path)
{
}
}
}

8
Assets/UnityTestTools/Assertions/InvalidPathException.cs.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 3b85786dfd1aef544bf8bb873d6a4ebb
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

208
Assets/UnityTestTools/Assertions/MemberResolver.cs

@ -0,0 +1,208 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text.RegularExpressions;
using UnityEngine;
namespace UnityTest
{
public class MemberResolver
{
private object m_CallingObjectRef;
private MemberInfo[] m_Callstack;
private readonly GameObject m_GameObject;
private readonly string m_Path;
public MemberResolver(GameObject gameObject, string path)
{
path = path.Trim();
ValidatePath(path);
m_GameObject = gameObject;
m_Path = path.Trim();
}
public object GetValue(bool useCache)
{
if (useCache && m_CallingObjectRef != null)
{
object val = m_CallingObjectRef;
for (int i = 0; i < m_Callstack.Length; i++)
val = GetValueFromMember(val, m_Callstack[i]);
return val;
}
object result = GetBaseObject();
var fullCallStack = GetCallstack();
m_CallingObjectRef = result;
var tempCallstack = new List<MemberInfo>();
for (int i = 0; i < fullCallStack.Length; i++)
{
var member = fullCallStack[i];
result = GetValueFromMember(result, member);
tempCallstack.Add(member);
if (result == null) return null;
var type = result.GetType();
//String is not a value type but we don't want to cache it
if (!IsValueType(type) && type != typeof(System.String))
{
tempCallstack.Clear();
m_CallingObjectRef = result;
}
}
m_Callstack = tempCallstack.ToArray();
return result;
}
public Type GetMemberType()
{
var callstack = GetCallstack();
if (callstack.Length == 0) return GetBaseObject().GetType();
var member = callstack[callstack.Length - 1];
if (member is FieldInfo)
return (member as FieldInfo).FieldType;
if (member is MethodInfo)
return (member as MethodInfo).ReturnType;
return null;
}
#region Static wrappers
public static bool TryGetMemberType(GameObject gameObject, string path, out Type value)
{
try
{
var mr = new MemberResolver(gameObject, path);
value = mr.GetMemberType();
return true;
}
catch (InvalidPathException)
{
value = null;
return false;
}
}
public static bool TryGetValue(GameObject gameObject, string path, out object value)
{
try
{
var mr = new MemberResolver(gameObject, path);
value = mr.GetValue(false);
return true;
}
catch (InvalidPathException)
{
value = null;
return false;
}
}
#endregion
private object GetValueFromMember(object obj, MemberInfo memberInfo)
{
if (memberInfo is FieldInfo)
return (memberInfo as FieldInfo).GetValue(obj);
if (memberInfo is MethodInfo)
return (memberInfo as MethodInfo).Invoke(obj, null);
throw new InvalidPathException(memberInfo.Name);
}
private object GetBaseObject()
{
if (string.IsNullOrEmpty(m_Path)) return m_GameObject;
var firstElement = m_Path.Split('.')[0];
var comp = m_GameObject.GetComponent(firstElement);
if (comp != null)
return comp;
return m_GameObject;
}
private MemberInfo[] GetCallstack()
{
if (m_Path == "") return new MemberInfo[0];
var propsQueue = new Queue<string>(m_Path.Split('.'));
Type type = GetBaseObject().GetType();
if (type != typeof(GameObject))
propsQueue.Dequeue();
PropertyInfo propertyTemp;
FieldInfo fieldTemp;
var list = new List<MemberInfo>();
while (propsQueue.Count != 0)
{
var nameToFind = propsQueue.Dequeue();
fieldTemp = GetField(type, nameToFind);
if (fieldTemp != null)
{
type = fieldTemp.FieldType;
list.Add(fieldTemp);
continue;
}
propertyTemp = GetProperty(type, nameToFind);
if (propertyTemp != null)
{
type = propertyTemp.PropertyType;
var getMethod = GetGetMethod(propertyTemp);
list.Add(getMethod);
continue;
}
throw new InvalidPathException(nameToFind);
}
return list.ToArray();
}
private void ValidatePath(string path)
{
bool invalid = false;
if (path.StartsWith(".") || path.EndsWith("."))
invalid = true;
if (path.IndexOf("..") >= 0)
invalid = true;
if (Regex.IsMatch(path, @"\s"))
invalid = true;
if (invalid)
throw new InvalidPathException(path);
}
private static bool IsValueType(Type type)
{
#if !UNITY_METRO
return type.IsValueType;
#else
return false;
#endif
}
private static FieldInfo GetField(Type type, string fieldName)
{
#if !UNITY_METRO
return type.GetField(fieldName);
#else
return null;
#endif
}
private static PropertyInfo GetProperty(Type type, string propertyName)
{
#if !UNITY_METRO
return type.GetProperty(propertyName);
#else
return null;
#endif
}
private static MethodInfo GetGetMethod(PropertyInfo propertyInfo)
{
#if !UNITY_METRO
return propertyInfo.GetGetMethod();
#else
return null;
#endif
}
}
}

8
Assets/UnityTestTools/Assertions/MemberResolver.cs.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 80df8ef907961e34dbcc7c89b22729b9
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

5
Assets/UnityTestTools/Common.meta

@ -0,0 +1,5 @@
fileFormatVersion: 2
guid: a2caba6436df568499c84c1c607ce766
folderAsset: yes
DefaultImporter:
userData:

4
Assets/UnityTestTools/Common/Editor.meta

@ -0,0 +1,4 @@
fileFormatVersion: 2
guid: f4ab061d0035ee545a936bdf8f3f8620
DefaultImporter:
userData:

57
Assets/UnityTestTools/Common/Editor/Icons.cs

@ -0,0 +1,57 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEditor;
using UnityEngine;
namespace UnityTest
{
public static class Icons
{
const string k_IconsFolderName = "icons";
private static readonly string k_IconsFolderPath = String.Format("UnityTestTools{0}Common{0}Editor{0}{1}", Path.DirectorySeparatorChar, k_IconsFolderName);
private static readonly string k_IconsAssetsPath = "";
public static readonly Texture2D FailImg;
public static readonly Texture2D IgnoreImg;
public static readonly Texture2D SuccessImg;
public static readonly Texture2D UnknownImg;
public static readonly Texture2D InconclusiveImg;
public static readonly Texture2D StopwatchImg;
public static readonly GUIContent GUIUnknownImg;
public static readonly GUIContent GUIInconclusiveImg;
public static readonly GUIContent GUIIgnoreImg;
public static readonly GUIContent GUISuccessImg;
public static readonly GUIContent GUIFailImg;
static Icons()
{
var dirs = Directory.GetDirectories("Assets", k_IconsFolderName, SearchOption.AllDirectories).Where(s => s.EndsWith(k_IconsFolderPath));
if (dirs.Any())
k_IconsAssetsPath = dirs.First();
else
Debug.LogWarning("The UnityTestTools asset folder path is incorrect. If you relocated the tools please change the path accordingly (Icons.cs).");
FailImg = LoadTexture("failed.png");
IgnoreImg = LoadTexture("ignored.png");
SuccessImg = LoadTexture("passed.png");
UnknownImg = LoadTexture("normal.png");
InconclusiveImg = LoadTexture("inconclusive.png");
StopwatchImg = LoadTexture("stopwatch.png");
GUIUnknownImg = new GUIContent(UnknownImg);
GUIInconclusiveImg = new GUIContent(InconclusiveImg);
GUIIgnoreImg = new GUIContent(IgnoreImg);
GUISuccessImg = new GUIContent(SuccessImg);
GUIFailImg = new GUIContent(FailImg);
}
private static Texture2D LoadTexture(string fileName)
{
return (Texture2D)AssetDatabase.LoadAssetAtPath(k_IconsAssetsPath + Path.DirectorySeparatorChar + fileName, typeof(Texture2D));
}
}
}

8
Assets/UnityTestTools/Common/Editor/Icons.cs.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 8571844b0c115b84cbe8b3f67e8dec04
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

39
Assets/UnityTestTools/Common/Editor/ProjectSettingsBase.cs

@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEditor;
using UnityEngine;
namespace UnityTest
{
public abstract class ProjectSettingsBase : ScriptableObject
{
private static readonly string k_SettingsPath = Path.Combine("UnityTestTools", "Common");
const string k_SettingsFolder = "Settings";
public virtual void Save()
{
EditorUtility.SetDirty(this);
}
public static T Load<T>() where T : ProjectSettingsBase, new ()
{
var pathsInProject = Directory.GetDirectories("Assets", "*", SearchOption.AllDirectories)
.Where(s => s.Contains(k_SettingsPath));
if (pathsInProject.Count() == 0) Debug.LogError("Can't find settings path: " + k_SettingsPath);
string pathInProject = Path.Combine(pathsInProject.First(), k_SettingsFolder);
var assetPath = Path.Combine(pathInProject, typeof(T).Name) + ".asset";
var settings = AssetDatabase.LoadAssetAtPath(assetPath, typeof(T)) as T;
if (settings != null) return settings;
settings = CreateInstance<T>();
Directory.CreateDirectory(pathInProject);
AssetDatabase.CreateAsset(settings, assetPath);
return settings;
}
}
}

8
Assets/UnityTestTools/Common/Editor/ProjectSettingsBase.cs.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 9ac961be07107124a88dcb81927143d4
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

5
Assets/UnityTestTools/Common/Editor/ResultWriter.meta

@ -0,0 +1,5 @@
fileFormatVersion: 2
guid: 4ffbf5a07740aa5479651bd415f52ebb
folderAsset: yes
DefaultImporter:
userData:

173
Assets/UnityTestTools/Common/Editor/ResultWriter/ResultSummarizer.cs

@ -0,0 +1,173 @@
// ****************************************************************
// Based on nUnit 2.6.2 (http://www.nunit.org/)
// ****************************************************************
using System;
using System.Collections.Generic;
using UnityEngine;
namespace UnityTest
{
/// <summary>
/// Summary description for ResultSummarizer.
/// </summary>
public class ResultSummarizer
{
private int m_ErrorCount;
private int m_FailureCount;
private int m_IgnoreCount;
private int m_InconclusiveCount;
private int m_NotRunnable;
private int m_ResultCount;
private int m_SkipCount;
private int m_SuccessCount;
private int m_TestsRun;
private TimeSpan m_Duration;
public ResultSummarizer(IEnumerable<ITestResult> results)
{
foreach (var result in results)
Summarize(result);
}
public bool Success
{
get { return m_FailureCount == 0; }
}
/// <summary>
/// Returns the number of test cases for which results
/// have been summarized. Any tests excluded by use of
/// Category or Explicit attributes are not counted.
/// </summary>
public int ResultCount
{
get { return m_ResultCount; }
}
/// <summary>
/// Returns the number of test cases actually run, which
/// is the same as ResultCount, less any Skipped, Ignored
/// or NonRunnable tests.
/// </summary>
public int TestsRun
{
get { return m_TestsRun; }
}
/// <summary>
/// Returns the number of tests that passed
/// </summary>
public int Passed
{
get { return m_SuccessCount; }
}
/// <summary>
/// Returns the number of test cases that had an error.
/// </summary>
public int Errors
{
get { return m_ErrorCount; }
}
/// <summary>
/// Returns the number of test cases that failed.
/// </summary>
public int Failures
{
get { return m_FailureCount; }
}
/// <summary>
/// Returns the number of test cases that failed.
/// </summary>
public int Inconclusive
{
get { return m_InconclusiveCount; }
}
/// <summary>
/// Returns the number of test cases that were not runnable
/// due to errors in the signature of the class or method.
/// Such tests are also counted as Errors.
/// </summary>
public int NotRunnable
{
get { return m_NotRunnable; }
}
/// <summary>
/// Returns the number of test cases that were skipped.
/// </summary>
public int Skipped
{
get { return m_SkipCount; }
}
public int Ignored
{
get { return m_IgnoreCount; }
}
public double Duration
{
get { return m_Duration.TotalSeconds; }
}
public int TestsNotRun
{
get { return m_SkipCount + m_IgnoreCount + m_NotRunnable; }
}
public void Summarize(ITestResult result)
{
m_Duration += TimeSpan.FromSeconds(result.Duration);
m_ResultCount++;
if(!result.Executed)
{
if(result.IsIgnored)
{
m_IgnoreCount++;
return;
}
m_SkipCount++;
return;
}
switch (result.ResultState)
{
case TestResultState.Success:
m_SuccessCount++;
m_TestsRun++;
break;
case TestResultState.Failure:
m_FailureCount++;
m_TestsRun++;
break;
case TestResultState.Error:
case TestResultState.Cancelled:
m_ErrorCount++;
m_TestsRun++;
break;
case TestResultState.Inconclusive:
m_InconclusiveCount++;
m_TestsRun++;
break;
case TestResultState.NotRunnable:
m_NotRunnable++;
// errorCount++;
break;
case TestResultState.Ignored:
m_IgnoreCount++;
break;
default:
m_SkipCount++;
break;
}
}
}
}

8
Assets/UnityTestTools/Common/Editor/ResultWriter/ResultSummarizer.cs.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: ce89106be5bd4204388d58510e4e55da
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

62
Assets/UnityTestTools/Common/Editor/ResultWriter/StackTraceFilter.cs

@ -0,0 +1,62 @@
// ****************************************************************
// Based on nUnit 2.6.2 (http://www.nunit.org/)
// ****************************************************************
using System;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
namespace UnityTest
{
/// <summary>
/// Summary description for StackTraceFilter.
/// </summary>
public class StackTraceFilter
{
public static string Filter(string stack)
{
if (stack == null) return null;
var sw = new StringWriter();
var sr = new StringReader(stack);
try
{
string line;
while ((line = sr.ReadLine()) != null)
{
if (!FilterLine(line))
sw.WriteLine(line.Trim());
}
}
catch (Exception)
{
return stack;
}
return sw.ToString();
}
static bool FilterLine(string line)
{
string[] patterns =
{
"NUnit.Core.TestCase",
"NUnit.Core.ExpectedExceptionTestCase",
"NUnit.Core.TemplateTestCase",
"NUnit.Core.TestResult",
"NUnit.Core.TestSuite",
"NUnit.Framework.Assertion",
"NUnit.Framework.Assert",
"System.Reflection.MonoMethod"
};
for (int i = 0; i < patterns.Length; i++)
{
if (line.IndexOf(patterns[i]) > 0)
return true;
}
return false;
}
}
}

8
Assets/UnityTestTools/Common/Editor/ResultWriter/StackTraceFilter.cs.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: fe6b4d68575d4ba44b1d5c5c3f0e96d3
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

303
Assets/UnityTestTools/Common/Editor/ResultWriter/XmlResultWriter.cs

@ -0,0 +1,303 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Security;
using System.Text;
using UnityEngine;
namespace UnityTest
{
public class XmlResultWriter
{
private readonly StringBuilder m_ResultWriter = new StringBuilder();
private int m_Indend;
private readonly string m_SuiteName;
private readonly ITestResult[] m_Results;
string m_Platform;
public XmlResultWriter(string suiteName, string platform, ITestResult[] results)
{
m_SuiteName = suiteName;
m_Results = results;
m_Platform = platform;
}
private const string k_NUnitVersion = "2.6.2-Unity";
public string GetTestResult()
{
InitializeXmlFile(m_SuiteName, new ResultSummarizer(m_Results));
foreach (var result in m_Results)
{
WriteResultElement(result);
}
TerminateXmlFile();
return m_ResultWriter.ToString();
}
private void InitializeXmlFile(string resultsName, ResultSummarizer summaryResults)
{
WriteHeader();
DateTime now = DateTime.Now;
var attributes = new Dictionary<string, string>
{
{"name", "Unity Tests"},
{"total", summaryResults.TestsRun.ToString()},
{"errors", summaryResults.Errors.ToString()},
{"failures", summaryResults.Failures.ToString()},
{"not-run", summaryResults.TestsNotRun.ToString()},
{"inconclusive", summaryResults.Inconclusive.ToString()},
{"ignored", summaryResults.Ignored.ToString()},
{"skipped", summaryResults.Skipped.ToString()},
{"invalid", summaryResults.NotRunnable.ToString()},
{"date", now.ToString("yyyy-MM-dd")},
{"time", now.ToString("HH:mm:ss")}
};
WriteOpeningElement("test-results", attributes);
WriteEnvironment(m_Platform);
WriteCultureInfo();
WriteTestSuite(resultsName, summaryResults);
WriteOpeningElement("results");
}
private void WriteOpeningElement(string elementName)
{
WriteOpeningElement(elementName, new Dictionary<string, string>());
}
private void WriteOpeningElement(string elementName, Dictionary<string, string> attributes)
{
WriteOpeningElement(elementName, attributes, false);
}
private void WriteOpeningElement(string elementName, Dictionary<string, string> attributes, bool closeImmediatelly)
{
WriteIndend();
m_Indend++;
m_ResultWriter.Append("<");
m_ResultWriter.Append(elementName);
foreach (var attribute in attributes)
{
m_ResultWriter.AppendFormat(" {0}=\"{1}\"", attribute.Key, SecurityElement.Escape(attribute.Value));
}
if (closeImmediatelly)
{
m_ResultWriter.Append(" /");
m_Indend--;
}
m_ResultWriter.AppendLine(">");
}
private void WriteIndend()
{
for (int i = 0; i < m_Indend; i++)
{
m_ResultWriter.Append(" ");
}
}
private void WriteClosingElement(string elementName)
{
m_Indend--;
WriteIndend();
m_ResultWriter.AppendLine("</" + elementName + ">");
}
private void WriteHeader()
{
m_ResultWriter.AppendLine("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
m_ResultWriter.AppendLine("<!--This file represents the results of running a test suite-->");
}
static string GetEnvironmentUserName()
{
return Environment.UserName;
}
static string GetEnvironmentMachineName()
{
return Environment.MachineName;
}
static string GetEnvironmentUserDomainName()
{
return Environment.UserDomainName;
}
static string GetEnvironmentVersion()
{
return Environment.Version.ToString();
}
static string GetEnvironmentOSVersion()
{
return Environment.OSVersion.ToString();
}
static string GetEnvironmentOSVersionPlatform()
{
return Environment.OSVersion.Platform.ToString();
}
static string EnvironmentGetCurrentDirectory()
{
return Environment.CurrentDirectory;
}
private void WriteEnvironment( string targetPlatform )
{
var attributes = new Dictionary<string, string>
{
{"nunit-version", k_NUnitVersion},
{"clr-version", GetEnvironmentVersion()},
{"os-version", GetEnvironmentOSVersion()},
{"platform", GetEnvironmentOSVersionPlatform()},
{"cwd", EnvironmentGetCurrentDirectory()},
{"machine-name", GetEnvironmentMachineName()},
{"user", GetEnvironmentUserName()},
{"user-domain", GetEnvironmentUserDomainName()},
{"unity-version", Application.unityVersion},
{"unity-platform", targetPlatform}
};
WriteOpeningElement("environment", attributes, true);
}
private void WriteCultureInfo()
{
var attributes = new Dictionary<string, string>
{
{"current-culture", CultureInfo.CurrentCulture.ToString()},
{"current-uiculture", CultureInfo.CurrentUICulture.ToString()}
};
WriteOpeningElement("culture-info", attributes, true);
}
private void WriteTestSuite(string resultsName, ResultSummarizer summaryResults)
{
var attributes = new Dictionary<string, string>
{
{"name", resultsName},
{"type", "Assembly"},
{"executed", "True"},
{"result", summaryResults.Success ? "Success" : "Failure"},
{"success", summaryResults.Success ? "True" : "False"},
{"time", summaryResults.Duration.ToString("#####0.000", NumberFormatInfo.InvariantInfo)}
};
WriteOpeningElement("test-suite", attributes);
}
private void WriteResultElement(ITestResult result)
{
StartTestElement(result);
switch (result.ResultState)
{
case TestResultState.Ignored:
case TestResultState.NotRunnable:
case TestResultState.Skipped:
WriteReasonElement(result);
break;
case TestResultState.Failure:
case TestResultState.Error:
case TestResultState.Cancelled:
WriteFailureElement(result);
break;
case TestResultState.Success:
case TestResultState.Inconclusive:
if (result.Message != null)
WriteReasonElement(result);
break;
};
WriteClosingElement("test-case");
}
private void TerminateXmlFile()
{
WriteClosingElement("results");
WriteClosingElement("test-suite");
WriteClosingElement("test-results");
}
#region Element Creation Helpers
private void StartTestElement(ITestResult result)
{
var attributes = new Dictionary<string, string>
{
{"name", result.FullName},
{"executed", result.Executed.ToString()}
};
string resultString;
switch (result.ResultState)
{
case TestResultState.Cancelled:
resultString = TestResultState.Failure.ToString();
break;
default:
resultString = result.ResultState.ToString();
break;
}
attributes.Add("result", resultString);
if (result.Executed)
{
attributes.Add("success", result.IsSuccess.ToString());
attributes.Add("time", result.Duration.ToString("#####0.000", NumberFormatInfo.InvariantInfo));
}
WriteOpeningElement("test-case", attributes);
}
private void WriteReasonElement(ITestResult result)
{
WriteOpeningElement("reason");
WriteOpeningElement("message");
WriteCData(result.Message);
WriteClosingElement("message");
WriteClosingElement("reason");
}
private void WriteFailureElement(ITestResult result)
{
WriteOpeningElement("failure");
WriteOpeningElement("message");
WriteCData(result.Message);
WriteClosingElement("message");
WriteOpeningElement("stack-trace");
if (result.StackTrace != null)
WriteCData(StackTraceFilter.Filter(result.StackTrace));
WriteClosingElement("stack-trace");
WriteClosingElement("failure");
}
#endregion
private void WriteCData(string text)
{
if (string.IsNullOrEmpty(text))
return;
m_ResultWriter.AppendFormat("<![CDATA[{0}]]>", text);
m_ResultWriter.AppendLine();
}
public void WriteToFile(string resultDestiantion, string resultFileName)
{
try
{
var path = Path.Combine(resultDestiantion, resultFileName);
Debug.Log("Saving results in " + path);
File.WriteAllText(path, GetTestResult(), Encoding.UTF8);
}
catch (Exception e)
{
Debug.LogError("Error while opening file");
Debug.LogException(e);
}
}
}
}

8
Assets/UnityTestTools/Common/Editor/ResultWriter/XmlResultWriter.cs.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: e9bba41ace7686d4ab0c400d1e7f55b7
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

47
Assets/UnityTestTools/Common/Editor/Styles.cs

@ -0,0 +1,47 @@
using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
namespace UnityTest
{
public static class Styles
{
public static GUIStyle info;
public static GUIStyle testList;
public static GUIStyle selectedFoldout;
public static GUIStyle foldout;
public static GUIStyle toolbarLabel;
public static GUIStyle testName;
private static readonly Color k_SelectedColor = new Color(0.3f, 0.5f, 0.85f);
static Styles()
{
info = new GUIStyle(EditorStyles.wordWrappedLabel);
info.wordWrap = false;
info.stretchHeight = true;
info.margin.right = 15;
testList = new GUIStyle("CN Box");
testList.margin.top = 0;
testList.padding.left = 3;
foldout = new GUIStyle(EditorStyles.foldout);
selectedFoldout = new GUIStyle(EditorStyles.foldout);
selectedFoldout.onFocused.textColor = selectedFoldout.focused.textColor =
selectedFoldout.onActive.textColor = selectedFoldout.active.textColor =
selectedFoldout.onNormal.textColor = selectedFoldout.normal.textColor = k_SelectedColor;
toolbarLabel = new GUIStyle(EditorStyles.toolbarButton);
toolbarLabel.normal.background = null;
toolbarLabel.contentOffset = new Vector2(0, -2);
testName = new GUIStyle(EditorStyles.label);
testName.padding.left += 12;
testName.focused.textColor = testName.onFocused.textColor = k_SelectedColor;
}
}
}

8
Assets/UnityTestTools/Common/Editor/Styles.cs.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: a8b92379e11501742b1badcbb08da812
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

104
Assets/UnityTestTools/Common/Editor/TestFilterSettings.cs

@ -0,0 +1,104 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System.Linq;
namespace UnityTest
{
public class TestFilterSettings
{
public bool ShowSucceeded;
public bool ShowFailed;
public bool ShowIgnored;
public bool ShowNotRun;
public string FilterByName;
public int FilterByCategory;
private GUIContent _succeededBtn;
private GUIContent _failedBtn;
private GUIContent _ignoredBtn;
private GUIContent _notRunBtn;
public string[] AvailableCategories;
private readonly string _prefsKey;
public TestFilterSettings(string prefsKey)
{
_prefsKey = prefsKey;
Load();
UpdateCounters(Enumerable.Empty<ITestResult>());
}
public void Load()
{
ShowSucceeded = EditorPrefs.GetBool(_prefsKey + ".ShowSucceeded", true);
ShowFailed = EditorPrefs.GetBool(_prefsKey + ".ShowFailed", true);
ShowIgnored = EditorPrefs.GetBool(_prefsKey + ".ShowIgnored", true);
ShowNotRun = EditorPrefs.GetBool(_prefsKey + ".ShowNotRun", true);
FilterByName = EditorPrefs.GetString(_prefsKey + ".FilterByName", string.Empty);
FilterByCategory = EditorPrefs.GetInt(_prefsKey + ".FilterByCategory", 0);
}
public void Save()
{
EditorPrefs.SetBool(_prefsKey + ".ShowSucceeded", ShowSucceeded);
EditorPrefs.SetBool(_prefsKey + ".ShowFailed", ShowFailed);
EditorPrefs.SetBool(_prefsKey + ".ShowIgnored", ShowIgnored);
EditorPrefs.SetBool(_prefsKey + ".ShowNotRun", ShowNotRun);
EditorPrefs.SetString(_prefsKey + ".FilterByName", FilterByName);
EditorPrefs.SetInt(_prefsKey + ".FilterByCategory", FilterByCategory);
}
public void UpdateCounters(IEnumerable<ITestResult> results)
{
var summary = new ResultSummarizer(results);
_succeededBtn = new GUIContent(summary.Passed.ToString(), Icons.SuccessImg, "Show tests that succeeded");
_failedBtn = new GUIContent((summary.Errors + summary.Failures + summary.Inconclusive).ToString(), Icons.FailImg, "Show tests that failed");
_ignoredBtn = new GUIContent((summary.Ignored + summary.NotRunnable).ToString(), Icons.IgnoreImg, "Show tests that are ignored");
_notRunBtn = new GUIContent((summary.TestsNotRun - summary.Ignored - summary.NotRunnable).ToString(), Icons.UnknownImg, "Show tests that didn't run");
}
public string[] GetSelectedCategories()
{
if(AvailableCategories == null) return new string[0];
return AvailableCategories.Where ((c, i) => (FilterByCategory & (1 << i)) != 0).ToArray();
}
public void OnGUI()
{
EditorGUI.BeginChangeCheck();
FilterByName = GUILayout.TextField(FilterByName, "ToolbarSeachTextField", GUILayout.MinWidth(100), GUILayout.MaxWidth(250), GUILayout.ExpandWidth(true));
if(GUILayout.Button (GUIContent.none, string.IsNullOrEmpty(FilterByName) ? "ToolbarSeachCancelButtonEmpty" : "ToolbarSeachCancelButton"))
FilterByName = string.Empty;
if (AvailableCategories != null && AvailableCategories.Length > 0)
FilterByCategory = EditorGUILayout.MaskField(FilterByCategory, AvailableCategories, EditorStyles.toolbarDropDown, GUILayout.MaxWidth(90));
ShowSucceeded = GUILayout.Toggle(ShowSucceeded, _succeededBtn, EditorStyles.toolbarButton);
ShowFailed = GUILayout.Toggle(ShowFailed, _failedBtn, EditorStyles.toolbarButton);
ShowIgnored = GUILayout.Toggle(ShowIgnored, _ignoredBtn, EditorStyles.toolbarButton);
ShowNotRun = GUILayout.Toggle(ShowNotRun, _notRunBtn, EditorStyles.toolbarButton);
if(EditorGUI.EndChangeCheck()) Save ();
}
public RenderingOptions BuildRenderingOptions()
{
var options = new RenderingOptions();
options.showSucceeded = ShowSucceeded;
options.showFailed = ShowFailed;
options.showIgnored = ShowIgnored;
options.showNotRunned = ShowNotRun;
options.nameFilter = FilterByName;
options.categories = GetSelectedCategories();
return options;
}
}
}

8
Assets/UnityTestTools/Common/Editor/TestFilterSettings.cs.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 5a2d025e58bff433e963d0a4cd7599ef
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

4
Assets/UnityTestTools/Common/Editor/icons.meta

@ -0,0 +1,4 @@
fileFormatVersion: 2
guid: e8bb6eae11352f44da0d6d8a8959b69e
DefaultImporter:
userData:

BIN
Assets/UnityTestTools/Common/Editor/icons/failed.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

35
Assets/UnityTestTools/Common/Editor/icons/failed.png.meta

@ -0,0 +1,35 @@
fileFormatVersion: 2
guid: 41488feb372865440b7c01773f04c0cf
TextureImporter:
serializedVersion: 2
mipmaps:
mipMapMode: 0
enableMipMap: 0
linearTexture: 1
correctGamma: 0
fadeOut: 0
borderMipMap: 0
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: .25
normalMapFilter: 0
isReadable: 0
grayScaleToAlpha: 0
generateCubemap: 0
seamlessCubemap: 0
textureFormat: -1
maxTextureSize: 1024
textureSettings:
filterMode: -1
aniso: 1
mipBias: -1
wrapMode: 1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
textureType: 2
buildTargetSettings: []
userData:

BIN
Assets/UnityTestTools/Common/Editor/icons/ignored.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

35
Assets/UnityTestTools/Common/Editor/icons/ignored.png.meta

@ -0,0 +1,35 @@
fileFormatVersion: 2
guid: 0076bfa6073f17546b3535ac1b456b0b
TextureImporter:
serializedVersion: 2
mipmaps:
mipMapMode: 0
enableMipMap: 0
linearTexture: 1
correctGamma: 0
fadeOut: 0
borderMipMap: 0
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: .25
normalMapFilter: 0
isReadable: 0
grayScaleToAlpha: 0
generateCubemap: 0
seamlessCubemap: 0
textureFormat: -1
maxTextureSize: 1024
textureSettings:
filterMode: -1
aniso: 1
mipBias: -1
wrapMode: 1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
textureType: 2
buildTargetSettings: []
userData:

BIN
Assets/UnityTestTools/Common/Editor/icons/inconclusive.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

35
Assets/UnityTestTools/Common/Editor/icons/inconclusive.png.meta

@ -0,0 +1,35 @@
fileFormatVersion: 2
guid: e28761099904678488cdddf7b6be2ceb
TextureImporter:
serializedVersion: 2
mipmaps:
mipMapMode: 0
enableMipMap: 0
linearTexture: 1
correctGamma: 0
fadeOut: 0
borderMipMap: 0
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: .25
normalMapFilter: 0
isReadable: 0
grayScaleToAlpha: 0
generateCubemap: 0
seamlessCubemap: 0
textureFormat: -1
maxTextureSize: 1024
textureSettings:
filterMode: -1
aniso: 1
mipBias: -1
wrapMode: 1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
textureType: 2
buildTargetSettings: []
userData:

BIN
Assets/UnityTestTools/Common/Editor/icons/normal.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

35
Assets/UnityTestTools/Common/Editor/icons/normal.png.meta

@ -0,0 +1,35 @@
fileFormatVersion: 2
guid: a9f3c491f4c2f9f43ac33a27c16913dd
TextureImporter:
serializedVersion: 2
mipmaps:
mipMapMode: 0
enableMipMap: 0
linearTexture: 1
correctGamma: 0
fadeOut: 0
borderMipMap: 0
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: .25
normalMapFilter: 0
isReadable: 0
grayScaleToAlpha: 0
generateCubemap: 0
seamlessCubemap: 0
textureFormat: -1
maxTextureSize: 1024
textureSettings:
filterMode: -1
aniso: 1
mipBias: -1
wrapMode: 1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
textureType: 2
buildTargetSettings: []
userData:

BIN
Assets/UnityTestTools/Common/Editor/icons/passed.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

35
Assets/UnityTestTools/Common/Editor/icons/passed.png.meta

@ -0,0 +1,35 @@
fileFormatVersion: 2
guid: 31f7928179ee46d4690d274579efb037
TextureImporter:
serializedVersion: 2
mipmaps:
mipMapMode: 0
enableMipMap: 0
linearTexture: 1
correctGamma: 0
fadeOut: 0
borderMipMap: 0
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: .25
normalMapFilter: 0
isReadable: 0
grayScaleToAlpha: 0
generateCubemap: 0
seamlessCubemap: 0
textureFormat: -1
maxTextureSize: 1024
textureSettings:
filterMode: -1
aniso: 1
mipBias: -1
wrapMode: 1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
textureType: 2
buildTargetSettings: []
userData:

BIN
Assets/UnityTestTools/Common/Editor/icons/stopwatch.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

35
Assets/UnityTestTools/Common/Editor/icons/stopwatch.png.meta

@ -0,0 +1,35 @@
fileFormatVersion: 2
guid: f73f95ae19d51af47ad56044f2779aa1
TextureImporter:
serializedVersion: 2
mipmaps:
mipMapMode: 0
enableMipMap: 0
linearTexture: 1
correctGamma: 0
fadeOut: 0
borderMipMap: 0
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: .25
normalMapFilter: 0
isReadable: 0
grayScaleToAlpha: 0
generateCubemap: 0
seamlessCubemap: 0
textureFormat: -1
maxTextureSize: 1024
textureSettings:
filterMode: -1
aniso: 1
mipBias: -1
wrapMode: 1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
textureType: 2
buildTargetSettings: []
userData:

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save