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