Browse Source
The test framework and tests will not be included in the published Fungus unitypackage.master
chrisgregan
10 years ago
247 changed files with 11343 additions and 0 deletions
@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 5c8e5d66ff19140a1bf3cfdc3955859c |
||||
folderAsset: yes |
||||
timeCreated: 1438859672 |
||||
licenseType: Free |
||||
DefaultImporter: |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,5 @@
|
||||
fileFormatVersion: 2 |
||||
guid: b27b28700d3365146808b6e082748201 |
||||
folderAsset: yes |
||||
DefaultImporter: |
||||
userData: |
@ -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; } |
||||
} |
||||
} |
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 8bafa54482a87ac4cbd7ff1bfd1ac93a |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
@ -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(); |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2 |
||||
guid: ef3769ab00d50bc4fbb05a9a91c741d9 |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
@ -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); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 85280dad1e618c143bd3fb07a197b469 |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
@ -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, |
||||
} |
||||
} |
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2 |
||||
guid: cbb75d1643c5a55439f8861a827f411b |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
@ -0,0 +1,5 @@
|
||||
fileFormatVersion: 2 |
||||
guid: bb9e10c25f478c84f826ea85b03ec179 |
||||
folderAsset: yes |
||||
DefaultImporter: |
||||
userData: |
@ -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; } } |
||||
} |
||||
} |
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2 |
||||
guid: b4995756bd539804e8143ff1e730f806 |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
@ -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; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 2586c8e41f35d2f4fadde53020bf4207 |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
@ -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(); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 4eff45b2ac4067b469d7994298341db6 |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
@ -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; } } |
||||
} |
||||
} |
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2 |
||||
guid: c86508f389d643b40b6e1d7dcc1d4df2 |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
@ -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; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2 |
||||
guid: a4928c6c2b973874c8d4e6c9a69bb5b4 |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
@ -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(); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 902961c69f102f4409c29b9e54258701 |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
@ -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(); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2 |
||||
guid: da4a3a521c5c1494aae123742ca5c8f5 |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
@ -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(); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 8d45a1674f5e2e04485eafef922fac41 |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
@ -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(); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 58783f051e477fd4e93b42ec7a43bb64 |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
@ -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(); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 927f2d7e4f63632448b2a63d480e601a |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
@ -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; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 9d6d16a58a17940419a1dcbff3c60ca5 |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
@ -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; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2 |
||||
guid: a713db190443e814f8254a5a59014ec4 |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
@ -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(); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 6febd2d5046657040b3da98b7010ee29 |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
@ -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; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 383a85a79f164d04b8a56b0ff4e04cb7 |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
@ -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; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 7b35a237804d5eb42bd8c4e67568ae24 |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
@ -0,0 +1,5 @@
|
||||
fileFormatVersion: 2 |
||||
guid: a28bb39b4fb20514990895d9cb4eaea9 |
||||
folderAsset: yes |
||||
DefaultImporter: |
||||
userData: |
@ -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(); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2 |
||||
guid: fd1cabf2c45d0a8489635607a6048621 |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
@ -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; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 1a1e855053e7e2f46ace1dc93f2036f2 |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
@ -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); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2 |
||||
guid: d83c02fb0f220344da42a8213ed36cb5 |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
@ -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); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 95c9cd9570a6fba4198b6e4f15e11e5e |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
@ -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(); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 83ec3ed09f8f2f34ea7483e055f6d76d |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
@ -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; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2 |
||||
guid: efab536803bd0154a8a7dc78e8767ad9 |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
@ -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; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 97340abf816b1424fa835a4f26bbdc78 |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
@ -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; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2 |
||||
guid: cb824de9146b42343a985aaf63beffd1 |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
@ -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 ""; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 33bf96aa461ea1d478bb757c52f51c95 |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
@ -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; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 5e577f31e55208b4d8a1774b958e6ed5 |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
@ -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 |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 6619da1897737044080bdb8bc60eff87 |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
@ -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); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2 |
||||
guid: bbbd193a27920d9478c2a766a7291d72 |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
@ -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) |
||||
{ |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 3b85786dfd1aef544bf8bb873d6a4ebb |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
@ -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 |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 80df8ef907961e34dbcc7c89b22729b9 |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
@ -0,0 +1,5 @@
|
||||
fileFormatVersion: 2 |
||||
guid: a2caba6436df568499c84c1c607ce766 |
||||
folderAsset: yes |
||||
DefaultImporter: |
||||
userData: |
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2 |
||||
guid: f4ab061d0035ee545a936bdf8f3f8620 |
||||
DefaultImporter: |
||||
userData: |
@ -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)); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 8571844b0c115b84cbe8b3f67e8dec04 |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
@ -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; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 9ac961be07107124a88dcb81927143d4 |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
@ -0,0 +1,5 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 4ffbf5a07740aa5479651bd415f52ebb |
||||
folderAsset: yes |
||||
DefaultImporter: |
||||
userData: |
@ -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; |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2 |
||||
guid: ce89106be5bd4204388d58510e4e55da |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
@ -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; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2 |
||||
guid: fe6b4d68575d4ba44b1d5c5c3f0e96d3 |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
@ -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); |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2 |
||||
guid: e9bba41ace7686d4ab0c400d1e7f55b7 |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
@ -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; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2 |
||||
guid: a8b92379e11501742b1badcbb08da812 |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
@ -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; |
||||
} |
||||
} |
||||
|
||||
} |
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 5a2d025e58bff433e963d0a4cd7599ef |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
@ -0,0 +1,4 @@
|
||||
fileFormatVersion: 2 |
||||
guid: e8bb6eae11352f44da0d6d8a8959b69e |
||||
DefaultImporter: |
||||
userData: |
After Width: | Height: | Size: 1.0 KiB |
@ -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: |
After Width: | Height: | Size: 1.0 KiB |
@ -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: |
After Width: | Height: | Size: 1.0 KiB |
@ -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: |
After Width: | Height: | Size: 1.0 KiB |
@ -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: |
After Width: | Height: | Size: 1.0 KiB |
@ -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: |
After Width: | Height: | Size: 1.0 KiB |
@ -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…
Reference in new issue