This commit is contained in:
2024-09-20 20:30:10 +02:00
commit 4fabf1a6fd
29169 changed files with 1706941 additions and 0 deletions

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 239dd6edc8e5cd14585c03e09e86a747
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,151 @@
using System.Collections;
using System.IO;
using NUnit.Framework;
using UnityEditor;
using UnityEngine.EventSystems;
using UnityEngine.TestTools;
using UnityEngine.UI;
using UnityEngine;
public class ButtonTests : IPrebuildSetup
{
GameObject m_PrefabRoot;
const string kPrefabPath = "Assets/Resources/ButtonPrefab.prefab";
public void Setup()
{
#if UNITY_EDITOR
var rootGO = new GameObject("rootGo");
var canvasGO = new GameObject("Canvas", typeof(Canvas));
canvasGO.transform.SetParent(rootGO.transform);
var canvas = canvasGO.GetComponent<Canvas>();
canvas.referencePixelsPerUnit = 100;
GameObject eventSystemGO = new GameObject("EventSystem", typeof(EventSystem));
eventSystemGO.transform.SetParent(rootGO.transform);
GameObject TestButtonGO = new GameObject("TestButton", typeof(RectTransform), typeof(TestButton));
TestButtonGO.transform.SetParent(canvasGO.transform);
if (!Directory.Exists("Assets/Resources/"))
Directory.CreateDirectory("Assets/Resources/");
PrefabUtility.SaveAsPrefabAsset(rootGO, kPrefabPath);
GameObject.DestroyImmediate(rootGO);
#endif
}
[SetUp]
public void TestSetup()
{
m_PrefabRoot = Object.Instantiate(Resources.Load("ButtonPrefab")) as GameObject;
}
[TearDown]
public void TearDown()
{
GameObject.DestroyImmediate(m_PrefabRoot);
}
[OneTimeTearDown]
public void OneTimeTearDown()
{
#if UNITY_EDITOR
AssetDatabase.DeleteAsset(kPrefabPath);
#endif
}
[Test]
public void PressShouldCallClickHandler()
{
Button button = m_PrefabRoot.GetComponentInChildren<Button>();
bool called = false;
button.onClick.AddListener(() => { called = true; });
button.OnPointerClick(new PointerEventData(m_PrefabRoot.GetComponentInChildren<EventSystem>()) { button = PointerEventData.InputButton.Left });
Assert.True(called);
}
[Test]
public void PressInactiveShouldNotCallClickHandler()
{
Button button = m_PrefabRoot.GetComponentInChildren<Button>();
bool called = false;
button.enabled = false;
button.onClick.AddListener(() => { called = true; });
button.OnPointerClick(new PointerEventData(m_PrefabRoot.GetComponentInChildren<EventSystem>()) { button = PointerEventData.InputButton.Left });
Assert.False(called);
}
[Test]
public void PressNotInteractableShouldNotCallClickHandler()
{
Button button = m_PrefabRoot.GetComponentInChildren<Button>();
bool called = false;
button.interactable = false;
button.onClick.AddListener(() => { called = true; });
button.OnPointerClick(new PointerEventData(m_PrefabRoot.GetComponentInChildren<EventSystem>()) { button = PointerEventData.InputButton.Left });
Assert.False(called);
}
[Test]
public void SelectShouldHoldThePreviousStateAfterDisablingAndEnabling()
{
TestButton button = m_PrefabRoot.GetComponentInChildren<TestButton>();
button.onClick.AddListener(() => {
button.Select();
button.enabled = false;
});
button.OnPointerClick(new PointerEventData(m_PrefabRoot.GetComponentInChildren<EventSystem>()) { button = PointerEventData.InputButton.Left });
Assert.False(button.enabled, "Expected button to not be enabled");
button.enabled = true;
Assert.True(button.isStateSelected, "Expected selected state to be true");
}
[Test]
public void SubmitShouldCallClickHandler()
{
Button button = m_PrefabRoot.GetComponentInChildren<Button>();
bool called = false;
button.onClick.AddListener(() => { called = true; });
button.OnSubmit(null);
Assert.True(called);
}
[Test]
public void SubmitInactiveShouldNotCallClickHandler()
{
Button button = m_PrefabRoot.GetComponentInChildren<Button>();
bool called = false;
button.enabled = false;
button.onClick.AddListener(() => { called = true; });
button.OnSubmit(new PointerEventData(m_PrefabRoot.GetComponentInChildren<EventSystem>()) { button = PointerEventData.InputButton.Left });
Assert.False(called);
}
[Test]
public void SubmitNotInteractableShouldNotCallClickHandler()
{
Button button = m_PrefabRoot.GetComponentInChildren<Button>();
bool called = false;
button.interactable = false;
button.onClick.AddListener(() => { called = true; });
button.OnSubmit(new PointerEventData(m_PrefabRoot.GetComponentInChildren<EventSystem>()) { button = PointerEventData.InputButton.Left });
Assert.False(called);
}
[UnityTest]
public IEnumerator SubmitShouldTransitionToPressedStateAndBackToNormal()
{
TestButton button = m_PrefabRoot.GetComponentInChildren<TestButton>();
Assert.True(button.IsTransitionToNormal(0));
button.OnSubmit(null);
Assert.True(button.isStateNormal);
Assert.True(button.IsTransitionToPressed(1));
yield return new WaitWhile(() => button.StateTransitionCount == 2);
// 3rd transition back to normal should have started
Assert.True(button.IsTransitionToNormal(2));
yield return null;
Assert.True(button.isStateNormal);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1ef2923b9c5521948a04299da53ae750
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,31 @@
using System.Collections.Generic;
using UnityEngine.UI;
class TestButton : Button
{
public bool isStateNormal { get { return currentSelectionState == SelectionState.Normal; } }
public bool isStateHighlighted { get { return currentSelectionState == SelectionState.Highlighted; } }
public bool isStatePressed { get { return currentSelectionState == SelectionState.Pressed; } }
public bool isStateDisabled { get { return currentSelectionState == SelectionState.Disabled; } }
public bool isStateSelected { get { return currentSelectionState == SelectionState.Selected; } }
private bool IsTransitionTo(int index, SelectionState selectionState)
{
return index < m_StateTransitions.Count && m_StateTransitions[index] == selectionState;
}
public bool IsTransitionToNormal(int index) { return IsTransitionTo(index, SelectionState.Normal); }
public bool IsTransitionToHighlighted(int index) { return IsTransitionTo(index, SelectionState.Highlighted); }
public bool IsTransitionToPressed(int index) { return IsTransitionTo(index, SelectionState.Pressed); }
public bool IsTransitionToDisabled(int index) { return IsTransitionTo(index, SelectionState.Disabled); }
private readonly List<SelectionState> m_StateTransitions = new List<SelectionState>();
public int StateTransitionCount { get { return m_StateTransitions.Count; } }
protected override void DoStateTransition(SelectionState state, bool instant)
{
m_StateTransitions.Add(state);
base.DoStateTransition(state, instant);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4f5ed95515938d14189b094f8654d0bd
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 9a3557da07c729b4eb774b8e30e157a4
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,9 @@
using UnityEngine;
public class BridgeScriptForRetainingObjects : MonoBehaviour
{
public const string bridgeObjectName = "BridgeGameObject";
public GameObject canvasGO;
public GameObject nestedCanvasGO;
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1a26e19d51cbfac42a02631ad1f9e39e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,203 @@
using UnityEngine;
using UnityEngine.TestTools;
using NUnit.Framework;
using System.Collections;
using UnityEngine.UI;
[TestFixture]
public class CanvasGroupTests
{
GameObject m_CanvasObject;
CanvasGroup m_CanvasGroup;
CanvasRenderer m_ChildCanvasRenderer;
CanvasGroup m_ChildCanvasGroup;
CanvasRenderer m_GrandChildCanvasRenderer;
CanvasGroup m_GrandChildCanvasGroup;
GameObject m_CanvasTwoObject;
CanvasGroup m_CanvasTwoGroup;
CanvasRenderer m_ChildCanvasTwoRenderer;
const float m_CanvasAlpha = 0.25f;
const float m_ChildAlpha = 0.5f;
const float m_GrandChildAlpha = 0.8f;
[SetUp]
public void TestSetup()
{
m_CanvasObject = new GameObject("Canvas", typeof(Canvas));
m_CanvasGroup = m_CanvasObject.AddComponent<CanvasGroup>();
m_CanvasGroup.alpha = m_CanvasAlpha;
var childObject = new GameObject("Child Object", typeof(Image));
childObject.transform.SetParent(m_CanvasObject.transform);
m_ChildCanvasGroup = childObject.AddComponent<CanvasGroup>();
m_ChildCanvasGroup.alpha = m_ChildAlpha;
m_ChildCanvasRenderer = childObject.GetComponent<CanvasRenderer>();
var grandChildObject = new GameObject("Grand Child Object", typeof(Image));
grandChildObject.transform.SetParent(childObject.transform);
m_GrandChildCanvasGroup = grandChildObject.AddComponent<CanvasGroup>();
m_GrandChildCanvasGroup.alpha = m_GrandChildAlpha;
m_GrandChildCanvasRenderer = grandChildObject.GetComponent<CanvasRenderer>();
m_CanvasTwoObject = new GameObject("CanvasTwo", typeof(Canvas));
m_CanvasTwoObject.transform.SetParent(m_CanvasObject.transform);
m_CanvasTwoGroup = m_CanvasTwoObject.AddComponent<CanvasGroup>();
m_CanvasTwoGroup.alpha = m_CanvasAlpha;
var childTwoObject = new GameObject("Child Two Object", typeof(Image));
childTwoObject.transform.SetParent(m_CanvasTwoObject.transform);
m_ChildCanvasTwoRenderer = childTwoObject.GetComponent<CanvasRenderer>();
}
[TearDown]
public void TearDown()
{
GameObject.DestroyImmediate(m_CanvasObject);
}
private void SetUpCanvasGroupState()
{
m_CanvasGroup.enabled = false;
m_CanvasGroup.ignoreParentGroups = false;
m_ChildCanvasGroup.enabled = false;
m_ChildCanvasGroup.ignoreParentGroups = false;
m_GrandChildCanvasGroup.enabled = false;
m_GrandChildCanvasGroup.ignoreParentGroups = false;
m_CanvasTwoGroup.enabled = false;
m_CanvasTwoGroup.ignoreParentGroups = false;
}
[Test]
public void EnabledCanvasGroupEffectSelfAndChildrenAlpha()
{
// Set up the states of the canvas groups for the tests.
SetUpCanvasGroupState();
// With no enabled CanvasGroup the Alphas should be 1
Assert.AreEqual(1.0f, m_ChildCanvasRenderer.GetInheritedAlpha());
Assert.AreEqual(1.0f, m_GrandChildCanvasRenderer.GetInheritedAlpha());
// Enable the child CanvasGroup. It and its children should now have the same alpha value.
m_ChildCanvasGroup.enabled = true;
Assert.AreEqual(m_ChildAlpha, m_ChildCanvasRenderer.GetInheritedAlpha());
Assert.AreEqual(m_ChildAlpha, m_GrandChildCanvasRenderer.GetInheritedAlpha());
}
[Test]
public void EnabledCanvasGroupOnACanvasEffectAllChildrenAlpha()
{
// Set up the states of the canvas groups for the tests.
SetUpCanvasGroupState();
// With no enabled CanvasGroup the Alphas should be 1
Assert.AreEqual(1.0f, m_ChildCanvasRenderer.GetInheritedAlpha());
Assert.AreEqual(1.0f, m_GrandChildCanvasRenderer.GetInheritedAlpha());
// Children under a different nest canvas should also obey the alpha
Assert.AreEqual(1.0f, m_ChildCanvasTwoRenderer.GetInheritedAlpha());
// Enable the Canvas CanvasGroup. All of the Canvas children should now have the same alpha value.
m_CanvasGroup.enabled = true;
Assert.AreEqual(m_CanvasAlpha, m_ChildCanvasRenderer.GetInheritedAlpha());
Assert.AreEqual(m_CanvasAlpha, m_GrandChildCanvasRenderer.GetInheritedAlpha());
// Children under a different nest canvas should also obey the alpha
Assert.AreEqual(m_CanvasAlpha, m_ChildCanvasTwoRenderer.GetInheritedAlpha());
}
[Test]
public void EnabledCanvasGroupOnLeafChildEffectOnlyThatChild()
{
// Set up the states of the canvas groups for the tests.
SetUpCanvasGroupState();
// With no enabled CanvasGroup the Alphas should be 1
Assert.AreEqual(1.0f, m_ChildCanvasRenderer.GetInheritedAlpha());
Assert.AreEqual(1.0f, m_GrandChildCanvasRenderer.GetInheritedAlpha());
// Enable the Leaf child CanvasGroup. Only it should have a modified alpha
m_GrandChildCanvasGroup.enabled = true;
Assert.AreEqual(1.0f, m_ChildCanvasRenderer.GetInheritedAlpha());
Assert.AreEqual(m_GrandChildAlpha, m_GrandChildCanvasRenderer.GetInheritedAlpha());
}
[Test]
public void EnabledCanvasGroupOnCanvasAndChildMultipleAlphaValuesCorrectly()
{
// Set up the states of the canvas groups for the tests.
SetUpCanvasGroupState();
// With no enabled CanvasGroup the Alphas should be 1
Assert.AreEqual(1.0f, m_ChildCanvasRenderer.GetInheritedAlpha());
Assert.AreEqual(1.0f, m_GrandChildCanvasRenderer.GetInheritedAlpha());
// Enable the Canvas CanvasGroup. All of the Canvas children should now have the same alpha value.
m_CanvasGroup.enabled = true;
m_ChildCanvasGroup.enabled = true;
Assert.AreEqual(m_CanvasAlpha * m_ChildAlpha, m_ChildCanvasRenderer.GetInheritedAlpha());
Assert.AreEqual(m_CanvasAlpha * m_ChildAlpha, m_GrandChildCanvasRenderer.GetInheritedAlpha());
}
[Test]
public void EnabledCanvasGroupOnCanvasAndChildWithChildIgnoringParentGroupMultipleAlphaValuesCorrectly()
{
// Set up the states of the canvas groups for the tests.
SetUpCanvasGroupState();
// With no enabled CanvasGroup the Alphas should be 1
Assert.AreEqual(1.0f, m_ChildCanvasRenderer.GetInheritedAlpha());
Assert.AreEqual(1.0f, m_GrandChildCanvasRenderer.GetInheritedAlpha());
// Enable the Canvas CanvasGroup. All of the Canvas children should now have the same alpha value.
m_CanvasGroup.enabled = true;
m_ChildCanvasGroup.enabled = true;
m_ChildCanvasGroup.ignoreParentGroups = true;
Assert.AreEqual(m_ChildAlpha, m_ChildCanvasRenderer.GetInheritedAlpha());
Assert.AreEqual(m_ChildAlpha, m_GrandChildCanvasRenderer.GetInheritedAlpha());
}
[Test]
public void EnabledCanvasGroupOnCanvasAndChildrenWithAllChildrenIgnoringParentGroupMultipleAlphaValuesCorrectly()
{
// Set up the states of the canvas groups for the tests.
SetUpCanvasGroupState();
// With no enabled CanvasGroup the Alphas should be 1
Assert.AreEqual(1.0f, m_ChildCanvasRenderer.GetInheritedAlpha());
Assert.AreEqual(1.0f, m_GrandChildCanvasRenderer.GetInheritedAlpha());
// Enable the Canvas CanvasGroup. All of the Canvas children should now have the same alpha value.
m_CanvasGroup.enabled = true;
m_ChildCanvasGroup.enabled = true;
m_GrandChildCanvasGroup.enabled = true;
m_ChildCanvasGroup.ignoreParentGroups = true;
m_GrandChildCanvasGroup.ignoreParentGroups = true;
Assert.AreEqual(m_ChildAlpha, m_ChildCanvasRenderer.GetInheritedAlpha());
Assert.AreEqual(m_GrandChildAlpha, m_GrandChildCanvasRenderer.GetInheritedAlpha());
}
[Test]
public void EnabledCanvasGroupOnNestedCanvasIgnoringParentGroupMultipleAlphaValuesCorrectly()
{
// Set up the states of the canvas groups for the tests.
SetUpCanvasGroupState();
// With no enabled CanvasGroup the Alphas should be 1
Assert.AreEqual(1.0f, m_ChildCanvasTwoRenderer.GetInheritedAlpha());
// Enable the Canvas CanvasGroup. All of the Canvas children should now have the same alpha value.
m_CanvasGroup.enabled = true;
m_CanvasTwoGroup.enabled = true;
m_CanvasTwoGroup.ignoreParentGroups = true;
Assert.AreEqual(m_CanvasAlpha, m_ChildCanvasTwoRenderer.GetInheritedAlpha());
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a14a59f2a5c757e469c3e4e17b798c2e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,47 @@
using System;
using System.Collections;
using UnityEngine;
using UnityEngine.TestTools;
using NUnit.Framework;
using UnityEngine.SceneManagement;
using UnityEditor;
[TestFixture]
public class CanvasResizeCorrectlyForRenderTexture
{
Canvas m_Canvas;
Camera m_Camera;
RenderTexture m_RenderTexture;
[Test]
public void CanvasResizeCorrectly()
{
var cameraGameObject = new GameObject("PreviewCamera", typeof(Camera));
var canvasGameObject = new GameObject("Canvas", typeof(Canvas));
m_Camera = cameraGameObject.GetComponent<Camera>();
m_Canvas = canvasGameObject.GetComponent<Canvas>();
m_Canvas.renderMode = RenderMode.ScreenSpaceCamera;
m_Canvas.worldCamera = m_Camera;
var rectTransform = canvasGameObject.transform as RectTransform;
m_Canvas.updateRectTransformForStandalone = StandaloneRenderResize.Disabled;
m_RenderTexture = new RenderTexture(100, 100, 0);
m_Camera.targetTexture = m_RenderTexture;
m_Camera.Render();
Assert.AreNotEqual(new Vector2(100, 100), rectTransform.sizeDelta);
m_Canvas.updateRectTransformForStandalone = StandaloneRenderResize.Enabled;
m_Camera.Render();
Assert.AreEqual(new Vector2(100, 100), rectTransform.sizeDelta);
}
[TearDown]
public void TearDown()
{
GameObject.DestroyImmediate(m_Canvas.gameObject);
GameObject.DestroyImmediate(m_Camera.gameObject);
UnityEngine.Object.DestroyImmediate(m_RenderTexture);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d4dbe29df1b294c4f8f0a2fb529d19fd
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,54 @@
using UnityEngine;
using UnityEngine.TestTools;
using NUnit.Framework;
using System.Collections;
using UnityEngine.UI;
[TestFixture]
[Category("RegressionTest")]
[Description("CoveredBugID = 734299")]
public class CanvasScalerWithChildTextObjectDoesNotCrash
{
GameObject m_CanvasObject;
[SetUp]
public void TestSetup()
{
#if UNITY_EDITOR
UnityEditor.EditorApplication.ExecuteMenuItem("Window/General/Game");
#endif
}
[UnityTest]
public IEnumerator CanvasScalerWithChildTextObjectWithTextFontDoesNotCrash()
{
//This adds a Canvas component as well
m_CanvasObject = new GameObject("Canvas");
var canvasScaler = m_CanvasObject.AddComponent<CanvasScaler>();
m_CanvasObject.GetComponent<Canvas>().renderMode = RenderMode.ScreenSpaceCamera;
//the crash only reproduces if the text component is a child of the game object
//that has the CanvasScaler component and if it has an actual font and text set
var textObject = new GameObject("Text").AddComponent<UnityEngine.UI.Text>();
textObject.font = Font.CreateDynamicFontFromOSFont("Arial", 14);
textObject.text = "New Text";
textObject.transform.SetParent(m_CanvasObject.transform);
canvasScaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize;
canvasScaler.referenceResolution = new Vector2(1080, 1020);
//The crash happens when setting the referenceResolution to a small value
canvasScaler.referenceResolution = new Vector2(9, 9);
//We need to wait a few milliseconds for the crash to happen, otherwise Debug.Log will
//get executed and the test will pass
yield return new WaitForSeconds(0.1f);
Assert.That(true);
}
[TearDown]
public void TearDown()
{
GameObject.DestroyImmediate(m_CanvasObject);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 13d161b14bb3ab74e8a9634e26fb7a5e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,64 @@
using System;
using System.Collections;
using UnityEngine;
using UnityEngine.TestTools;
using NUnit.Framework;
using UnityEngine.SceneManagement;
using UnityEditor;
[TestFixture]
public class CanvasSizeCorrectInAwakeAndStart : IPrebuildSetup
{
const string k_SceneName = "CanvasSizeCorrectInAwakeAndStartScene";
GameObject m_CanvasGameObject;
Scene m_InitScene;
public void Setup()
{
#if UNITY_EDITOR
Action codeToExecute = delegate()
{
var canvasGO = new GameObject("CanvasToAddImage", typeof(Canvas));
var imageGO = new GameObject("ImageOnCanvas", typeof(UnityEngine.UI.Image));
imageGO.transform.localPosition = Vector3.one;
imageGO.transform.SetParent(canvasGO.transform);
imageGO.AddComponent<CanvasSizeCorrectInAwakeAndStartScript>();
canvasGO.GetComponent<Canvas>().renderMode = RenderMode.ScreenSpaceOverlay;
imageGO.SetActive(false);
};
CreateSceneUtility.CreateScene(k_SceneName, codeToExecute);
#endif
}
[SetUp]
public void TestSetup()
{
m_InitScene = SceneManager.GetActiveScene();
}
[UnityTest]
public IEnumerator CanvasSizeIsCorrectInAwakeAndStart()
{
AsyncOperation operation = SceneManager.LoadSceneAsync(k_SceneName, LoadSceneMode.Additive);
yield return operation;
SceneManager.SetActiveScene(SceneManager.GetSceneByName(k_SceneName));
m_CanvasGameObject = GameObject.Find("CanvasToAddImage");
var imageGO = m_CanvasGameObject.transform.Find("ImageOnCanvas");
imageGO.gameObject.SetActive(true);
var component = imageGO.GetComponent<CanvasSizeCorrectInAwakeAndStartScript>();
yield return new WaitUntil(() => component.isAwakeCalled && component.isStartCalled);
}
[TearDown]
public void TearDown()
{
GameObject.DestroyImmediate(m_CanvasGameObject);
SceneManager.SetActiveScene(m_InitScene);
SceneManager.UnloadSceneAsync(k_SceneName);
#if UNITY_EDITOR
AssetDatabase.DeleteAsset("Assets/" + k_SceneName + ".unity");
#endif
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ec35c13a8280a8d4e817bc4afd8a95de
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,21 @@
using NUnit.Framework;
using UnityEngine;
using UnityEngine.TestTools.Utils;
public class CanvasSizeCorrectInAwakeAndStartScript : MonoBehaviour
{
public bool isStartCalled { get; private set; }
public bool isAwakeCalled { get; private set; }
protected void Awake()
{
Assert.That(transform.position, Is.Not.EqualTo(Vector3.zero).Using(new Vector3EqualityComparer(0.0f)));
isAwakeCalled = true;
}
protected void Start()
{
Assert.That(transform.position, Is.Not.EqualTo(Vector3.zero).Using(new Vector3EqualityComparer(0.0f)));
isStartCalled = true;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: df1ba932d4ce4534e97a0f10c85cd3c9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,84 @@
using UnityEngine;
using UnityEngine.TestTools;
using NUnit.Framework;
using System.Collections;
using UnityEngine.TestTools.Utils;
[TestFixture]
public class CheckMeshColorsAndColors32Match
{
GameObject m_CanvasGO;
GameObject m_ColorMeshGO;
GameObject m_Color32MeshGO;
Texture2D m_ScreenTexture;
[SetUp]
public void TestSetup()
{
// Create Canvas
m_CanvasGO = new GameObject("Canvas");
Canvas canvas = m_CanvasGO.AddComponent<Canvas>();
canvas.renderMode = RenderMode.ScreenSpaceOverlay;
// Create Color UI GameObject
m_ColorMeshGO = new GameObject("ColorMesh");
CanvasRenderer colorMeshCanvasRenderer = m_ColorMeshGO.AddComponent<CanvasRenderer>();
RectTransform colorMeshRectTransform = m_ColorMeshGO.AddComponent<RectTransform>();
colorMeshRectTransform.pivot = colorMeshRectTransform.anchorMin = colorMeshRectTransform.anchorMax = Vector2.zero;
m_ColorMeshGO.transform.SetParent(m_CanvasGO.transform);
// Create Color32 UI GameObject
m_Color32MeshGO = new GameObject("Color32Mesh");
CanvasRenderer color32MeshCanvasRenderer = m_Color32MeshGO.AddComponent<CanvasRenderer>();
RectTransform color32MeshRectTransform = m_Color32MeshGO.AddComponent<RectTransform>();
color32MeshRectTransform.pivot = color32MeshRectTransform.anchorMin = color32MeshRectTransform.anchorMax = Vector2.zero;
m_Color32MeshGO.transform.SetParent(m_CanvasGO.transform);
Material material = new Material(Shader.Find("UI/Default"));
// Setup Color mesh and add it to Color CanvasRenderer
Mesh meshColor = new Mesh();
meshColor.vertices = new Vector3[3] { new Vector3(0, 0, 0), new Vector3(0, 10, 0), new Vector3(10, 0, 0) };
meshColor.triangles = new int[3] { 0, 1, 2 };
meshColor.normals = new Vector3[3] { Vector3.zero, Vector3.zero, Vector3.zero };
meshColor.colors = new Color[3] { Color.white, Color.white, Color.white };
meshColor.uv = new Vector2[3] { new Vector2(0, 0), new Vector2(0, 1), new Vector2(1, 0) };
colorMeshCanvasRenderer.SetMesh(meshColor);
colorMeshCanvasRenderer.SetMaterial(material, null);
// Setup Color32 mesh and add it to Color32 CanvasRenderer
Mesh meshColor32 = new Mesh();
meshColor32.vertices = new Vector3[3] { new Vector3(10, 0, 0), new Vector3(10, 10, 0), new Vector3(20, 0, 0) };
meshColor32.triangles = new int[3] { 0, 1, 2 };
meshColor32.normals = new Vector3[3] { Vector3.zero, Vector3.zero, Vector3.zero };
meshColor32.colors32 = new Color32[3] { Color.white, Color.white, Color.white };
meshColor32.uv = new Vector2[3] { new Vector2(0, 0), new Vector2(0, 1), new Vector2(1, 0) };
color32MeshCanvasRenderer.SetMesh(meshColor32);
color32MeshCanvasRenderer.SetMaterial(material, null);
}
[TearDown]
public void TearDown()
{
GameObject.DestroyImmediate(m_CanvasGO);
GameObject.DestroyImmediate(m_ScreenTexture);
}
[UnityTest]
public IEnumerator CheckMeshColorsAndColors32Matches()
{
yield return new WaitForEndOfFrame();
// Create a Texture2D
m_ScreenTexture = new Texture2D(Screen.width, Screen.height, TextureFormat.RGB24, false);
m_ScreenTexture.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0);
m_ScreenTexture.Apply();
Color screenPixelColorForMeshColor = m_ScreenTexture.GetPixel(1, 0);
Color screenPixelColorForMesh32Color = m_ScreenTexture.GetPixel(11, 0);
Assert.That(screenPixelColorForMesh32Color, Is.EqualTo(screenPixelColorForMeshColor).Using(new ColorEqualityComparer(0.0f)), "UI Mesh with Colors does not match UI Mesh with Colors32");
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9390296e78291b543b2f4a9761ef8139
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,74 @@
using UnityEngine;
using UnityEngine.TestTools;
using NUnit.Framework;
using System.Collections;
using UnityEngine.UI;
[TestFixture]
[UnityPlatform(include = new RuntimePlatform[] { RuntimePlatform.OSXEditor, RuntimePlatform.LinuxEditor, RuntimePlatform.WindowsEditor })]
[Category("RegressionTest")]
[Description("CoveredBugID = 904415")]
public class CoroutineWorksIfUIObjectIsAttached
{
GameObject m_CanvasMaster;
GameObject m_ImageObject;
[SetUp]
public void TestSetup()
{
m_CanvasMaster = new GameObject("Canvas", typeof(Canvas), typeof(CanvasScaler), typeof(GraphicRaycaster));
m_ImageObject = new GameObject("Image", typeof(Image));
m_ImageObject.SetActive(false);
}
[UnityTest]
public IEnumerator CoroutineWorksOnAttachingUIObject()
{
// Generating Basic scene
m_CanvasMaster.AddComponent<CoroutineObject>();
yield return null;
m_ImageObject.transform.SetParent(m_CanvasMaster.transform);
m_ImageObject.AddComponent<BugObject>();
m_ImageObject.SetActive(true);
yield return null;
yield return null;
yield return null;
Assert.That(m_CanvasMaster.GetComponent<CoroutineObject>().coroutineCount, Is.GreaterThan(1), "The Coroutine wasn't supposed to stop but continue to run, something made it stopped");
}
[TearDown]
public void TearDown()
{
GameObject.DestroyImmediate(m_CanvasMaster);
GameObject.DestroyImmediate(m_ImageObject);
}
}
public class BugObject : MonoBehaviour
{
void Awake()
{
GameObject newObject = new GameObject("NewGameObjectThatTriggersBug");
newObject.transform.SetParent(transform);
newObject.AddComponent<Text>();
}
}
public class CoroutineObject : MonoBehaviour
{
public int coroutineCount { get; private set; }
public IEnumerator Start()
{
// This coroutine should not stop and continue adding to the timer
while (true)
{
coroutineCount++;
yield return null;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8573c56c34e616248a3881b2c56280ef
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,25 @@
using System;
using System.Linq;
using UnityEngine;
using UnityEngine.SceneManagement;
class CreateSceneUtility
{
public static void CreateScene(string sceneName, Action delegateToExecute)
{
#if UNITY_EDITOR
string scenePath = "Assets/" + sceneName + ".unity";
var initScene = SceneManager.GetActiveScene();
var list = UnityEditor.EditorBuildSettings.scenes.ToList();
var newScene = UnityEditor.SceneManagement.EditorSceneManager.NewScene(UnityEditor.SceneManagement.NewSceneSetup.DefaultGameObjects, UnityEditor.SceneManagement.NewSceneMode.Additive);
GameObject.DestroyImmediate(Camera.main.GetComponent<AudioListener>());
delegateToExecute();
UnityEditor.SceneManagement.EditorSceneManager.SaveScene(newScene, scenePath);
UnityEditor.SceneManagement.EditorSceneManager.UnloadSceneAsync(newScene);
list.Add(new UnityEditor.EditorBuildSettingsScene(scenePath, true));
UnityEditor.EditorBuildSettings.scenes = list.ToArray();
SceneManager.SetActiveScene(initScene);
#endif
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: db339ef553721e94999125c0b9f909dc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,102 @@
using System.IO;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.TestTools;
using NUnit.Framework;
using System.Collections;
using UnityEditor;
public class NestedCanvas : IPrebuildSetup
{
Object m_GO1;
Object m_GO2;
const string kPrefabPath = "Assets/Resources/NestedCanvasPrefab.prefab";
public void Setup()
{
#if UNITY_EDITOR
var rootGO = new GameObject("RootGO");
var rootCanvasGO = new GameObject("Canvas", typeof(Canvas), typeof(CanvasGroup));
rootCanvasGO.transform.SetParent(rootGO.transform);
var nestedCanvas = new GameObject("Nested Canvas", typeof(Canvas), typeof(Image));
nestedCanvas.transform.SetParent(rootCanvasGO.transform);
var nestedCanvasCamera = new GameObject("Nested Canvas Camera", typeof(Camera));
nestedCanvasCamera.transform.SetParent(rootCanvasGO.transform);
var rootCanvas = rootCanvasGO.GetComponent<Canvas>();
rootCanvas.renderMode = RenderMode.WorldSpace;
rootCanvas.worldCamera = nestedCanvasCamera.GetComponent<Camera>();
if (!Directory.Exists("Assets/Resources/"))
Directory.CreateDirectory("Assets/Resources/");
UnityEditor.PrefabUtility.SaveAsPrefabAsset(rootGO, kPrefabPath);
GameObject.DestroyImmediate(rootGO);
#endif
}
[UnityTest]
[Description("[UI] Button does not interact after nested canvas is used(case 892913)")]
public IEnumerator WorldCanvas_CanFindCameraAfterDisablingAndEnablingRootCanvas()
{
m_GO1 = Object.Instantiate(Resources.Load("NestedCanvasPrefab"));
yield return null;
var nestedCanvasGo = GameObject.Find("Nested Canvas");
var nestedCanvas = nestedCanvasGo.GetComponent<Canvas>();
Assert.IsNotNull(nestedCanvas.worldCamera, "Expected the nested canvas worldCamera to NOT be null after loading the scene.");
nestedCanvasGo.transform.parent.gameObject.SetActive(false);
nestedCanvasGo.transform.parent.gameObject.SetActive(true);
Assert.IsNotNull(nestedCanvas.worldCamera, "Expected the nested canvas worldCamera to NOT be null after the parent canvas has been re-enabled.");
}
[UnityTest]
public IEnumerator WorldCanvas_CanFindTheSameCameraAfterDisablingAndEnablingRootCanvas()
{
m_GO2 = Object.Instantiate(Resources.Load("NestedCanvasPrefab"));
yield return null;
var nestedCanvasGo = GameObject.Find("Nested Canvas");
var nestedCanvas = nestedCanvasGo.GetComponent<Canvas>();
var worldCamera = nestedCanvas.worldCamera;
nestedCanvasGo.transform.parent.gameObject.SetActive(false);
nestedCanvasGo.transform.parent.gameObject.SetActive(true);
Assert.AreEqual(worldCamera, nestedCanvas.worldCamera, "Expected the same world camera to be returned after the root canvas was disabled and then re-enabled.");
}
[UnityTest]
public IEnumerator NestedCanvasHasProperInheritedAlpha()
{
GameObject root = (GameObject)Object.Instantiate(Resources.Load("NestedCanvasPrefab"));
CanvasGroup group = root.GetComponentInChildren<CanvasGroup>();
Image image = root.GetComponentInChildren<Image>();
group.alpha = 0.5f;
yield return null;
Assert.True(image.canvasRenderer.GetInheritedAlpha() == 0.5f);
GameObject.DestroyImmediate(root);
}
[TearDown]
public void TearDown()
{
GameObject.DestroyImmediate(m_GO1);
GameObject.DestroyImmediate(m_GO2);
}
[OneTimeTearDown]
public void OneTimeTearDown()
{
#if UNITY_EDITOR
AssetDatabase.DeleteAsset(kPrefabPath);
#endif
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fc8d686a4c18b8d49bb1db4150de0459
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,57 @@
using UnityEngine;
using UnityEngine.TestTools;
using NUnit.Framework;
public class NestedCanvasMaintainsCorrectSize : IPrebuildSetup
{
BridgeScriptForRetainingObjects m_BridgeComponent;
public void Setup()
{
#if UNITY_EDITOR
var canvasGO = new GameObject("Canvas", typeof(Canvas));
canvasGO.GetComponent<Canvas>().renderMode = RenderMode.ScreenSpaceOverlay;
var nestedCanvasGO = new GameObject("NestedCanvas", typeof(Canvas));
nestedCanvasGO.transform.SetParent(canvasGO.transform);
var rectTransform = (RectTransform)nestedCanvasGO.transform;
rectTransform.anchorMin = Vector2.zero;
rectTransform.anchorMax = Vector2.one;
rectTransform.anchoredPosition = Vector2.zero;
rectTransform.sizeDelta = new Vector2(-20f, -20f);
var bridgeObject = GameObject.Find(BridgeScriptForRetainingObjects.bridgeObjectName) ?? new GameObject(BridgeScriptForRetainingObjects.bridgeObjectName);
var component = bridgeObject.GetComponent<BridgeScriptForRetainingObjects>() ?? bridgeObject.AddComponent<BridgeScriptForRetainingObjects>();
component.canvasGO = canvasGO;
component.nestedCanvasGO = nestedCanvasGO;
canvasGO.SetActive(false);
nestedCanvasGO.SetActive(false);
#endif
}
[SetUp]
public void TestSetup()
{
m_BridgeComponent = GameObject.Find(BridgeScriptForRetainingObjects.bridgeObjectName).GetComponent<BridgeScriptForRetainingObjects>();
m_BridgeComponent.canvasGO.SetActive(true);
m_BridgeComponent.nestedCanvasGO.SetActive(true);
}
[Test]
public void NestedCanvasMaintainsCorrectSizeAtGameStart()
{
var rectTransform = (RectTransform)m_BridgeComponent.nestedCanvasGO.transform;
Assert.That(rectTransform.anchoredPosition, Is.EqualTo(Vector2.zero));
Assert.That(rectTransform.sizeDelta, Is.EqualTo(new Vector2(-20f, -20f)));
Assert.That(rectTransform.anchorMin, Is.EqualTo(Vector2.zero));
Assert.That(rectTransform.anchorMax, Is.EqualTo(Vector2.one));
}
[TearDown]
public void TearDown()
{
GameObject.DestroyImmediate(m_BridgeComponent.canvasGO);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: be07f70ee67e6d74e851a9333719bbb6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,61 @@
using System;
using UnityEngine;
using UnityEngine.TestTools;
using NUnit.Framework;
using System.Collections;
using UnityEngine.Profiling;
using UnityEngine.SceneManagement;
using UnityEditor;
[TestFixture]
[UnityPlatform(include = new RuntimePlatform[] { RuntimePlatform.OSXEditor, RuntimePlatform.LinuxEditor, RuntimePlatform.WindowsEditor })]
[Category("RegressionTest")]
[Description("CoveredBugID = 883807, CoveredBugDescription = \"Object::GetInstanceID crash when trying to switch canvas\"")]
public class NoActiveCameraInSceneDoesNotCrashEditor : IPrebuildSetup
{
Scene m_InitScene;
const string k_SceneName = "NoActiveCameraInSceneDoesNotCrashEditorScene";
public void Setup()
{
#if UNITY_EDITOR
Action codeToExecute = delegate()
{
UnityEditor.EditorApplication.ExecuteMenuItem("GameObject/UI/Legacy/Button");
};
CreateSceneUtility.CreateScene(k_SceneName, codeToExecute);
#endif
}
[SetUp]
public void TestSetup()
{
m_InitScene = SceneManager.GetActiveScene();
}
[UnityTest]
public IEnumerator EditorShouldNotCrashWithoutActiveCamera()
{
AsyncOperation operationResult = SceneManager.LoadSceneAsync(k_SceneName, LoadSceneMode.Additive);
yield return operationResult;
SceneManager.SetActiveScene(SceneManager.GetSceneByName(k_SceneName));
Profiler.enabled = true;
Camera.main.gameObject.SetActive(false);
yield return new WaitForSeconds(0.1f);
Assert.That(Profiler.enabled, Is.True, "Expected the profiler to be enabled. Unable to test if the profiler will crash the editor if it is not enabled.");
}
[TearDown]
public void TearDown()
{
SceneManager.SetActiveScene(m_InitScene);
SceneManager.UnloadSceneAsync(k_SceneName);
#if UNITY_EDITOR
AssetDatabase.DeleteAsset("Assets/" + k_SceneName + ".unity");
#endif
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9c21cfda3336137438c3001d40564be0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,47 @@
using NUnit.Framework;
using UnityEngine;
using UnityEngine.UI;
namespace Graphics
{
[Category("RegressionTest")]
[Description("CoveredBugID = 1395695, CoveredBugDescription = \"RectMask2D hides all content when parented from other display to first dislpay in the Game view window\"")]
public class RectMask2DReparentedToDifferentCanvas
{
GameObject m_GameObjectA;
GameObject m_GameObjectB;
Canvas m_CanvasA;
Canvas m_CanvasB;
RectMask2D m_Mask;
[SetUp]
public void TestSetup()
{
m_GameObjectA = new GameObject("Canvas A");
m_GameObjectB = new GameObject("Canvas B");
m_CanvasA = m_GameObjectA.AddComponent<Canvas>();
m_CanvasB = m_GameObjectB.AddComponent<Canvas>();
var rectMaskGameObject = new GameObject("RectMask2D");
m_Mask = rectMaskGameObject.AddComponent<RectMask2D>();
}
[TearDown]
public void TearDown()
{
Object.DestroyImmediate(m_Mask.gameObject);
Object.DestroyImmediate(m_GameObjectA);
Object.DestroyImmediate(m_GameObjectB);
}
[Test]
public void ReparentingRectMask2D_UpdatesCanvas()
{
m_Mask.transform.SetParent(m_GameObjectA.transform);
Assert.AreSame(m_CanvasA, m_Mask.Canvas);
m_Mask.transform.SetParent(m_GameObjectB.transform);
Assert.AreSame(m_CanvasB, m_Mask.Canvas, "Expected Canvas to be updated after parent changed.");
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2ba506934dc2ce14591a37f3b00dca92
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,63 @@
using UnityEngine;
using UnityEngine.TestTools;
using NUnit.Framework;
using System.Collections;
using UnityEngine.UI;
namespace Graphics
{
[TestFixture]
[Category("RegressionTest")]
[Description(
"CoveredBugID = 782957, CoveredBugDescription = \"Some element from scroll view are invisible when they're masked with RectMask2D and sub-canvases\"")]
public class RectMask2DWithNestedCanvasCullsUsingCorrectCanvasRect
{
GameObject m_RootCanvasGO;
GameObject m_MaskGO;
GameObject m_ImageGO;
[SetUp]
public void TestSetup()
{
m_RootCanvasGO = new GameObject("Canvas");
m_MaskGO = new GameObject("Mask", typeof(RectMask2D));
m_ImageGO = new GameObject("Image");
}
[UnityTest]
public IEnumerator RectMask2DShouldNotCullImagesWithCanvas()
{
//Root Canvas
var canvas = m_RootCanvasGO.AddComponent<Canvas>();
canvas.renderMode = RenderMode.ScreenSpaceOverlay;
// Rectmaskk2D
var maskRect = m_MaskGO.GetComponent<RectTransform>();
maskRect.sizeDelta = new Vector2(200, 200);
// Our image that will be in the RectMask2D
var image = m_ImageGO.AddComponent<Image>();
var imageRenderer = m_ImageGO.GetComponent<CanvasRenderer>();
var imageRect = m_ImageGO.GetComponent<RectTransform>();
m_ImageGO.AddComponent<Canvas>();
imageRect.sizeDelta = new Vector2(10, 10);
m_MaskGO.transform.SetParent(canvas.transform);
image.transform.SetParent(m_MaskGO.transform);
imageRect.position = maskRect.position = Vector3.zero;
yield return new WaitForSeconds(0.1f);
Assert.That(imageRenderer.cull, Is.False,
"Expected image(with canvas) to not be culled by the RectMask2D but it was.");
}
[TearDown]
public void TearDown()
{
GameObject.DestroyImmediate(m_RootCanvasGO);
GameObject.DestroyImmediate(m_MaskGO);
GameObject.DestroyImmediate(m_ImageGO);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 735d54f21944f834f931716514c87a84
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,73 @@
using System;
using System.Collections;
using UnityEngine;
using UnityEngine.TestTools;
using NUnit.Framework;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using UnityEditor;
[TestFixture]
public class RectTransformValidAfterEnable : IPrebuildSetup
{
const string kSceneName = "DisabledCanvasScene";
const string kGameObjectName = "DisabledCanvas";
public void Setup()
{
#if UNITY_EDITOR
Action codeToExecute = delegate()
{
var canvasGameObject = new GameObject(kGameObjectName, typeof(Canvas));
canvasGameObject.SetActive(false);
canvasGameObject.GetComponent<Canvas>().renderMode = RenderMode.ScreenSpaceOverlay;
canvasGameObject.GetComponent<RectTransform>().sizeDelta = new Vector2(0, 0);
canvasGameObject.GetComponent<RectTransform>().anchoredPosition = new Vector2(0, 0);
CanvasScaler canvasScaler = canvasGameObject.AddComponent<CanvasScaler>();
canvasScaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize;
canvasScaler.referenceResolution = new Vector2(1024, 768);
};
CreateSceneUtility.CreateScene(kSceneName, codeToExecute);
#endif
}
[UnityTest]
public IEnumerator CheckRectTransformValidAfterEnable()
{
AsyncOperation operation = SceneManager.LoadSceneAsync(kSceneName, LoadSceneMode.Additive);
yield return operation;
Scene scene = SceneManager.GetSceneByName(kSceneName);
GameObject[] gameObjects = scene.GetRootGameObjects();
GameObject canvasGameObject = null;
foreach (GameObject gameObject in gameObjects)
{
if (gameObject.name == kGameObjectName)
{
canvasGameObject = gameObject;
break;
}
}
Assert.IsNotNull(canvasGameObject);
RectTransform rectTransform = canvasGameObject.GetComponent<RectTransform>();
canvasGameObject.SetActive(true);
yield return new WaitForEndOfFrame();
Rect rect = rectTransform.rect;
Assert.Greater(rect.width, 0);
Assert.Greater(rect.height, 0);
operation = SceneManager.UnloadSceneAsync(kSceneName);
yield return operation;
}
[TearDown]
public void TearDown()
{
//Manually add Assets/ and .unity as CreateSceneUtility does that for you.
#if UNITY_EDITOR
AssetDatabase.DeleteAsset("Assets/" + kSceneName + ".unity");
#endif
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 811d999912a5f3f459a637aad029fbc8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,83 @@
using UnityEngine;
using UnityEngine.TestTools;
using NUnit.Framework;
using System.Collections;
using UnityEngine.UI;
[TestFixture]
[Category("RegressionTest")]
[Description("Case 723062")]
public class SiblingOrderChangesLayout
{
GameObject m_CanvasGO;
GameObject m_ParentGO;
GameObject m_Child1GO;
GameObject m_Child2GO;
[SetUp]
public void TestSetup()
{
m_CanvasGO = new GameObject("Canvas", typeof(Canvas));
m_ParentGO = new GameObject("ParentRenderer");
m_Child1GO = CreateTextObject("ChildRenderer1");
m_Child2GO = CreateTextObject("ChildRenderer2");
#if UNITY_EDITOR
UnityEditor.EditorApplication.ExecuteMenuItem("Window/General/Game");
#endif
}
[UnityTest]
public IEnumerator ReorderingSiblingChangesLayout()
{
m_ParentGO.transform.SetParent(m_CanvasGO.transform);
m_Child1GO.transform.SetParent(m_ParentGO.transform);
m_Child2GO.transform.SetParent(m_ParentGO.transform);
m_ParentGO.AddComponent<CanvasRenderer>();
m_ParentGO.AddComponent<RectTransform>();
m_ParentGO.AddComponent<VerticalLayoutGroup>();
m_ParentGO.AddComponent<ContentSizeFitter>();
yield return new WaitForEndOfFrame();
Vector2 child1Pos = m_Child1GO.GetComponent<RectTransform>().anchoredPosition;
Vector2 child2Pos = m_Child2GO.GetComponent<RectTransform>().anchoredPosition;
Assert.That(child1Pos, Is.Not.EqualTo(child2Pos));
Assert.That(m_Child1GO.GetComponent<CanvasRenderer>().hasMoved, Is.False, "CanvasRenderer.hasMoved should be false");
m_Child2GO.transform.SetAsFirstSibling();
Canvas.ForceUpdateCanvases();
Assert.That(m_Child1GO.GetComponent<CanvasRenderer>().hasMoved, Is.True, "CanvasRenderer.hasMoved should be true");
Vector2 newChild1Pos = m_Child1GO.GetComponent<RectTransform>().anchoredPosition;
Vector2 newChild2Pos = m_Child2GO.GetComponent<RectTransform>().anchoredPosition;
Assert.That(newChild1Pos, Is.EqualTo(child2Pos), "Child1 should have moved to Child2's position");
Assert.That(newChild2Pos, Is.EqualTo(child1Pos), "Child2 should have moved to Child1's position");
}
[TearDown]
public void TearDown()
{
GameObject.DestroyImmediate(m_CanvasGO);
}
// Factory method for creating UI text objects taken from the original bug repro scene:
private GameObject CreateTextObject(string name)
{
GameObject outputTextGameObject = new GameObject("OutputContent", typeof(CanvasRenderer));
RectTransform outputTextTransform = outputTextGameObject.AddComponent<RectTransform>();
outputTextTransform.pivot = new Vector2(0.5f, 0);
outputTextTransform.anchorMin = Vector2.zero;
outputTextTransform.anchorMax = new Vector2(1, 0);
outputTextTransform.anchoredPosition = Vector2.zero;
outputTextTransform.sizeDelta = Vector2.zero;
Text outputText = outputTextGameObject.AddComponent<Text>();
outputText.text = "Hello World!";
outputTextGameObject.name = name;
return outputTextGameObject;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c32df609537c54c46adf92992a673693
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: bae197be297529d4fa735fbe7c91828d
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,162 @@
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.TestTools;
using NUnit.Framework;
using System.IO;
using UnityEditor;
using System.Collections.Generic;
public class DropdownTests : IPrebuildSetup
{
GameObject m_PrefabRoot;
GameObject m_CameraGO;
const string kPrefabPath = "Assets/Resources/DropdownPrefab.prefab";
public void Setup()
{
#if UNITY_EDITOR
var rootGO = new GameObject("rootGo");
var canvasGO = new GameObject("Canvas", typeof(Canvas));
var canvas = canvasGO.GetComponent<Canvas>();
canvas.renderMode = RenderMode.WorldSpace;
canvasGO.transform.SetParent(rootGO.transform);
var dropdownGO = new GameObject("Dropdown", typeof(RectTransform), typeof(Dropdown));
var dropdownTransform = dropdownGO.GetComponent<RectTransform>();
dropdownTransform.SetParent(canvas.transform);
dropdownTransform.anchoredPosition = Vector2.zero;
var dropdown = dropdownGO.GetComponent<Dropdown>();
var templateGO = new GameObject("Template", typeof(RectTransform));
templateGO.SetActive(false);
var templateTransform = templateGO.GetComponent<RectTransform>();
templateTransform.SetParent(dropdownTransform);
var itemGo = new GameObject("Item", typeof(RectTransform), typeof(Toggle));
itemGo.transform.SetParent(templateTransform);
dropdown.template = templateTransform;
if (!Directory.Exists("Assets/Resources/"))
Directory.CreateDirectory("Assets/Resources/");
PrefabUtility.SaveAsPrefabAsset(rootGO, kPrefabPath);
GameObject.DestroyImmediate(rootGO);
// add a custom sorting layer before test. It doesn't seem to be serialized so no need to remove it after test
SerializedObject tagManager = new SerializedObject(AssetDatabase.LoadAllAssetsAtPath("ProjectSettings/TagManager.asset")[0]);
SerializedProperty sortingLayers = tagManager.FindProperty("m_SortingLayers");
sortingLayers.InsertArrayElementAtIndex(sortingLayers.arraySize);
var arrayElement = sortingLayers.GetArrayElementAtIndex(sortingLayers.arraySize - 1);
foreach (SerializedProperty a in arrayElement)
{
switch (a.name)
{
case "name":
a.stringValue = "test layer";
break;
case "uniqueID":
a.intValue = 314159265;
break;
case "locked":
a.boolValue = false;
break;
}
}
tagManager.ApplyModifiedProperties();
#endif
}
[SetUp]
public void TestSetup()
{
m_PrefabRoot = Object.Instantiate(Resources.Load("DropdownPrefab")) as GameObject;
m_CameraGO = new GameObject("Camera", typeof(Camera));
}
// test for case 958281 - [UI] Dropdown list does not copy the parent canvas layer when the panel is opened
[UnityTest]
public IEnumerator Dropdown_Canvas()
{
var dropdown = m_PrefabRoot.GetComponentInChildren<Dropdown>();
var rootCanvas = m_PrefabRoot.GetComponentInChildren<Canvas>();
rootCanvas.sortingLayerName = "test layer";
dropdown.Show();
yield return null;
var dropdownList = dropdown.transform.Find("Dropdown List");
var dropdownListCanvas = dropdownList.GetComponentInChildren<Canvas>();
Assert.AreEqual(rootCanvas.sortingLayerID, dropdownListCanvas.sortingLayerID, "Sorting layers should match");
}
// test for case 1343542 - [UI] Child Canvas' Sorting Layer is changed to the same value as the parent
[UnityTest]
public IEnumerator Dropdown_Canvas_Already_Exists()
{
var dropdown = m_PrefabRoot.GetComponentInChildren<Dropdown>();
var rootCanvas = m_PrefabRoot.GetComponentInChildren<Canvas>();
var templateCanvas = dropdown.transform.Find("Template").gameObject.AddComponent<Canvas>();
templateCanvas.overrideSorting = true;
templateCanvas.sortingLayerName = "test layer";
dropdown.Show();
yield return null;
var dropdownList = dropdown.transform.Find("Dropdown List");
var dropdownListCanvas = dropdownList.GetComponentInChildren<Canvas>();
Assert.AreNotEqual(rootCanvas.sortingLayerName, dropdownListCanvas.sortingLayerName, "Sorting layers should not match");
}
// test for case 935649 - open dropdown menus become unresponsive when disabled and reenabled
[UnityTest]
public IEnumerator Dropdown_Disable()
{
var dropdown = m_PrefabRoot.GetComponentInChildren<Dropdown>();
dropdown.Show();
dropdown.gameObject.SetActive(false);
yield return null;
var dropdownList = dropdown.transform.Find("Dropdown List");
Assert.IsNull(dropdownList);
}
[UnityTest]
public IEnumerator Dropdown_ResetAndClear()
{
var options = new List<string> { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10" };
var dropdown = m_PrefabRoot.GetComponentInChildren<Dropdown>();
// generate a first dropdown
dropdown.ClearOptions();
dropdown.AddOptions(options);
dropdown.value = 3;
yield return null;
// clear it and generate a new one
dropdown.ClearOptions();
yield return null;
// check is the value is 0
Assert.IsTrue(dropdown.value == 0);
}
[TearDown]
public void TearDown()
{
Object.DestroyImmediate(m_PrefabRoot);
GameObject.DestroyImmediate(m_CameraGO);
}
[OneTimeTearDown]
public void OneTimeTearDown()
{
#if UNITY_EDITOR
AssetDatabase.DeleteAsset(kPrefabPath);
SerializedObject tagManager = new SerializedObject(AssetDatabase.LoadAllAssetsAtPath("ProjectSettings/TagManager.asset")[0]);
SerializedProperty sortingLayers = tagManager.FindProperty("m_SortingLayers");
sortingLayers.DeleteArrayElementAtIndex(sortingLayers.arraySize);
tagManager.ApplyModifiedProperties();
#endif
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 358a618bc6bd9354d81cc206fd2ed80e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: ab93e1a81defc3243a6e9cd0df3cb443
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,151 @@
using System.Collections;
using System.Collections.Generic;
using NUnit.Framework;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.TestTools;
using UnityEngine.UI;
using UnityEngine.TestTools.Utils;
public class GraphicRaycasterTests
{
Camera m_Camera;
EventSystem m_EventSystem;
Canvas m_Canvas;
RectTransform m_CanvasRectTrans;
Text m_TextComponent;
[SetUp]
public void TestSetup()
{
m_Camera = new GameObject("GraphicRaycaster Camera").AddComponent<Camera>();
m_Camera.transform.position = Vector3.zero;
m_Camera.transform.LookAt(Vector3.forward);
m_Camera.farClipPlane = 10;
m_EventSystem = new GameObject("Event System").AddComponent<EventSystem>();
m_Canvas = new GameObject("Canvas").AddComponent<Canvas>();
m_Canvas.renderMode = RenderMode.WorldSpace;
m_Canvas.worldCamera = m_Camera;
m_Canvas.gameObject.AddComponent<GraphicRaycaster>();
m_CanvasRectTrans = m_Canvas.GetComponent<RectTransform>();
m_CanvasRectTrans.sizeDelta = new Vector2(100, 100);
var textGO = new GameObject("Text");
m_TextComponent = textGO.AddComponent<Text>();
var textRectTrans = m_TextComponent.rectTransform;
textRectTrans.SetParent(m_Canvas.transform);
textRectTrans.anchorMin = Vector2.zero;
textRectTrans.anchorMax = Vector2.one;
textRectTrans.offsetMin = Vector2.zero;
textRectTrans.offsetMax = Vector2.zero;
}
[UnityTest]
public IEnumerator GraphicRaycasterDoesNotHitGraphicBehindCameraFarClipPlane()
{
m_CanvasRectTrans.anchoredPosition3D = new Vector3(0, 0, 11);
yield return null;
var results = new List<RaycastResult>();
var pointerEvent = new PointerEventData(m_EventSystem)
{
position = new Vector2(Screen.width / 2f, Screen.height / 2f)
};
m_EventSystem.RaycastAll(pointerEvent, results);
Assert.IsEmpty(results, "Expected no results from a raycast against a graphic behind the camera's far clip plane.");
}
[UnityTest]
public IEnumerator GraphicRaycasterReturnsWorldPositionAndWorldNormal()
{
m_CanvasRectTrans.anchoredPosition3D = new Vector3(0, 0, 11);
m_Camera.farClipPlane = 12;
yield return null;
var results = new List<RaycastResult>();
var pointerEvent = new PointerEventData(m_EventSystem)
{
position = new Vector2(Screen.width / 2f, Screen.height / 2f)
};
m_EventSystem.RaycastAll(pointerEvent, results);
// on katana on 10.13 agents world position returned is 0, -0.00952, 11
// it does not reproduce for me localy, so we just tweak the comparison threshold
Assert.That(new Vector3(0, 0, 11), Is.EqualTo(results[0].worldPosition).Using(new Vector3EqualityComparer(0.01f)));
Assert.That(new Vector3(0, 0, -1), Is.EqualTo(results[0].worldNormal).Using(new Vector3EqualityComparer(0.001f)));
}
[UnityTest]
public IEnumerator GraphicRaycasterUsesGraphicPadding()
{
m_CanvasRectTrans.anchoredPosition3D = new Vector3(0, 0, 11);
m_TextComponent.raycastPadding = new Vector4(-50, -50, -50, -50);
m_Camera.farClipPlane = 12;
yield return null;
var results = new List<RaycastResult>();
var pointerEvent = new PointerEventData(m_EventSystem)
{
position = new Vector2((Screen.width / 2f) - 60, Screen.height / 2f)
};
m_EventSystem.RaycastAll(pointerEvent, results);
Assert.IsNotEmpty(results, "Expected at least 1 result from a raycast outside the graphics RectTransform whose padding would make the click hit.");
}
[UnityTest]
public IEnumerator GraphicOnTheSamePlaneAsTheCameraCanBeTargetedForEvents()
{
m_Canvas.renderMode = RenderMode.ScreenSpaceCamera;
m_Canvas.planeDistance = 0;
m_Camera.orthographic = true;
m_Camera.orthographicSize = 1;
m_Camera.nearClipPlane = 0;
m_Camera.farClipPlane = 12;
yield return null;
var results = new List<RaycastResult>();
var pointerEvent = new PointerEventData(m_EventSystem)
{
position = new Vector2((Screen.width / 2f), Screen.height / 2f)
};
m_EventSystem.RaycastAll(pointerEvent, results);
Assert.IsNotEmpty(results, "Expected at least 1 result from a raycast ");
}
#if ENABLE_INPUT_SYSTEM
[UnityTest]
public IEnumerator GraphicRaycasterIgnoresEventsFromTheWrongDisplay()
{
m_CanvasRectTrans.anchoredPosition3D = new Vector3(0, 0, 11);
m_Camera.farClipPlane = 12;
yield return null;
var results = new List<RaycastResult>();
var pointerEvent = new PointerEventData(m_EventSystem)
{
position = new Vector2(Screen.width / 2f, Screen.height / 2f),
displayIndex = 1,
};
m_EventSystem.RaycastAll(pointerEvent, results);
Assert.IsEmpty(results, "Pointer event on display 1 was not ignored on display 0");
}
#endif
[TearDown]
public void TearDown()
{
Object.DestroyImmediate(m_Camera.gameObject);
Object.DestroyImmediate(m_EventSystem.gameObject);
Object.DestroyImmediate(m_Canvas.gameObject);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e6323ebef616fee4486ee155cd56d191
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,88 @@
using System.Collections;
using System.Collections.Generic;
using NUnit.Framework;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.TestTools;
using UnityEngine.UI;
using UnityEngine.TestTools.Utils;
public class GraphicRaycasterWorldSpaceCanvasTests
{
Camera m_Camera;
EventSystem m_EventSystem;
Canvas m_Canvas;
RectTransform m_CanvasRectTrans;
[SetUp]
public void TestSetup()
{
m_Camera = new GameObject("GraphicRaycaster Camera").AddComponent<Camera>();
m_Camera.transform.position = Vector3.zero;
m_Camera.transform.LookAt(Vector3.forward);
m_Camera.farClipPlane = 10;
m_EventSystem = new GameObject("Event System").AddComponent<EventSystem>();
m_Canvas = new GameObject("Canvas").AddComponent<Canvas>();
m_Canvas.renderMode = RenderMode.WorldSpace;
m_Canvas.worldCamera = m_Camera;
m_Canvas.gameObject.AddComponent<GraphicRaycaster>();
m_CanvasRectTrans = m_Canvas.GetComponent<RectTransform>();
m_CanvasRectTrans.sizeDelta = new Vector2(100, 100);
var textRectTrans = new GameObject("Text").AddComponent<Text>().rectTransform;
textRectTrans.SetParent(m_Canvas.transform);
textRectTrans.anchorMin = Vector2.zero;
textRectTrans.anchorMax = Vector2.one;
textRectTrans.offsetMin = Vector2.zero;
textRectTrans.offsetMax = Vector2.zero;
}
[UnityTest]
public IEnumerator GraphicRaycasterDoesNotHitGraphicBehindCameraFarClipPlane()
{
m_CanvasRectTrans.anchoredPosition3D = new Vector3(0, 0, 11);
yield return null;
var results = new List<RaycastResult>();
var pointerEvent = new PointerEventData(m_EventSystem)
{
position = new Vector2(Screen.width / 2f, Screen.height / 2f)
};
m_EventSystem.RaycastAll(pointerEvent, results);
Assert.IsEmpty(results, "Expected no results from a raycast against a graphic behind the camera's far clip plane.");
}
[UnityTest]
public IEnumerator GraphicRaycasterReturnsWorldPositionAndWorldNormal()
{
m_CanvasRectTrans.anchoredPosition3D = new Vector3(0, 0, 11);
m_Camera.farClipPlane = 12;
yield return null;
var results = new List<RaycastResult>();
var pointerEvent = new PointerEventData(m_EventSystem)
{
position = new Vector2(Screen.width / 2f, Screen.height / 2f)
};
m_EventSystem.RaycastAll(pointerEvent, results);
// on katana on 10.13 agents world position returned is 0, -0.00952, 11
// it does not reproduce for me localy, so we just tweak the comparison threshold
Assert.That(new Vector3(0, 0, 11), Is.EqualTo(results[0].worldPosition).Using(new Vector3EqualityComparer(0.01f)));
Assert.That(new Vector3(0, 0, -1), Is.EqualTo(results[0].worldNormal).Using(new Vector3EqualityComparer(0.001f)));
}
[TearDown]
public void TearDown()
{
Object.DestroyImmediate(m_Camera.gameObject);
Object.DestroyImmediate(m_EventSystem.gameObject);
Object.DestroyImmediate(m_Canvas.gameObject);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3d42c4854f9093e409cd90c00ef26de0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,259 @@
using System.Collections;
using NUnit.Framework;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.TestTools;
using UnityEngine.UI;
public class InputModuleTests
{
EventSystem m_EventSystem;
FakeBaseInput m_FakeBaseInput;
StandaloneInputModule m_StandaloneInputModule;
Canvas m_Canvas;
Image m_Image;
Image m_NestedImage;
[SetUp]
public void TestSetup()
{
// Camera | Canvas (Image) | Event System
m_Canvas = new GameObject("Canvas").AddComponent<Canvas>();
m_Canvas.renderMode = RenderMode.ScreenSpaceOverlay;
m_Canvas.gameObject.AddComponent<GraphicRaycaster>();
m_Image = new GameObject("Image").AddComponent<Image>();
m_Image.gameObject.transform.SetParent(m_Canvas.transform);
RectTransform imageRectTransform = m_Image.GetComponent<RectTransform>();
imageRectTransform.sizeDelta = new Vector2(400f, 400f);
imageRectTransform.localPosition = Vector3.zero;
m_NestedImage = new GameObject("NestedImage").AddComponent<Image>();
m_NestedImage.gameObject.transform.SetParent(m_Image.transform);
RectTransform nestedImageRectTransform = m_NestedImage.GetComponent<RectTransform>();
nestedImageRectTransform.sizeDelta = new Vector2(200f, 200f);
nestedImageRectTransform.localPosition = Vector3.zero;
GameObject go = new GameObject("Event System");
m_EventSystem = go.AddComponent<EventSystem>();
m_EventSystem.pixelDragThreshold = 1;
m_StandaloneInputModule = go.AddComponent<StandaloneInputModule>();
m_FakeBaseInput = go.AddComponent<FakeBaseInput>();
// Override input with FakeBaseInput so we can send fake mouse/keyboards button presses and touches
m_StandaloneInputModule.inputOverride = m_FakeBaseInput;
Cursor.lockState = CursorLockMode.None;
}
[UnityTest]
public IEnumerator DragCallbacksDoGetCalled()
{
// While left mouse button is pressed and the mouse is moving, OnBeginDrag and OnDrag callbacks should be called
// Then when the left mouse button is released, OnEndDrag callback should be called
// Add script to EventSystem to update the mouse position
m_EventSystem.gameObject.AddComponent<MouseUpdate>();
// Add script to Image which implements OnBeginDrag, OnDrag & OnEndDrag callbacks
DragCallbackCheck callbackCheck = m_Image.gameObject.AddComponent<DragCallbackCheck>();
// Setting required input.mousePresent to fake mouse presence
m_FakeBaseInput.MousePresent = true;
var canvasRT = m_Canvas.gameObject.transform as RectTransform;
m_FakeBaseInput.MousePosition = new Vector2(Screen.width / 2, Screen.height / 2);
yield return null;
// Left mouse button down simulation
m_FakeBaseInput.MouseButtonDown[0] = true;
yield return null;
// Left mouse button down flag needs to reset in the next frame
m_FakeBaseInput.MouseButtonDown[0] = false;
yield return null;
// Left mouse button up simulation
m_FakeBaseInput.MouseButtonUp[0] = true;
yield return null;
// Left mouse button up flag needs to reset in the next frame
m_FakeBaseInput.MouseButtonUp[0] = false;
yield return null;
Assert.IsTrue(callbackCheck.onBeginDragCalled, "OnBeginDrag not called");
Assert.IsTrue(callbackCheck.onDragCalled, "OnDragCalled not called");
Assert.IsTrue(callbackCheck.onEndDragCalled, "OnEndDragCalled not called");
Assert.IsTrue(callbackCheck.onDropCalled, "OnDrop not called");
}
[UnityTest]
public IEnumerator MouseOutsideMaskRectTransform_WhileInsidePaddedArea_PerformsClick()
{
var mask = new GameObject("Panel").AddComponent<RectMask2D>();
mask.gameObject.transform.SetParent(m_Canvas.transform);
RectTransform panelRectTransform = mask.GetComponent<RectTransform>();
panelRectTransform.sizeDelta = new Vector2(100, 100f);
panelRectTransform.localPosition = Vector3.zero;
m_Image.gameObject.transform.SetParent(mask.transform, true);
mask.padding = new Vector4(-30, -30, -30, -30);
PointerClickCallbackCheck callbackCheck = m_Image.gameObject.AddComponent<PointerClickCallbackCheck>();
var canvasRT = m_Canvas.gameObject.transform as RectTransform;
var screenMiddle = new Vector2(Screen.width / 2, Screen.height / 2);
m_FakeBaseInput.MousePresent = true;
m_FakeBaseInput.MousePosition = screenMiddle;
yield return null;
// Click the center of the screen should hit the middle of the image.
m_FakeBaseInput.MouseButtonDown[0] = true;
yield return null;
m_FakeBaseInput.MouseButtonDown[0] = false;
yield return null;
m_FakeBaseInput.MouseButtonUp[0] = true;
yield return null;
m_FakeBaseInput.MouseButtonUp[0] = false;
yield return null;
Assert.IsTrue(callbackCheck.pointerDown);
//Reset the callbackcheck and click outside the mask but still in the image.
callbackCheck.pointerDown = false;
m_FakeBaseInput.MousePosition = new Vector2(screenMiddle.x - 60, screenMiddle.y);
yield return null;
m_FakeBaseInput.MouseButtonDown[0] = true;
yield return null;
m_FakeBaseInput.MouseButtonDown[0] = false;
yield return null;
m_FakeBaseInput.MouseButtonUp[0] = true;
yield return null;
m_FakeBaseInput.MouseButtonUp[0] = false;
yield return null;
Assert.IsTrue(callbackCheck.pointerDown);
//Reset the callbackcheck and click outside the mask and outside in the image.
callbackCheck.pointerDown = false;
m_FakeBaseInput.MousePosition = new Vector2(screenMiddle.x - 100, screenMiddle.y);
yield return null;
m_FakeBaseInput.MouseButtonDown[0] = true;
yield return null;
m_FakeBaseInput.MouseButtonDown[0] = false;
yield return null;
m_FakeBaseInput.MouseButtonUp[0] = true;
yield return null;
m_FakeBaseInput.MouseButtonUp[0] = false;
yield return null;
Assert.IsFalse(callbackCheck.pointerDown);
}
[UnityTest]
public IEnumerator PointerEnterChildShouldNotFullyExit_NotSendPointerEventToParent()
{
m_StandaloneInputModule.sendPointerHoverToParent = false;
PointerExitCallbackCheck callbackCheck = m_Image.gameObject.AddComponent<PointerExitCallbackCheck>();
m_NestedImage.gameObject.AddComponent<PointerExitCallbackCheck>();
var screenMiddle = new Vector2(Screen.width / 2, Screen.height / 2);
m_FakeBaseInput.MousePresent = true;
m_FakeBaseInput.MousePosition = screenMiddle - new Vector2(150, 150);
yield return null;
m_FakeBaseInput.MousePosition = screenMiddle;
yield return null;
Assert.IsTrue(callbackCheck.pointerData.fullyExited == false);
}
[UnityTest]
public IEnumerator PointerEnterChildShouldNotExit_SendPointerEventToParent()
{
m_StandaloneInputModule.sendPointerHoverToParent = true;
PointerExitCallbackCheck callbackCheck = m_Image.gameObject.AddComponent<PointerExitCallbackCheck>();
m_NestedImage.gameObject.AddComponent<PointerExitCallbackCheck>();
var screenMiddle = new Vector2(Screen.width / 2, Screen.height / 2);
m_FakeBaseInput.MousePresent = true;
m_FakeBaseInput.MousePosition = screenMiddle - new Vector2(150, 150);
yield return null;
m_FakeBaseInput.MousePosition = screenMiddle;
yield return null;
Assert.IsTrue(callbackCheck.pointerData == null);
}
[UnityTest]
public IEnumerator PointerEnterChildShouldNotReenter()
{
PointerEnterCallbackCheck callbackCheck = m_NestedImage.gameObject.AddComponent<PointerEnterCallbackCheck>();
var screenMiddle = new Vector2(Screen.width / 2, Screen.height / 2);
m_FakeBaseInput.MousePresent = true;
m_FakeBaseInput.MousePosition = screenMiddle - new Vector2(150, 150);
yield return null;
m_FakeBaseInput.MousePosition = screenMiddle;
yield return null;
Assert.IsTrue(callbackCheck.pointerData.reentered == false);
}
[UnityTest]
public IEnumerator PointerExitChildShouldReenter_NotSendPointerEventToParent()
{
m_StandaloneInputModule.sendPointerHoverToParent = false;
PointerEnterCallbackCheck callbackCheck = m_Image.gameObject.AddComponent<PointerEnterCallbackCheck>();
var screenMiddle = new Vector2(Screen.width / 2, Screen.height / 2);
m_FakeBaseInput.MousePresent = true;
m_FakeBaseInput.MousePosition = screenMiddle - new Vector2(150, 150);
yield return null;
m_FakeBaseInput.MousePosition = screenMiddle;
yield return null;
m_FakeBaseInput.MousePosition = screenMiddle - new Vector2(150, 150);
yield return null;
Assert.IsTrue(callbackCheck.pointerData.reentered == true);
}
[UnityTest]
public IEnumerator PointerExitChildShouldNotSendEnter_SendPointerEventToParent()
{
m_StandaloneInputModule.sendPointerHoverToParent = true;
m_NestedImage.gameObject.AddComponent<PointerEnterCallbackCheck>();
var screenMiddle = new Vector2(Screen.width / 2, Screen.height / 2);
m_FakeBaseInput.MousePresent = true;
m_FakeBaseInput.MousePosition = screenMiddle;
yield return null;
PointerEnterCallbackCheck callbackCheck = m_Image.gameObject.AddComponent<PointerEnterCallbackCheck>();
m_FakeBaseInput.MousePosition = screenMiddle - new Vector2(150, 150);
yield return null;
Assert.IsTrue(callbackCheck.pointerData == null);
}
[UnityTest]
public IEnumerator PointerExitChildShouldFullyExit()
{
PointerExitCallbackCheck callbackCheck = m_NestedImage.gameObject.AddComponent<PointerExitCallbackCheck>();
var screenMiddle = new Vector2(Screen.width / 2, Screen.height / 2);
m_FakeBaseInput.MousePresent = true;
m_FakeBaseInput.MousePosition = screenMiddle - new Vector2(150, 150);
yield return null;
m_FakeBaseInput.MousePosition = screenMiddle;
yield return null;
m_FakeBaseInput.MousePosition = screenMiddle - new Vector2(150, 150);
yield return null;
Assert.IsTrue(callbackCheck.pointerData.fullyExited == true);
}
[TearDown]
public void TearDown()
{
GameObject.DestroyImmediate(m_EventSystem.gameObject);
GameObject.DestroyImmediate(m_Canvas.gameObject);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e4e290d31ab7fb54880746bb8f818e0d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 7a892c920c8ad2848b469ec9579c5219
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,40 @@
using UnityEngine;
using UnityEngine.EventSystems;
public class DragCallbackCheck : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler, IDropHandler, IPointerDownHandler
{
private bool loggedOnDrag = false;
public bool onBeginDragCalled = false;
public bool onDragCalled = false;
public bool onEndDragCalled = false;
public bool onDropCalled = false;
public void OnBeginDrag(PointerEventData eventData)
{
onBeginDragCalled = true;
}
public void OnDrag(PointerEventData eventData)
{
if (loggedOnDrag)
return;
loggedOnDrag = true;
onDragCalled = true;
}
public void OnEndDrag(PointerEventData eventData)
{
onEndDragCalled = true;
}
public void OnDrop(PointerEventData eventData)
{
onDropCalled = true;
}
public void OnPointerDown(PointerEventData eventData)
{
// Empty to ensure we get the drop if we have a pointer handle as well.
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 76c82729ad712f14bae1a8a279c52ac3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,117 @@
using System;
using UnityEngine;
using UnityEngine.EventSystems;
public class FakeBaseInput : BaseInput
{
[NonSerialized]
public String CompositionString = "";
private IMECompositionMode m_ImeCompositionMode = IMECompositionMode.Auto;
private Vector2 m_CompositionCursorPos = Vector2.zero;
[NonSerialized]
public bool MousePresent = false;
[NonSerialized]
public bool[] MouseButtonDown = new bool[3];
[NonSerialized]
public bool[] MouseButtonUp = new bool[3];
[NonSerialized]
public bool[] MouseButton = new bool[3];
[NonSerialized]
public Vector2 MousePosition = Vector2.zero;
[NonSerialized]
public Vector2 MouseScrollDelta = Vector2.zero;
[NonSerialized]
public bool TouchSupported = false;
[NonSerialized]
public int TouchCount = 0;
[NonSerialized]
public Touch TouchData;
[NonSerialized]
public float AxisRaw = 0f;
[NonSerialized]
public bool ButtonDown = false;
public override string compositionString
{
get { return CompositionString; }
}
public override IMECompositionMode imeCompositionMode
{
get { return m_ImeCompositionMode; }
set { m_ImeCompositionMode = value; }
}
public override Vector2 compositionCursorPos
{
get { return m_CompositionCursorPos; }
set { m_CompositionCursorPos = value; }
}
public override bool mousePresent
{
get { return MousePresent; }
}
public override bool GetMouseButtonDown(int button)
{
return MouseButtonDown[button];
}
public override bool GetMouseButtonUp(int button)
{
return MouseButtonUp[button];
}
public override bool GetMouseButton(int button)
{
return MouseButton[button];
}
public override Vector2 mousePosition
{
get { return MousePosition; }
}
public override Vector2 mouseScrollDelta
{
get { return MouseScrollDelta; }
}
public override bool touchSupported
{
get { return TouchSupported; }
}
public override int touchCount
{
get { return TouchCount; }
}
public override Touch GetTouch(int index)
{
return TouchData;
}
public override float GetAxisRaw(string axisName)
{
return AxisRaw;
}
public override bool GetButtonDown(string buttonName)
{
return ButtonDown;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 138dbec4f8742654fbceb0a19d68b9c5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,20 @@
using UnityEngine;
public class MouseUpdate : MonoBehaviour
{
FakeBaseInput m_FakeBaseInput;
void Awake()
{
m_FakeBaseInput = GetComponent<FakeBaseInput>();
}
void Update()
{
Debug.Assert(m_FakeBaseInput, "FakeBaseInput component has not been added to the EventSystem");
// Update mouse position
m_FakeBaseInput.MousePosition.x += 10f;
m_FakeBaseInput.MousePosition.y += 10f;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 19c6f364c1e81cb4f829a057824639ad
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,13 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class PointerClickCallbackCheck : MonoBehaviour, IPointerDownHandler
{
public bool pointerDown = false;
public void OnPointerDown(PointerEventData eventData)
{
pointerDown = true;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0573713975c6b8246b7544ed524ef1dc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,13 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class PointerEnterCallbackCheck : MonoBehaviour, IPointerEnterHandler
{
public PointerEventData pointerData { get; private set; }
public void OnPointerEnter(PointerEventData eventData)
{
pointerData = eventData;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: eb4fb871430ff484e9ee3850946c504d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,13 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class PointerExitCallbackCheck : MonoBehaviour, IPointerExitHandler
{
public PointerEventData pointerData { get; private set; }
public void OnPointerExit(PointerEventData eventData)
{
pointerData = eventData;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: af94bd3a805f27e42ab86647265be74e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,118 @@
using NUnit.Framework;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Rendering;
public class Physics2DRaycasterTests
{
GameObject m_CamGO;
SpriteRenderer m_RedSprite;
SpriteRenderer m_BlueSprite;
SpriteRenderer m_GreenSprite;
EventSystem m_EventSystem;
[SetUp]
public void TestSetup()
{
m_CamGO = new GameObject("Physics2DRaycaster Camera");
m_CamGO.transform.position = new Vector3(0, 0, -10);
m_CamGO.transform.LookAt(Vector3.zero);
var cam = m_CamGO.AddComponent<Camera>();
cam.orthographic = true;
m_CamGO.AddComponent<Physics2DRaycaster>();
m_EventSystem = m_CamGO.AddComponent<EventSystem>();
var texture = new Texture2D(64, 64);
var sprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), new Vector2(0, 0));
m_RedSprite = CreateTestSprite("Red", Color.red, sprite);
m_BlueSprite = CreateTestSprite("Blue", Color.blue, sprite);
m_GreenSprite = CreateTestSprite("Green", Color.green, sprite);
}
static SpriteRenderer CreateTestSprite(string name, Color color, Sprite sprite)
{
var go = new GameObject(name);
var sr = go.AddComponent<SpriteRenderer>();
sr.sprite = sprite;
sr.color = color;
go.AddComponent<BoxCollider2D>();
return sr;
}
[TearDown]
public void TearDown()
{
GameObject.DestroyImmediate(m_CamGO);
GameObject.DestroyImmediate(m_RedSprite.gameObject);
GameObject.DestroyImmediate(m_BlueSprite.gameObject);
GameObject.DestroyImmediate(m_GreenSprite.gameObject);
}
static void AssertRaycastResultsOrder(List<RaycastResult> results, params SpriteRenderer[] expectedOrder)
{
Assert.AreEqual(expectedOrder.Length, results.Count);
for (int i = 0; i < expectedOrder.Length; ++i)
{
Assert.AreSame(expectedOrder[i].gameObject, results[i].gameObject, "Expected {0} at index {1} but got {2}", expectedOrder[i], i, results[i].gameObject);
}
}
List<RaycastResult> PerformRaycast()
{
var results = new List<RaycastResult>();
var pointerEvent = new PointerEventData(m_EventSystem)
{
position = new Vector2(Screen.width / 2f, Screen.height / 2f)
};
m_EventSystem.RaycastAll(pointerEvent, results);
return results;
}
[Test]
public void RaycastAllResultsAreSortedByRendererSortingOrder()
{
m_RedSprite.sortingOrder = -10;
m_BlueSprite.sortingOrder = 0;
m_GreenSprite.sortingOrder = 5;
var results = PerformRaycast();
AssertRaycastResultsOrder(results, m_GreenSprite, m_BlueSprite, m_RedSprite);
}
[Test]
public void RaycastAllResultsAreSortedBySortGroupOrder()
{
var blueSg = m_BlueSprite.gameObject.AddComponent<SortingGroup>();
blueSg.sortingLayerID = 0;
blueSg.sortingOrder = -10;
var redSg = m_RedSprite.gameObject.AddComponent<SortingGroup>();
redSg.sortingLayerID = 0;
redSg.sortingOrder = 10;
SortingGroup.UpdateAllSortingGroups();
var results = PerformRaycast();
AssertRaycastResultsOrder(results, m_RedSprite, m_GreenSprite, m_BlueSprite);
}
[Test]
public void RaycastAllResultsAreSortedBySortGroupOrderAndSortingOrder()
{
m_RedSprite.sortingOrder = -10;
m_BlueSprite.sortingOrder = 0;
m_GreenSprite.sortingOrder = 5;
var sg = m_BlueSprite.gameObject.AddComponent<SortingGroup>();
sg.sortingLayerID = 0;
sg.sortingOrder = 100;
SortingGroup.UpdateAllSortingGroups();
var results = PerformRaycast();
AssertRaycastResultsOrder(results, m_BlueSprite, m_GreenSprite, m_RedSprite);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6fb761a492f57d84586a8264df7b3cc0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,46 @@
using UnityEngine;
using NUnit.Framework;
using System.Collections.Generic;
using UnityEngine.EventSystems;
public class PhysicsRaycasterTests
{
GameObject m_CamGO;
GameObject m_Collider;
[SetUp]
public void TestSetup()
{
m_CamGO = new GameObject("PhysicsRaycaster Camera");
m_Collider = GameObject.CreatePrimitive(PrimitiveType.Cube);
}
[Test]
public void PhysicsRaycasterDoesNotCastOutsideCameraViewRect()
{
m_CamGO.transform.position = new Vector3(0, 0, -10);
m_CamGO.transform.LookAt(Vector3.zero);
var cam = m_CamGO.AddComponent<Camera>();
cam.rect = new Rect(0.5f, 0, 0.5f, 1);
m_CamGO.AddComponent<PhysicsRaycaster>();
var eventSystem = m_CamGO.AddComponent<EventSystem>();
// Create an object that will be hit if a raycast does occur.
m_Collider.transform.localScale = new Vector3(100, 100, 1);
List<RaycastResult> results = new List<RaycastResult>();
var pointerEvent = new PointerEventData(eventSystem)
{
position = new Vector2(0, 0) // Raycast from the left side of the screen which is outside of the camera's view rect.
};
eventSystem.RaycastAll(pointerEvent, results);
Assert.IsEmpty(results, "Expected no results from a raycast that is outside of the camera's viewport.");
}
[TearDown]
public void TearDown()
{
GameObject.DestroyImmediate(m_CamGO);
GameObject.DestroyImmediate(m_Collider);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 833143c443f979e44ae0b8ed899e3b59
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,121 @@
using System.Collections;
using System.Collections.Generic;
using System.IO;
using NUnit.Framework;
using UnityEditor;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.TestTools;
using UnityEngine.UI;
public class RaycastSortingTests : IPrebuildSetup
{
// Test to check that a a raycast over two canvases will not use hierarchal depth to compare two results
// from different canvases (case 912396 - Raycast hits ignores 2nd Canvas which is drawn in front)
GameObject m_PrefabRoot;
const string kPrefabPath = "Assets/Resources/RaycastSortingPrefab.prefab";
public void Setup()
{
#if UNITY_EDITOR
var rootGO = new GameObject("RootGO");
var cameraGO = new GameObject("Camera", typeof(Camera));
var camera = cameraGO.GetComponent<Camera>();
cameraGO.transform.SetParent(rootGO.transform);
var eventSystemGO = new GameObject("EventSystem", typeof(EventSystem), typeof(StandaloneInputModule));
eventSystemGO.transform.SetParent(rootGO.transform);
var backCanvasGO = new GameObject("BackCanvas", typeof(Canvas), typeof(GraphicRaycaster));
backCanvasGO.transform.SetParent(rootGO.transform);
var backCanvas = backCanvasGO.GetComponent<Canvas>();
backCanvas.renderMode = RenderMode.ScreenSpaceCamera;
backCanvas.planeDistance = 100;
backCanvas.worldCamera = camera;
var backCanvasBackground = new GameObject("BackCanvasBackground", typeof(RectTransform), typeof(Image));
var backCanvasBackgroundTransform = backCanvasBackground.GetComponent<RectTransform>();
backCanvasBackgroundTransform.SetParent(backCanvasGO.transform);
backCanvasBackgroundTransform.anchorMin = Vector2.zero;
backCanvasBackgroundTransform.anchorMax = Vector2.one;
backCanvasBackgroundTransform.sizeDelta = Vector2.zero;
backCanvasBackgroundTransform.anchoredPosition3D = Vector3.zero;
backCanvasBackgroundTransform.localScale = Vector3.one;
var backCanvasDeeper = new GameObject("BackCanvasDeeperHierarchy", typeof(RectTransform), typeof(Image));
var backCanvasDeeperTransform = backCanvasDeeper.GetComponent<RectTransform>();
backCanvasDeeperTransform.SetParent(backCanvasBackgroundTransform);
backCanvasDeeperTransform.anchorMin = new Vector2(0.5f, 0);
backCanvasDeeperTransform.anchorMax = Vector2.one;
backCanvasDeeperTransform.sizeDelta = Vector2.zero;
backCanvasDeeperTransform.anchoredPosition3D = Vector3.zero;
backCanvasDeeperTransform.localScale = Vector3.one;
backCanvasDeeper.GetComponent<Image>().color = new Color(0.6985294f, 0.7754564f, 1f);
var frontCanvasGO = new GameObject("FrontCanvas", typeof(Canvas), typeof(GraphicRaycaster));
frontCanvasGO.transform.SetParent(rootGO.transform);
var frontCanvas = frontCanvasGO.GetComponent<Canvas>();
frontCanvas.renderMode = RenderMode.ScreenSpaceCamera;
frontCanvas.planeDistance = 50;
frontCanvas.worldCamera = camera;
var frontCanvasTopLevel = new GameObject("FrontCanvasTopLevel", typeof(RectTransform), typeof(Text));
var frontCanvasTopLevelTransform = frontCanvasTopLevel.GetComponent<RectTransform>();
frontCanvasTopLevelTransform.SetParent(frontCanvasGO.transform);
frontCanvasTopLevelTransform.anchorMin = Vector2.zero;
frontCanvasTopLevelTransform.anchorMax = new Vector2(1, 0.5f);
frontCanvasTopLevelTransform.sizeDelta = Vector2.zero;
frontCanvasTopLevelTransform.anchoredPosition3D = Vector3.zero;
frontCanvasTopLevelTransform.localScale = Vector3.one;
var text = frontCanvasTopLevel.GetComponent<Text>();
text.text = "FrontCanvasTopLevel";
text.color = Color.black;
text.fontSize = 97;
if (!Directory.Exists("Assets/Resources/"))
Directory.CreateDirectory("Assets/Resources/");
UnityEditor.PrefabUtility.SaveAsPrefabAsset(rootGO, kPrefabPath);
GameObject.DestroyImmediate(rootGO);
#endif
}
[SetUp]
public void TestSetup()
{
m_PrefabRoot = Object.Instantiate(Resources.Load("RaycastSortingPrefab")) as GameObject;
}
[UnityTest]
public IEnumerator RaycastResult_Sorting()
{
Camera cam = m_PrefabRoot.GetComponentInChildren<Camera>();
EventSystem eventSystem = m_PrefabRoot.GetComponentInChildren<EventSystem>();
GameObject shouldHit = m_PrefabRoot.GetComponentInChildren<Text>().gameObject;
PointerEventData eventData = new PointerEventData(eventSystem);
//bottom left quadrant
eventData.position = cam.ViewportToScreenPoint(new Vector3(0.75f, 0.25f));
List<RaycastResult> results = new List<RaycastResult>();
eventSystem.RaycastAll(eventData, results);
Assert.IsTrue(results[0].gameObject.name == shouldHit.name);
yield return null;
}
[TearDown]
public void TearDown()
{
Object.DestroyImmediate(m_PrefabRoot);
}
[OneTimeTearDown]
public void OneTimeTearDown()
{
#if UNITY_EDITOR
AssetDatabase.DeleteAsset(kPrefabPath);
#endif
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0ca2545d76d1fb34fa45a9f1e432d259
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,498 @@
using System.Reflection;
using System.Collections;
using NUnit.Framework;
using UnityEngine.EventSystems;
using UnityEngine.TestTools;
namespace UnityEngine.UI.Tests
{
[TestFixture]
class SelectableTests
{
private class SelectableTest : Selectable
{
public bool isStateNormal { get { return currentSelectionState == SelectionState.Normal; } }
public bool isStateHighlighted { get { return currentSelectionState == SelectionState.Highlighted; } }
public bool isStateSelected { get { return currentSelectionState == SelectionState.Selected; } }
public bool isStatePressed { get { return currentSelectionState == SelectionState.Pressed; } }
public bool isStateDisabled { get { return currentSelectionState == SelectionState.Disabled; } }
public Selectable GetSelectableAtIndex(int index)
{
return s_Selectables[index];
}
public int GetSelectableCurrentIndex()
{
return m_CurrentIndex;
}
}
private SelectableTest selectable;
private GameObject m_CanvasRoot;
private GameObject m_EventSystemGO;
private CanvasGroup CreateAndParentGroupTo(string name, GameObject child)
{
GameObject canvasRoot = new GameObject("Canvas", typeof(RectTransform), typeof(Canvas));
GameObject groupGO = new GameObject(name, typeof(RectTransform), typeof(CanvasGroup));
groupGO.transform.SetParent(canvasRoot.transform);
child.transform.SetParent(groupGO.transform);
return groupGO.GetComponent<CanvasGroup>();
}
[SetUp]
public void TestSetup()
{
m_EventSystemGO = new GameObject("EventSystem", typeof(EventSystem));
EventSystem.current = m_EventSystemGO.GetComponent<EventSystem>();
m_CanvasRoot = new GameObject("Canvas", typeof(RectTransform), typeof(Canvas));
GameObject SelectableGO = new GameObject("Selectable", typeof(RectTransform), typeof(CanvasRenderer));
SelectableGO.transform.SetParent(m_CanvasRoot.transform);
selectable = SelectableGO.AddComponent<SelectableTest>();
selectable.targetGraphic = selectable.gameObject.AddComponent<ConcreteGraphic>();
}
[TearDown]
public void TearDown()
{
GameObject.DestroyImmediate(m_CanvasRoot);
GameObject.DestroyImmediate(m_EventSystemGO);
}
[Test] // regression test 1160054
public void SelectableArrayRemovesReferenceUponDisable()
{
int originalSelectableCount = Selectable.allSelectableCount;
selectable.enabled = false;
Assert.AreEqual(originalSelectableCount - 1, Selectable.allSelectableCount, "We have more then originalSelectableCount - 1 selectable objects.");
//ensure the item as the last index is nulled out as it replaced the item that was disabled.
Assert.IsNull(selectable.GetSelectableAtIndex(Selectable.allSelectableCount));
selectable.enabled = true;
}
#region Selected object
[Test]
public void SettingCurrentSelectedSelectableNonInteractableShouldNullifyCurrentSelected()
{
EventSystem.current.SetSelectedGameObject(selectable.gameObject);
selectable.interactable = false;
// it should be unselected now that it is not interactable anymore
Assert.IsNull(EventSystem.current.currentSelectedGameObject);
}
[Test]
public void PointerEnterDownShouldMakeItSelectedGameObject()
{
Assert.IsNull(EventSystem.current.currentSelectedGameObject);
selectable.InvokeOnPointerEnter(new PointerEventData(EventSystem.current));
selectable.InvokeOnPointerDown(new PointerEventData(EventSystem.current));
Assert.AreEqual(selectable.gameObject, EventSystem.current.currentSelectedGameObject);
}
[Test]
public void OnSelectShouldSetSelectedState()
{
Assert.True(selectable.isStateNormal);
selectable.OnSelect(new BaseEventData(EventSystem.current));
Assert.True(selectable.isStateSelected);
}
[Test]
public void OnDeselectShouldUnsetSelectedState()
{
Assert.True(selectable.isStateNormal);
selectable.OnSelect(new BaseEventData(EventSystem.current));
Assert.True(selectable.isStateSelected);
selectable.OnDeselect(new BaseEventData(EventSystem.current));
Assert.True(selectable.isStateNormal);
}
#endregion
#region Interactable
[Test]
public void SettingCanvasGroupNotInteractableShouldMakeSelectableNotInteractable()
{
// Canvas Group on same object
var group = selectable.gameObject.AddComponent<CanvasGroup>();
Assert.IsTrue(selectable.IsInteractable());
group.interactable = false;
// actual call happens on the native side, cause by interactable = false
selectable.InvokeOnCanvasGroupChanged();
Assert.IsFalse(selectable.IsInteractable());
}
[Test]
public void DisablingCanvasGroupShouldMakeSelectableAsInteractable()
{
var group = selectable.gameObject.AddComponent<CanvasGroup>();
Assert.IsTrue(selectable.IsInteractable());
group.enabled = false;
group.interactable = false;
selectable.InvokeOnCanvasGroupChanged();
Assert.IsTrue(selectable.IsInteractable());
}
[Test]
public void SettingParentCanvasGroupNotInteractableShouldMakeSelectableNotInteractable()
{
var canvasGroup = CreateAndParentGroupTo("CanvasGroup", selectable.gameObject);
Assert.IsTrue(selectable.IsInteractable());
canvasGroup.interactable = false;
// actual call happens on the native side, cause by interactable = false
selectable.InvokeOnCanvasGroupChanged();
Assert.IsFalse(selectable.IsInteractable());
}
[Test]
public void SettingParentParentCanvasGroupNotInteractableShouldMakeSelectableNotInteractable()
{
var canvasGroup1 = CreateAndParentGroupTo("CanvasGroup1", selectable.gameObject);
var canvasGroup2 = CreateAndParentGroupTo("CanvasGroup2", canvasGroup1.gameObject);
Assert.IsTrue(selectable.IsInteractable());
canvasGroup2.interactable = false;
// actual call happens on the native side, cause by interactable = false
selectable.InvokeOnCanvasGroupChanged();
Assert.IsFalse(selectable.IsInteractable());
}
[Test]
public void SettingParentParentCanvasGroupInteractableShouldMakeSelectableInteractable()
{
var canvasGroup1 = CreateAndParentGroupTo("CanvasGroup1", selectable.gameObject);
CreateAndParentGroupTo("CanvasGroup2", canvasGroup1.gameObject);
Assert.IsTrue(selectable.IsInteractable());
// actual call happens on the native side, cause by interactable
selectable.InvokeOnCanvasGroupChanged();
Assert.IsTrue(selectable.IsInteractable());
}
[Test]
public void SettingParentParentCanvasGroupNotInteractableShouldNotMakeSelectableNotInteractableIfIgnoreParentGroups()
{
var canvasGroup1 = CreateAndParentGroupTo("CanvasGroup1", selectable.gameObject);
canvasGroup1.ignoreParentGroups = true;
var canvasGroup2 = CreateAndParentGroupTo("CanvasGroup2", canvasGroup1.gameObject);
Assert.IsTrue(selectable.IsInteractable());
canvasGroup2.interactable = false;
// actual call happens on the native side, cause by interactable = false
selectable.InvokeOnCanvasGroupChanged();
Assert.IsTrue(selectable.IsInteractable());
}
[Test]// regression test 861736
public void PointerEnterThenSetNotInteractableThenExitThenSetInteractableShouldSetStateToDefault()
{
Assert.True(selectable.isStateNormal);
selectable.InvokeOnPointerEnter(new PointerEventData(EventSystem.current)
{
pointerEnter = selectable.gameObject
});
Assert.True(selectable.isStateHighlighted);
selectable.interactable = false;
selectable.InvokeOnPointerExit(new PointerEventData(EventSystem.current)
{
pointerEnter = selectable.gameObject
});
selectable.interactable = true;
Assert.False(selectable.isStateHighlighted);
Assert.True(selectable.isStateNormal);
}
[Test]// regression test 861736
public void PointerEnterThenSetNotInteractableThenSetInteractableShouldStayHighlighted()
{
Assert.True(selectable.isStateNormal);
selectable.InvokeOnPointerEnter(new PointerEventData(EventSystem.current)
{
pointerEnter = selectable.gameObject
});
Assert.True(selectable.isStateHighlighted);
selectable.interactable = false;
selectable.interactable = true;
Assert.True(selectable.isStateHighlighted);
}
[Test]
public void InstantiatingSelectableUnderNotInteractableCanvasGroupShouldAlsoNotBeInteractable()
{
var canvasGroup = CreateAndParentGroupTo("ParentGroup", selectable.gameObject);
canvasGroup.interactable = false;
Assert.False(canvasGroup.interactable);
var newSelectable = Object.Instantiate(selectable.gameObject, canvasGroup.transform).GetComponent<SelectableTest>();
Assert.False(newSelectable.IsInteractable());
}
#endregion
#region Tweening
[UnityTest]
public IEnumerator SettingNotInteractableShouldTweenToDisabledColor()
{
var canvasRenderer = selectable.gameObject.GetComponent<CanvasRenderer>();
selectable.InvokeOnEnable();
canvasRenderer.SetColor(selectable.colors.normalColor);
selectable.interactable = false;
yield return new WaitForSeconds(1);
Assert.AreEqual(selectable.colors.disabledColor, canvasRenderer.GetColor());
selectable.interactable = true;
yield return new WaitForSeconds(1);
Assert.AreEqual(selectable.colors.normalColor, canvasRenderer.GetColor());
}
[UnityTest][Ignore("Fails")] // regression test 742140
public IEnumerator SettingNotInteractableThenInteractableShouldNotTweenToDisabledColor()
{
var canvasRenderer = selectable.gameObject.GetComponent<CanvasRenderer>();
selectable.enabled = false;
selectable.enabled = true;
canvasRenderer.SetColor(selectable.colors.normalColor);
selectable.interactable = false;
selectable.interactable = true;
Color c = canvasRenderer.GetColor();
for (int i = 0; i < 30; i++)
{
yield return null;
Color c2 = canvasRenderer.GetColor();
Assert.AreNotEqual(c2, c);
}
Assert.AreEqual(selectable.colors.normalColor, canvasRenderer.GetColor());
}
[UnityTest]
public IEnumerator SettingInteractableToFalseTrueFalseShouldTweenToDisabledColor()
{
var canvasRenderer = selectable.gameObject.GetComponent<CanvasRenderer>();
selectable.InvokeOnEnable();
canvasRenderer.SetColor(selectable.colors.normalColor);
selectable.interactable = false;
selectable.interactable = true;
selectable.interactable = false;
yield return new WaitForSeconds(1);
Assert.AreEqual(selectable.colors.disabledColor, canvasRenderer.GetColor());
}
#if PACKAGE_ANIMATION
[Test]
public void TriggerAnimationWithNoAnimator()
{
Assert.Null(selectable.animator);
Assert.DoesNotThrow(() => selectable.InvokeTriggerAnimation("asdasd"));
}
[Test]
public void TriggerAnimationWithDisabledAnimator()
{
var an = selectable.gameObject.AddComponent<Animator>();
an.enabled = false;
Assert.NotNull(selectable.animator);
Assert.DoesNotThrow(() => selectable.InvokeTriggerAnimation("asdasd"));
}
[Test]
public void TriggerAnimationAnimatorWithNoRuntimeController()
{
var an = selectable.gameObject.AddComponent<Animator>();
an.runtimeAnimatorController = null;
Assert.NotNull(selectable.animator);
Assert.DoesNotThrow(() => selectable.InvokeTriggerAnimation("asdasd"));
}
#endif
#endregion
#region Selection state and pointer
[Test]
public void SelectShouldSetSelectedObject()
{
Assert.Null(EventSystem.current.currentSelectedGameObject);
selectable.Select();
Assert.AreEqual(selectable.gameObject, EventSystem.current.currentSelectedGameObject);
}
[Test]
public void SelectWhenAlreadySelectingShouldNotSetSelectedObject()
{
Assert.Null(EventSystem.current.currentSelectedGameObject);
var fieldInfo = typeof(EventSystem).GetField("m_SelectionGuard", BindingFlags.NonPublic | BindingFlags.Instance);
fieldInfo
.SetValue(EventSystem.current, true);
selectable.Select();
Assert.Null(EventSystem.current.currentSelectedGameObject);
}
[Test]
public void PointerEnterShouldHighlight()
{
Assert.True(selectable.isStateNormal);
selectable.InvokeOnPointerEnter(new PointerEventData(EventSystem.current)
{
pointerEnter = selectable.gameObject
});
Assert.True(selectable.isStateHighlighted);
}
[Test]
public void PointerEnterOnSelectedObjectShouldStaySelected()
{
selectable.InvokeOnSelect(null);
Assert.True(selectable.isStateSelected);
selectable.InvokeOnPointerEnter(new PointerEventData(EventSystem.current)
{
pointerEnter = selectable.gameObject
});
Assert.True(selectable.isStateSelected);
}
[Test]
public void PointerEnterAndRightClickShouldHighlightNotPress()
{
Assert.True(selectable.isStateNormal);
selectable.InvokeOnPointerEnter(new PointerEventData(EventSystem.current)
{
pointerEnter = selectable.gameObject
});
selectable.InvokeOnPointerDown(new PointerEventData(EventSystem.current)
{
button = PointerEventData.InputButton.Right
});
Assert.True(selectable.isStateHighlighted);
}
[Test]
public void PointerEnterAndRightClickShouldPress()
{
Assert.True(selectable.isStateNormal);
selectable.InvokeOnPointerEnter(new PointerEventData(EventSystem.current)
{
pointerEnter = selectable.gameObject
});
selectable.InvokeOnPointerDown(new PointerEventData(EventSystem.current));
Assert.True(selectable.isStatePressed);
}
[Test]
public void PointerEnterLeftClickExitShouldPress()
{
Assert.True(selectable.isStateNormal);
selectable.InvokeOnPointerEnter(new PointerEventData(EventSystem.current)
{
pointerEnter = selectable.gameObject
});
selectable.InvokeOnPointerDown(new PointerEventData(EventSystem.current));
selectable.InvokeOnPointerExit(new PointerEventData(EventSystem.current)
{
pointerEnter = selectable.gameObject
});
Assert.True(selectable.isStatePressed);
}
[Test]
public void PointerEnterLeftClickExitReleaseShouldSelect()
{
Assert.True(selectable.isStateNormal);
selectable.InvokeOnPointerEnter(new PointerEventData(EventSystem.current)
{
pointerEnter = selectable.gameObject
});
selectable.InvokeOnPointerDown(new PointerEventData(EventSystem.current));
selectable.InvokeOnPointerExit(new PointerEventData(EventSystem.current)
{
pointerEnter = selectable.gameObject
});
selectable.InvokeOnPointerUp(new PointerEventData(EventSystem.current));
Assert.True(selectable.isStateSelected);
}
[Test]
public void PointerDownShouldSetSelectedObject()
{
Assert.Null(EventSystem.current.currentSelectedGameObject);
selectable.InvokeOnPointerDown(new PointerEventData(EventSystem.current));
Assert.AreEqual(selectable.gameObject, EventSystem.current.currentSelectedGameObject);
}
[Test]
public void PointerLeftDownRightDownRightUpShouldNotChangeState()
{
Assert.True(selectable.isStateNormal);
selectable.InvokeOnPointerEnter(new PointerEventData(EventSystem.current)
{
pointerEnter = selectable.gameObject
});
selectable.InvokeOnPointerDown(new PointerEventData(EventSystem.current) { button = PointerEventData.InputButton.Left });
selectable.InvokeOnPointerDown(new PointerEventData(EventSystem.current) { button = PointerEventData.InputButton.Right });
selectable.InvokeOnPointerUp(new PointerEventData(EventSystem.current) { button = PointerEventData.InputButton.Right });
Assert.True(selectable.isStatePressed);
}
[Test, Ignore("No disabled state assigned ? Investigate")]
public void SettingNotInteractableShouldDisable()
{
Assert.True(selectable.isStateNormal);
selectable.interactable = false;
selectable.InvokeOnCanvasGroupChanged();
Assert.True(selectable.isStateDisabled);
}
#endregion
#region No event system
[Test] // regression test 787563
public void SettingInteractableWithNoEventSystemShouldNotCrash()
{
EventSystem.current.enabled = false;
selectable.interactable = false;
}
[Test] // regression test 787563
public void OnPointerDownWithNoEventSystemShouldNotCrash()
{
EventSystem.current.enabled = false;
selectable.OnPointerDown(new PointerEventData(EventSystem.current) {button = PointerEventData.InputButton.Left});
}
[Test] // regression test 787563
public void SelectWithNoEventSystemShouldNotCrash()
{
EventSystem.current.enabled = false;
selectable.Select();
}
#endregion
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 39dcddcb5895328489c92214aa73e3bb
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 8313ea704470a264295ec9e09aec6ebc
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,264 @@
using System.Collections.Generic;
using System.IO;
using NUnit.Framework;
using UnityEditor;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.TestTools;
using UnityEngine.UI;
using UnityEngine.UI.Tests;
namespace Graphics
{
class GraphicTests : IPrebuildSetup
{
private GameObject m_PrefabRoot;
private ConcreteGraphic m_graphic;
private Canvas m_canvas;
const string kPrefabPath = "Assets/Resources/GraphicTestsPrefab.prefab";
bool m_dirtyVert;
bool m_dirtyLayout;
bool m_dirtyMaterial;
public void Setup()
{
#if UNITY_EDITOR
var rootGO = new GameObject("rootGo");
var canvasGO = new GameObject("CanvasRoot", typeof(Canvas), typeof(GraphicRaycaster));
canvasGO.transform.SetParent(rootGO.transform);
var graphicGO = new GameObject("Graphic", typeof(RectTransform), typeof(ConcreteGraphic));
graphicGO.transform.SetParent(canvasGO.transform);
var gameObject = new GameObject("EventSystem", typeof(EventSystem));
gameObject.transform.SetParent(rootGO.transform);
if (!Directory.Exists("Assets/Resources/"))
Directory.CreateDirectory("Assets/Resources/");
PrefabUtility.SaveAsPrefabAsset(rootGO, kPrefabPath);
GameObject.DestroyImmediate(rootGO);
#endif
}
[SetUp]
public void TestSetup()
{
m_PrefabRoot = Object.Instantiate(Resources.Load("GraphicTestsPrefab")) as GameObject;
m_canvas = m_PrefabRoot.GetComponentInChildren<Canvas>();
m_graphic = m_PrefabRoot.GetComponentInChildren<ConcreteGraphic>();
m_graphic.RegisterDirtyVerticesCallback(() => m_dirtyVert = true);
m_graphic.RegisterDirtyLayoutCallback(() => m_dirtyLayout = true);
m_graphic.RegisterDirtyMaterialCallback(() => m_dirtyMaterial = true);
ResetDirtyFlags();
}
[TearDown]
public void TearDown()
{
m_graphic = null;
m_canvas = null;
GameObject.DestroyImmediate(m_PrefabRoot);
}
[OneTimeTearDown]
public void OneTimeTearDown()
{
#if UNITY_EDITOR
AssetDatabase.DeleteAsset(kPrefabPath);
#endif
}
private void ResetDirtyFlags()
{
m_dirtyVert = m_dirtyLayout = m_dirtyMaterial = false;
}
[Test]
public void SettingDirtyOnActiveGraphicCallsCallbacks()
{
m_graphic.enabled = false;
m_graphic.enabled = true;
m_graphic.SetAllDirty();
Assert.True(m_dirtyVert, "Vertices have not been dirtied");
Assert.True(m_dirtyLayout, "Layout has not been dirtied");
Assert.True(m_dirtyMaterial, "Material has not been dirtied");
ResetDirtyFlags();
m_graphic.SetLayoutDirty();
Assert.True(m_dirtyLayout, "Layout has not been dirtied");
m_graphic.SetVerticesDirty();
Assert.True(m_dirtyVert, "Vertices have not been dirtied");
m_graphic.SetMaterialDirty();
Assert.True(m_dirtyMaterial, "Material has not been dirtied");
}
private bool ContainsGraphic(IList<Graphic> array, int size, Graphic element)
{
for (int i = 0; i < size; ++i)
{
if (array[i] == element)
return true;
}
return false;
}
private void RefreshGraphicByRaycast()
{
// force refresh by raycast
List<RaycastResult> raycastResultCache = new List<RaycastResult>();
PointerEventData data = new PointerEventData(EventSystem.current);
var raycaster = m_canvas.GetComponent<GraphicRaycaster>();
raycaster.Raycast(data, raycastResultCache);
}
private bool CheckGraphicAddedToGraphicRegistry()
{
var graphicList = GraphicRegistry.GetGraphicsForCanvas(m_canvas);
var graphicListSize = graphicList.Count;
return ContainsGraphic(graphicList, graphicListSize, m_graphic);
}
private bool CheckGraphicAddedToRaycastGraphicRegistry()
{
var graphicList = GraphicRegistry.GetRaycastableGraphicsForCanvas(m_canvas);
var graphicListSize = graphicList.Count;
return ContainsGraphic(graphicList, graphicListSize, m_graphic);
}
private void CheckGraphicRaycastDisableValidity()
{
RefreshGraphicByRaycast();
Assert.False(CheckGraphicAddedToGraphicRegistry(), "Graphic should no longer be registered in m_CanvasGraphics");
Assert.False(CheckGraphicAddedToRaycastGraphicRegistry(), "Graphic should no longer be registered in m_RaycastableGraphics");
}
[Test]
public void OnEnableLeavesGraphicInExpectedState()
{
m_graphic.enabled = false;
m_graphic.enabled = true; // on enable is called directly
Assert.True(CheckGraphicAddedToGraphicRegistry(), "Graphic should be registered in m_CanvasGraphics");
Assert.True(CheckGraphicAddedToRaycastGraphicRegistry(), "Graphic should be registered in m_RaycastableGraphics");
Assert.AreEqual(Texture2D.whiteTexture, m_graphic.mainTexture, "mainTexture should be Texture2D.whiteTexture");
Assert.NotNull(m_graphic.canvas);
Assert.True(m_dirtyVert, "Vertices have not been dirtied");
Assert.True(m_dirtyLayout, "Layout has not been dirtied");
Assert.True(m_dirtyMaterial, "Material has not been dirtied");
}
[Test]
public void OnEnableTwiceLeavesGraphicInExpectedState()
{
m_graphic.enabled = true;
// force onEnable by reflection to call it second time
m_graphic.InvokeOnEnable();
m_graphic.enabled = false;
CheckGraphicRaycastDisableValidity();
}
[Test]
public void OnDisableLeavesGraphicInExpectedState()
{
m_graphic.enabled = true;
m_graphic.enabled = false;
CheckGraphicRaycastDisableValidity();
}
[Test]
public void OnPopulateMeshWorksAsExpected()
{
m_graphic.rectTransform.anchoredPosition = new Vector2(100, 100);
m_graphic.rectTransform.sizeDelta = new Vector2(150, 742);
m_graphic.color = new Color(50, 100, 150, 200);
VertexHelper vh = new VertexHelper();
m_graphic.InvokeOnPopulateMesh(vh);
GraphicTestHelper.TestOnPopulateMeshDefaultBehavior(m_graphic, vh);
}
[Test]
public void OnDidApplyAnimationPropertiesSetsAllDirty()
{
m_graphic.enabled = true; // Usually set through SetEnabled, from Behavior
m_graphic.InvokeOnDidApplyAnimationProperties();
Assert.True(m_dirtyVert, "Vertices have not been dirtied");
Assert.True(m_dirtyLayout, "Layout has not been dirtied");
Assert.True(m_dirtyMaterial, "Material has not been dirtied");
}
[Test]
public void MakingGraphicNonRaycastableRemovesGraphicFromProperLists()
{
Assert.True(CheckGraphicAddedToGraphicRegistry(), "Graphic should be registered in m_CanvasGraphics");
Assert.True(CheckGraphicAddedToRaycastGraphicRegistry(), "Graphic should be registered in m_RaycastableGraphics");
m_graphic.raycastTarget = false;
Assert.True(CheckGraphicAddedToGraphicRegistry(), "Graphic should be registered in m_CanvasGraphics");
Assert.False(CheckGraphicAddedToRaycastGraphicRegistry(), "Graphic should no longer be registered in m_RaycastableGraphics");
}
[Test]
public void OnEnableLeavesNonRaycastGraphicInExpectedState()
{
m_graphic.enabled = false;
m_graphic.raycastTarget = false;
m_graphic.enabled = true; // on enable is called directly
Assert.True(CheckGraphicAddedToGraphicRegistry(), "Graphic should be registered in m_CanvasGraphics");
Assert.False(CheckGraphicAddedToRaycastGraphicRegistry(), "Graphic should no longer be registered in m_RaycastableGraphics");
Assert.AreEqual(Texture2D.whiteTexture, m_graphic.mainTexture, "mainTexture should be Texture2D.whiteTexture");
Assert.NotNull(m_graphic.canvas);
Assert.True(m_dirtyVert, "Vertices have not been dirtied");
Assert.True(m_dirtyLayout, "Layout has not been dirtied");
Assert.True(m_dirtyMaterial, "Material has not been dirtied");
}
[Test]
public void SettingRaycastTargetOnDisabledGraphicDoesntAddItRaycastList()
{
Assert.True(CheckGraphicAddedToGraphicRegistry(), "Graphic should be registered in m_CanvasGraphics");
Assert.True(CheckGraphicAddedToRaycastGraphicRegistry(), "Graphic should be registered in m_RaycastableGraphics");
m_graphic.raycastTarget = false;
Assert.True(CheckGraphicAddedToGraphicRegistry(), "Graphic should be registered in m_CanvasGraphics");
Assert.False(CheckGraphicAddedToRaycastGraphicRegistry(), "Graphic should no longer be registered in m_RaycastableGraphics");
m_graphic.enabled = false;
Assert.False(CheckGraphicAddedToGraphicRegistry(), "Graphic should NOT be registered in m_CanvasGraphics");
Assert.False(CheckGraphicAddedToRaycastGraphicRegistry(), "Graphic should no longer be registered in m_RaycastableGraphics");
m_graphic.raycastTarget = true;
Assert.False(CheckGraphicAddedToGraphicRegistry(), "Graphic should NOT be registered in m_CanvasGraphics");
Assert.False(CheckGraphicAddedToRaycastGraphicRegistry(), "Graphic should no longer be registered in m_RaycastableGraphics");
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e88a766c2b8b47841936c136f4afbba9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,528 @@
using System;
using System.Collections.Generic;
using NUnit.Framework;
namespace UnityEngine.UI.Tests
{
[TestFixture]
class ImageTests
{
Image m_Image;
private Sprite m_Sprite;
private Sprite m_OverrideSprite;
Texture2D texture = new Texture2D(128, 128);
Texture2D overrideTexture = new Texture2D(512, 512);
bool m_dirtyVert;
bool m_dirtyLayout;
bool m_dirtyMaterial;
Camera m_camera;
GameObject m_CanvasRoot;
[SetUp]
public void TestSetup()
{
m_CanvasRoot = new GameObject("Canvas", typeof(RectTransform), typeof(Canvas));
GameObject gameObject = new GameObject("Image", typeof(RectTransform), typeof(Image));
gameObject.transform.SetParent(m_CanvasRoot.transform);
m_camera = new GameObject("Camera", typeof(Camera)).GetComponent<Camera>();
m_Image = gameObject.GetComponent<Image>();
Color[] colors = new Color[128 * 128];
for (int y = 0; y < 128; y++)
for (int x = 0; x < 128; x++)
colors[x + 128 * y] = new Color(0, 0, 0, 1 - x / 128f);
texture.SetPixels(colors);
texture.Apply();
Color[] overrideColors = new Color[512 * 512];
for (int y = 0; y < 512; y++)
for (int x = 0; x < 512; x++)
overrideColors[x + 512 * y] = new Color(0, 0, 0, y / 512f);
overrideTexture.SetPixels(overrideColors);
overrideTexture.Apply();
m_Sprite = Sprite.Create(texture, new Rect(0, 0, 128, 128), new Vector2(0.5f, 0.5f), 100);
m_OverrideSprite = Sprite.Create(overrideTexture, new Rect(0, 0, 512, 512), new Vector2(0.5f, 0.5f), 200);
m_Image.rectTransform.anchoredPosition = new Vector2(0, 0);
m_Image.rectTransform.sizeDelta = new Vector2(100, 100);
m_Image.RegisterDirtyVerticesCallback(() => m_dirtyVert = true);
m_Image.RegisterDirtyLayoutCallback(() => m_dirtyLayout = true);
m_Image.RegisterDirtyMaterialCallback(() => m_dirtyMaterial = true);
ResetDirtyFlags();
}
[TearDown]
public void TearDown()
{
m_Image = null;
m_Sprite = null;
GameObject.DestroyImmediate(m_CanvasRoot);
GameObject.DestroyImmediate(m_camera.gameObject);
m_camera = null;
}
private void ResetDirtyFlags()
{
m_dirtyVert = m_dirtyLayout = m_dirtyMaterial = false;
}
[Test]
public void SetTestSprite()
{
m_Image.sprite = m_Sprite;
m_Image.overrideSprite = m_OverrideSprite;
Assert.AreEqual(m_Sprite, m_Image.sprite);
m_Image.sprite = null;
Assert.AreEqual(null, m_Image.sprite);
}
[Test]
public void TestPixelsPerUnit()
{
m_Image.sprite = m_Sprite;
Assert.AreEqual(1.0f, m_Image.pixelsPerUnit);
m_Image.overrideSprite = m_OverrideSprite;
Assert.AreEqual(2.0f, m_Image.pixelsPerUnit);
m_Image.overrideSprite = null;
Assert.AreEqual(1.0f, m_Image.pixelsPerUnit);
}
[Test]
public void RaycastOverImageWithoutASpriteReturnTrue()
{
m_Image.sprite = null;
bool raycast = m_Image.Raycast(new Vector2(10, 10), m_camera);
Assert.AreEqual(true, raycast);
}
[Test]
[TestCase(0.0f, 1000, 1000)]
[TestCase(1.0f, 1000, 1000)]
[TestCase(0.0f, -1000, 1000)]
[TestCase(1.0f, -1000, 1000)]
[TestCase(0.0f, 1000, -1000)]
[TestCase(1.0f, 1000, -1000)]
[TestCase(0.0f, -1000, -1000)]
[TestCase(1.0f, -1000, -1000)]
public void RaycastOverImageWithoutASpriteReturnsTrueWithCoordinatesOutsideTheBoundaries(float alphaThreshold, float x, float y)
{
m_Image.alphaHitTestMinimumThreshold = 1.0f - alphaThreshold;
bool raycast = m_Image.Raycast(new Vector2(x, y), m_camera);
Assert.IsTrue(raycast);
}
[Test]
public void RaycastOverImage_IgnoresDisabledCanvasGroup()
{
var canvasGroup = m_CanvasRoot.AddComponent<CanvasGroup>();
canvasGroup.blocksRaycasts = false;
canvasGroup.enabled = false;
bool raycast = m_Image.Raycast(new Vector2(1000, 1000), m_camera);
Assert.IsTrue(raycast);
}
[Test]
public void SettingSpriteMarksAllAsDirty()
{
m_Image.sprite = m_Sprite;
Assert.True(m_dirtyVert, "Vertices have not been dirtied");
Assert.True(m_dirtyLayout, "Layout has not been dirtied");
Assert.True(m_dirtyMaterial, "Material has not been dirtied");
}
[Test]
public void SettingOverrideSpriteMarksAllAsDirty()
{
m_Image.overrideSprite = m_OverrideSprite;
Assert.True(m_dirtyVert, "Vertices have not been dirtied");
Assert.True(m_dirtyLayout, "Layout has not been dirtied");
Assert.True(m_dirtyMaterial, "Material has not been dirtied");
}
[Test]
public void SettingTypeMarksVerticesAsDirty()
{
m_Image.type = Image.Type.Filled;
Assert.True(m_dirtyVert, "Vertices have not been dirtied");
Assert.False(m_dirtyLayout, "Layout has been dirtied");
Assert.False(m_dirtyMaterial, "Material has been dirtied");
}
[Test]
public void SettingPreserveAspectMarksVerticesAsDirty()
{
m_Image.preserveAspect = true;
Assert.True(m_dirtyVert, "Vertices have not been dirtied");
Assert.False(m_dirtyLayout, "Layout has been dirtied");
Assert.False(m_dirtyMaterial, "Material has been dirtied");
}
[Test]
public void SettingFillCenterMarksVerticesAsDirty()
{
m_Image.fillCenter = false;
Assert.True(m_dirtyVert, "Vertices have not been dirtied");
Assert.False(m_dirtyLayout, "Layout has been dirtied");
Assert.False(m_dirtyMaterial, "Material has been dirtied");
}
[Test]
public void SettingFillMethodMarksVerticesAsDirty()
{
m_Image.fillMethod = Image.FillMethod.Horizontal;
Assert.True(m_dirtyVert, "Vertices have not been dirtied");
Assert.False(m_dirtyLayout, "Layout has been dirtied");
Assert.False(m_dirtyMaterial, "Material has been dirtied");
}
[Test]
public void SettingFillAmountMarksVerticesAsDirty()
{
m_Image.fillAmount = 0.5f;
Assert.True(m_dirtyVert, "Vertices have not been dirtied");
Assert.False(m_dirtyLayout, "Layout has been dirtied");
Assert.False(m_dirtyMaterial, "Material has been dirtied");
}
[Test]
public void SettingFillClockwiseMarksVerticesAsDirty()
{
m_Image.fillClockwise = false;
Assert.True(m_dirtyVert, "Vertices have not been dirtied");
Assert.False(m_dirtyLayout, "Layout has been dirtied");
Assert.False(m_dirtyMaterial, "Material has been dirtied");
}
[Test]
public void SettingFillOriginMarksVerticesAsDirty()
{
m_Image.fillOrigin = 1;
Assert.True(m_dirtyVert, "Vertices have not been dirtied");
Assert.False(m_dirtyLayout, "Layout has been dirtied");
Assert.False(m_dirtyMaterial, "Material has been dirtied");
}
[Test]
public void SettingEventAlphaThresholdMarksNothingAsDirty()
{
m_Image.alphaHitTestMinimumThreshold = 0.5f;
Assert.False(m_dirtyVert, "Vertices have been dirtied");
Assert.False(m_dirtyLayout, "Layout has been dirtied");
Assert.False(m_dirtyMaterial, "Material has been dirtied");
}
[Test]
public void OnAfterDeserializeMakeFillOriginZeroIfNotBetweenZeroAndThree()
{
for (int i = -10; i < 0; i++)
{
m_Image.fillOrigin = i;
m_Image.OnAfterDeserialize();
Assert.AreEqual(0, m_Image.fillOrigin);
}
for (int i = 0; i < 4; i++)
{
m_Image.fillOrigin = i;
m_Image.OnAfterDeserialize();
Assert.AreEqual(i, m_Image.fillOrigin);
}
for (int i = 4; i < 10; i++)
{
m_Image.fillOrigin = i;
m_Image.OnAfterDeserialize();
Assert.AreEqual(0, m_Image.fillOrigin);
}
}
[Test]
public void OnAfterDeserializeMakeFillOriginZeroIfFillOriginGreaterThan1AndFillMethodHorizontalOrVertical()
{
m_Image.fillMethod = Image.FillMethod.Horizontal;
Image.FillMethod[] fillMethodsToTest = {Image.FillMethod.Horizontal, Image.FillMethod.Vertical};
foreach (var fillMethod in fillMethodsToTest)
{
m_Image.fillMethod = fillMethod;
for (int i = -10; i < 0; i++)
{
m_Image.fillOrigin = i;
m_Image.OnAfterDeserialize();
Assert.AreEqual(0, m_Image.fillOrigin);
}
for (int i = 0; i < 2; i++)
{
m_Image.fillOrigin = i;
m_Image.OnAfterDeserialize();
Assert.AreEqual(i, m_Image.fillOrigin);
}
for (int i = 2; i < 100; i++)
{
m_Image.fillOrigin = i;
m_Image.OnAfterDeserialize();
Assert.AreEqual(0, m_Image.fillOrigin);
}
}
}
[Test]
public void OnAfterDeserializeClampsFillAmountBetweenZeroAndOne()
{
for (float f = -5; f < 0; f += 0.1f)
{
m_Image.fillAmount = f;
m_Image.OnAfterDeserialize();
Assert.AreEqual(0, m_Image.fillAmount);
}
for (float f = 0; f < 1; f += 0.1f)
{
m_Image.fillAmount = f;
m_Image.OnAfterDeserialize();
Assert.AreEqual(f, m_Image.fillAmount);
}
for (float f = 1; f < 5; f += 0.1f)
{
m_Image.fillAmount = f;
m_Image.OnAfterDeserialize();
Assert.AreEqual(1, m_Image.fillAmount);
}
}
[Test]
public void SetNativeSizeSetsAllAsDirtyAndSetsAnchorMaxAndSizeDeltaWhenOverrideSpriteIsNotNull()
{
m_Image.sprite = m_Sprite;
m_Image.overrideSprite = m_OverrideSprite;
m_Image.rectTransform.anchorMax = new Vector2(100, 100);
m_Image.rectTransform.anchorMin = new Vector2(0, 0);
m_Image.SetNativeSize();
Assert.True(m_dirtyVert, "Vertices have not been dirtied");
Assert.True(m_dirtyLayout, "Layout has not been dirtied");
Assert.True(m_dirtyMaterial, "Material has not been dirtied");
Assert.AreEqual(m_Image.rectTransform.anchorMin, m_Image.rectTransform.anchorMax);
Assert.AreEqual(m_OverrideSprite.rect.size / m_Image.pixelsPerUnit, m_Image.rectTransform.sizeDelta);
}
[Test]
public void OnPopulateMeshWhenNoOverrideSpritePresentDefersToGraphicImplementation()
{
m_OverrideSprite = null;
m_Image.rectTransform.anchoredPosition = new Vector2(100, 452);
m_Image.rectTransform.sizeDelta = new Vector2(881, 593);
m_Image.color = new Color(0.1f, 0.2f, 0.8f, 0);
VertexHelper vh = new VertexHelper();
m_Image.InvokeOnPopulateMesh(vh);
Assert.AreEqual(4, vh.currentVertCount);
List<UIVertex> verts = new List<UIVertex>();
vh.GetUIVertexStream(verts);
// The vertices for the 2 triangles of the canvas
UIVertex[] expectedVertices =
{
new UIVertex
{
color = m_Image.color,
position = m_Image.rectTransform.rect.min,
uv0 = new Vector2(0f, 0f),
normal = new Vector3(0, 0, -1),
tangent = new Vector4(1, 0, 0, -1)
},
new UIVertex
{
color = m_Image.color,
position = new Vector3(m_Image.rectTransform.rect.xMin, m_Image.rectTransform.rect.yMax),
uv0 = new Vector2(0f, 1f),
normal = new Vector3(0, 0, -1),
tangent = new Vector4(1, 0, 0, -1)
},
new UIVertex
{
color = m_Image.color,
position = m_Image.rectTransform.rect.max,
uv0 = new Vector2(1f, 1f),
normal = new Vector3(0, 0, -1),
tangent = new Vector4(1, 0, 0, -1)
},
new UIVertex
{
color = m_Image.color,
position = m_Image.rectTransform.rect.max,
uv0 = new Vector2(1f, 1f),
normal = new Vector3(0, 0, -1),
tangent = new Vector4(1, 0, 0, -1)
},
new UIVertex
{
color = m_Image.color,
position = new Vector3(m_Image.rectTransform.rect.xMax, m_Image.rectTransform.rect.yMin),
uv0 = new Vector2(1f, 0f),
normal = new Vector3(0, 0, -1),
tangent = new Vector4(1, 0, 0, -1)
},
new UIVertex
{
color = m_Image.color,
position = m_Image.rectTransform.rect.min,
uv0 = new Vector2(0f, 0f),
normal = new Vector3(0, 0, -1),
tangent = new Vector4(1, 0, 0, -1)
},
};
for (int i = 0; i < verts.Count; i++)
{
Assert.AreEqual(expectedVertices[i], verts[i]);
}
}
private void TestOnPopulateMeshTypeSimple(VertexHelper vh, Vector4 UVs)
{
List<UIVertex> verts = new List<UIVertex>();
vh.GetUIVertexStream(verts);
Assert.AreEqual(4, vh.currentVertCount);
Assert.AreEqual(6, vh.currentIndexCount);
var imgRect = m_Image.rectTransform.rect;
Vector3[] expectedVertices =
{
imgRect.min,
new Vector3(imgRect.xMin, imgRect.yMax),
imgRect.max,
imgRect.max,
new Vector3(imgRect.xMax, imgRect.yMin),
imgRect.min
};
Vector2[] expectedUV0s =
{
new Vector2(UVs.x, UVs.y),
new Vector2(UVs.x, UVs.w),
new Vector2(UVs.z, UVs.w),
new Vector2(UVs.z, UVs.w),
new Vector2(UVs.z, UVs.y),
new Vector2(UVs.x, UVs.y),
};
var expectedNormal = new Vector3(0, 0, -1);
var expectedTangent = new Vector4(1, 0, 0, -1);
Color32 expectedColor = m_Image.color;
Vector2 expectedUV1 = new Vector2(0, 0);
for (int i = 0; i < 6; i++)
{
Assert.AreEqual(expectedVertices[i], verts[i].position);
Assert.AreEqual(expectedUV0s[i], verts[i].uv0);
Assert.AreEqual(expectedUV1, verts[i].uv1);
Assert.AreEqual(expectedNormal, verts[i].normal);
Assert.AreEqual(expectedTangent, verts[i].tangent);
Assert.AreEqual(expectedColor, verts[i].color);
}
}
[Test]
public void OnPopulateMeshWithTypeTiledNoBorderGeneratesExpectedResults()
{
m_Image.sprite = m_Sprite;
m_Image.sprite.texture.wrapMode = TextureWrapMode.Repeat;
m_Image.type = Image.Type.Tiled;
VertexHelper vh = new VertexHelper();
m_Image.InvokeOnPopulateMesh(vh);
Assert.AreEqual(4, vh.currentVertCount);
Assert.AreEqual(6, vh.currentIndexCount);
}
[Test]
public void MinWidthHeightAreZeroWithNoImage()
{
Assert.AreEqual(0, m_Image.minWidth);
Assert.AreEqual(0, m_Image.minHeight);
}
[Test]
public void FlexibleWidthHeightAreCorrectWithNoImage()
{
Assert.AreEqual(-1, m_Image.flexibleWidth);
Assert.AreEqual(-1, m_Image.flexibleHeight);
}
[Test]
public void PreferredWidthHeightAreCorrectWithNoImage()
{
Assert.AreEqual(0, m_Image.preferredWidth);
Assert.AreEqual(0, m_Image.preferredHeight);
}
[Test]
public void MinWidthHeightAreZeroWithImage()
{
m_Image.sprite = m_Sprite;
Assert.AreEqual(0, m_Image.minWidth);
Assert.AreEqual(0, m_Image.minHeight);
}
[Test]
public void FlexibleWidthHeightAreCorrectWithImage()
{
m_Image.sprite = m_Sprite;
Assert.AreEqual(-1, m_Image.flexibleWidth);
Assert.AreEqual(-1, m_Image.flexibleHeight);
}
[Test]
public void PreferredWidthHeightAreCorrectWithImage()
{
m_Image.sprite = m_Sprite;
Assert.AreEqual(128, m_Image.preferredWidth);
Assert.AreEqual(128, m_Image.preferredHeight);
}
[Test]
public void MinWidthHeightAreZeroWithOverrideImage()
{
m_Image.sprite = m_Sprite;
m_Image.overrideSprite = m_OverrideSprite;
Assert.AreEqual(0, m_Image.minWidth);
Assert.AreEqual(0, m_Image.minHeight);
}
[Test]
public void FlexibleWidthHeightAreCorrectWithOverrideImage()
{
m_Image.sprite = m_Sprite;
m_Image.overrideSprite = m_OverrideSprite;
Assert.AreEqual(-1, m_Image.flexibleWidth);
Assert.AreEqual(-1, m_Image.flexibleHeight);
}
[Test]
public void PreferredWidthHeightAreCorrectWithOverrideImage()
{
m_Image.sprite = m_Sprite;
m_Image.overrideSprite = m_OverrideSprite;
Assert.AreEqual(256, m_Image.preferredWidth);
Assert.AreEqual(256, m_Image.preferredHeight);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a0bae4ff8f5baf64aad3b92b8aea0603
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,163 @@
using System.Collections;
using System.Collections.Generic;
using System.IO;
using NUnit.Framework;
using UnityEditor;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.TestTools;
using UnityEngine.UI;
namespace Graphics
{
class MaskTests : IPrebuildSetup
{
GameObject m_PrefabRoot;
const string kPrefabPath = "Assets/Resources/MaskTestsPrefab.prefab";
Mask m_mask;
public void Setup()
{
#if UNITY_EDITOR
var rootGO = new GameObject("rootGo");
GameObject canvasGO = new GameObject("Canvas", typeof(RectTransform), typeof(Canvas));
canvasGO.transform.SetParent(rootGO.transform);
var canvas = canvasGO.GetComponent<Canvas>();
canvas.referencePixelsPerUnit = 100;
var gameObject = new GameObject("Mask", typeof(RectTransform), typeof(Mask), typeof(Image));
gameObject.transform.SetParent(canvasGO.transform);
if (!Directory.Exists("Assets/Resources/"))
Directory.CreateDirectory("Assets/Resources/");
PrefabUtility.SaveAsPrefabAsset(rootGO, kPrefabPath);
GameObject.DestroyImmediate(rootGO);
#endif
}
[SetUp]
public void TestSetup()
{
m_PrefabRoot = Object.Instantiate(Resources.Load("MaskTestsPrefab")) as GameObject;
m_mask = m_PrefabRoot.GetComponentInChildren<Mask>();
}
[TearDown]
public void TearDown()
{
m_mask = null;
Object.DestroyImmediate(m_PrefabRoot);
}
[OneTimeTearDown]
public void OneTimeTearDown()
{
#if UNITY_EDITOR
AssetDatabase.DeleteAsset(kPrefabPath);
#endif
}
[UnityTest]
public IEnumerator GetModifiedMaterialReturnsOriginalMaterialWhenNoGraphicComponentIsAttached()
{
Object.DestroyImmediate(m_mask.gameObject.GetComponent<Image>());
yield return null;
Material material = new Material(Graphic.defaultGraphicMaterial);
Material modifiedMaterial = m_mask.GetModifiedMaterial(material);
Assert.AreEqual(material, modifiedMaterial);
}
private Dictionary<string, GameObject> CreateMaskHierarchy(string suffix, int hierarchyDepth, out GameObject root)
{
var nameToObjectMapping = new Dictionary<string, GameObject>();
root = new GameObject("root", typeof(RectTransform), typeof(Canvas));
nameToObjectMapping["root"] = root;
GameObject current = root;
for (int i = 0; i < hierarchyDepth; i++)
{
string name = suffix + (i + 1);
var gameObject = new GameObject(name, typeof(RectTransform), typeof(Mask), typeof(Image));
gameObject.transform.SetParent(current.transform);
nameToObjectMapping[name] = gameObject;
current = gameObject;
}
return nameToObjectMapping;
}
[Test]
public void GetModifiedMaterialReturnsOriginalMaterialWhenDepthIsEightOrMore()
{
GameObject root;
var objectsMap = CreateMaskHierarchy("subMask", 9, out root);
Mask mask = objectsMap["subMask" + 9].GetComponent<Mask>();
Material material = new Material(Graphic.defaultGraphicMaterial);
Material modifiedMaterial = mask.GetModifiedMaterial(material);
Assert.AreEqual(material, modifiedMaterial);
GameObject.DestroyImmediate(root);
}
[Test]
public void GetModifiedMaterialReturnsDesiredMaterialWithSingleMask()
{
Material material = new Material(Graphic.defaultGraphicMaterial);
Material modifiedMaterial = m_mask.GetModifiedMaterial(material);
Assert.AreNotEqual(material, modifiedMaterial);
Assert.AreEqual(1, modifiedMaterial.GetInt("_Stencil"));
Assert.AreEqual(StencilOp.Replace, (StencilOp)modifiedMaterial.GetInt("_StencilOp"));
Assert.AreEqual(CompareFunction.Always, (CompareFunction)modifiedMaterial.GetInt("_StencilComp"));
Assert.AreEqual(255, modifiedMaterial.GetInt("_StencilReadMask"));
Assert.AreEqual(255, modifiedMaterial.GetInt("_StencilWriteMask"));
Assert.AreEqual(ColorWriteMask.All, (ColorWriteMask)modifiedMaterial.GetInt("_ColorMask"));
Assert.AreEqual(1, modifiedMaterial.GetInt("_UseUIAlphaClip"));
Assert.IsTrue(modifiedMaterial.IsKeywordEnabled("UNITY_UI_ALPHACLIP"));
}
[Test]
public void GetModifiedMaterialReturnsDesiredMaterialWithMultipleMasks()
{
for (int i = 2; i < 8; i++)
{
GameObject root;
var objectsMap = CreateMaskHierarchy("subMask", i, out root);
Mask mask = objectsMap["subMask" + i].GetComponent<Mask>();
int stencilDepth = MaskUtilities.GetStencilDepth(mask.transform, objectsMap["root"].transform);
int desiredStencilBit = 1 << stencilDepth;
Material material = new Material(Graphic.defaultGraphicMaterial);
Material modifiedMaterial = mask.GetModifiedMaterial(material);
int stencil = modifiedMaterial.GetInt("_Stencil");
Assert.AreNotEqual(material, modifiedMaterial);
Assert.AreEqual(desiredStencilBit | (desiredStencilBit - 1), stencil);
Assert.AreEqual(StencilOp.Replace, (StencilOp)modifiedMaterial.GetInt("_StencilOp"));
Assert.AreEqual(CompareFunction.Equal, (CompareFunction)modifiedMaterial.GetInt("_StencilComp"));
Assert.AreEqual(desiredStencilBit - 1, modifiedMaterial.GetInt("_StencilReadMask"));
Assert.AreEqual(desiredStencilBit | (desiredStencilBit - 1), modifiedMaterial.GetInt("_StencilWriteMask"));
Assert.AreEqual(ColorWriteMask.All, (ColorWriteMask)modifiedMaterial.GetInt("_ColorMask"));
Assert.AreEqual(1, modifiedMaterial.GetInt("_UseUIAlphaClip"));
Assert.IsTrue(modifiedMaterial.IsKeywordEnabled("UNITY_UI_ALPHACLIP"));
GameObject.DestroyImmediate(root);
}
}
[Test]
public void GraphicComponentWithMaskIsMarkedAsIsMaskingGraphicWhenEnabled()
{
var graphic = m_PrefabRoot.GetComponentInChildren<Image>();
Assert.AreEqual(true, graphic.isMaskingGraphic);
m_mask.enabled = false;
Assert.AreEqual(false, graphic.isMaskingGraphic);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b611b0a598aeada419afa9737807c598
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,169 @@
using System.Reflection;
using System.Collections;
using NUnit.Framework;
using UnityEngine.EventSystems;
using UnityEngine.TestTools;
namespace UnityEngine.UI.Tests
{
[TestFixture]
class NavigationTests
{
GameObject canvasRoot;
Selectable topLeftSelectable;
Selectable bottomLeftSelectable;
Selectable topRightSelectable;
Selectable bottomRightSelectable;
[SetUp]
public void TestSetup()
{
canvasRoot = new GameObject("Canvas", typeof(RectTransform), typeof(Canvas));
GameObject topLeftGO = new GameObject("topLeftGO", typeof(RectTransform), typeof(CanvasRenderer), typeof(Selectable));
topLeftGO.transform.SetParent(canvasRoot.transform);
(topLeftGO.transform as RectTransform).anchoredPosition = new Vector2(50, 200);
topLeftSelectable = topLeftGO.GetComponent<Selectable>();
GameObject bottomLeftGO = new GameObject("bottomLeftGO", typeof(RectTransform), typeof(CanvasRenderer), typeof(Selectable));
bottomLeftGO.transform.SetParent(canvasRoot.transform);
(bottomLeftGO.transform as RectTransform).anchoredPosition = new Vector2(50, 50);
bottomLeftSelectable = bottomLeftGO.GetComponent<Selectable>();
GameObject topRightGO = new GameObject("topRightGO", typeof(RectTransform), typeof(CanvasRenderer), typeof(Selectable));
topRightGO.transform.SetParent(canvasRoot.transform);
(topRightGO.transform as RectTransform).anchoredPosition = new Vector2(200, 200);
topRightSelectable = topRightGO.GetComponent<Selectable>();
GameObject bottomRightGO = new GameObject("bottomRightGO", typeof(RectTransform), typeof(CanvasRenderer), typeof(Selectable));
bottomRightGO.transform.SetParent(canvasRoot.transform);
(bottomRightGO.transform as RectTransform).anchoredPosition = new Vector2(200, 50);
bottomRightSelectable = bottomRightGO.GetComponent<Selectable>();
}
[TearDown]
public void TearDown()
{
GameObject.DestroyImmediate(canvasRoot);
}
[Test]
public void FindSelectableOnRight_ReturnsNextSelectableRightOfTarget()
{
Selectable selectableRightOfTopLeft = topLeftSelectable.FindSelectableOnRight();
Selectable selectableRightOfBottomLeft = bottomLeftSelectable.FindSelectableOnRight();
Assert.AreEqual(topRightSelectable, selectableRightOfTopLeft, "Wrong selectable to right of Top Left Selectable");
Assert.AreEqual(bottomRightSelectable, selectableRightOfBottomLeft, "Wrong selectable to right of Bottom Left Selectable");
}
[Test]
public void FindSelectableOnLeft_ReturnsNextSelectableLeftOfTarget()
{
Selectable selectableLeftOfTopRight = topRightSelectable.FindSelectableOnLeft();
Selectable selectableLeftOfBottomRight = bottomRightSelectable.FindSelectableOnLeft();
Assert.AreEqual(topLeftSelectable, selectableLeftOfTopRight, "Wrong selectable to left of Top Right Selectable");
Assert.AreEqual(bottomLeftSelectable, selectableLeftOfBottomRight, "Wrong selectable to left of Bottom Right Selectable");
}
[Test]
public void FindSelectableOnRDown_ReturnsNextSelectableBelowTarget()
{
Selectable selectableDownOfTopLeft = topLeftSelectable.FindSelectableOnDown();
Selectable selectableDownOfTopRight = topRightSelectable.FindSelectableOnDown();
Assert.AreEqual(bottomLeftSelectable, selectableDownOfTopLeft, "Wrong selectable to Bottom of Top Left Selectable");
Assert.AreEqual(bottomRightSelectable, selectableDownOfTopRight, "Wrong selectable to Bottom of top Right Selectable");
}
[Test]
public void FindSelectableOnUp_ReturnsNextSelectableAboveTarget()
{
Selectable selectableUpOfBottomLeft = bottomLeftSelectable.FindSelectableOnUp();
Selectable selectableUpOfBottomRight = bottomRightSelectable.FindSelectableOnUp();
Assert.AreEqual(topLeftSelectable, selectableUpOfBottomLeft, "Wrong selectable to Up of bottom Left Selectable");
Assert.AreEqual(topRightSelectable, selectableUpOfBottomRight, "Wrong selectable to Up of bottom Right Selectable");
}
[Test]
public void FindSelectableOnRight__WrappingEnabled_ReturnsFurthestSelectableOnLeft()
{
Navigation nav = topRightSelectable.navigation;
nav.wrapAround = true;
nav.mode = Navigation.Mode.Horizontal;
topRightSelectable.navigation = nav;
nav = bottomRightSelectable.navigation;
nav.wrapAround = true;
nav.mode = Navigation.Mode.Horizontal;
bottomRightSelectable.navigation = nav;
Selectable selectableRightOfTopRight = topRightSelectable.FindSelectableOnRight();
Selectable selectableRightOfBottomRight = bottomRightSelectable.FindSelectableOnRight();
Assert.AreEqual(bottomLeftSelectable, selectableRightOfTopRight, "Wrong selectable to right of Top Right Selectable");
Assert.AreEqual(topLeftSelectable, selectableRightOfBottomRight, "Wrong selectable to right of Bottom Right Selectable");
}
[Test]
public void FindSelectableOnLeft_WrappingEnabled_ReturnsFurthestSelectableOnRight()
{
Navigation nav = topLeftSelectable.navigation;
nav.wrapAround = true;
nav.mode = Navigation.Mode.Horizontal;
topLeftSelectable.navigation = nav;
nav = bottomLeftSelectable.navigation;
nav.wrapAround = true;
nav.mode = Navigation.Mode.Horizontal;
bottomLeftSelectable.navigation = nav;
Selectable selectableLeftOfTopLeft = topLeftSelectable.FindSelectableOnLeft();
Selectable selectableLeftOfBottomLeft = bottomLeftSelectable.FindSelectableOnLeft();
Assert.AreEqual(bottomRightSelectable, selectableLeftOfTopLeft, "Wrong selectable to left of Top Left Selectable");
Assert.AreEqual(topRightSelectable, selectableLeftOfBottomLeft, "Wrong selectable to left of Bottom Left Selectable");
}
[Test]
public void FindSelectableOnDown_WrappingEnabled_ReturnsFurthestSelectableAbove()
{
Navigation nav = bottomLeftSelectable.navigation;
nav.wrapAround = true;
nav.mode = Navigation.Mode.Vertical;
bottomLeftSelectable.navigation = nav;
nav = bottomRightSelectable.navigation;
nav.wrapAround = true;
nav.mode = Navigation.Mode.Vertical;
bottomRightSelectable.navigation = nav;
Selectable selectableDownOfBottomLeft = bottomLeftSelectable.FindSelectableOnDown();
Selectable selectableDownOfBottomRight = bottomRightSelectable.FindSelectableOnDown();
Assert.AreEqual(topRightSelectable, selectableDownOfBottomLeft, "Wrong selectable to Bottom of Bottom Left Selectable");
Assert.AreEqual(topLeftSelectable, selectableDownOfBottomRight, "Wrong selectable to Bottom of Bottom Right Selectable");
}
[Test]
public void FindSelectableOnUp_WrappingEnabled_ReturnsFurthestSelectableBelow()
{
Navigation nav = topLeftSelectable.navigation;
nav.wrapAround = true;
nav.mode = Navigation.Mode.Vertical;
topLeftSelectable.navigation = nav;
nav = topRightSelectable.navigation;
nav.wrapAround = true;
nav.mode = Navigation.Mode.Vertical;
topRightSelectable.navigation = nav;
Selectable selectableUpOfTopLeft = topLeftSelectable.FindSelectableOnUp();
Selectable selectableUpOfTopRight = topRightSelectable.FindSelectableOnUp();
Assert.AreEqual(bottomRightSelectable, selectableUpOfTopLeft, "Wrong selectable to Up of Top Left Selectable");
Assert.AreEqual(bottomLeftSelectable, selectableUpOfTopRight, "Wrong selectable to Up of Top Right Selectable");
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: aca0de4e74f6cdf41a449805f345a4f5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,77 @@
using System.Collections;
using System.IO;
using NUnit.Framework;
using UnityEditor;
using UnityEngine;
using UnityEngine.TestTools;
using UnityEngine.UI;
namespace Graphics
{
public class RawImageTest : IPrebuildSetup
{
private const int Width = 32;
private const int Height = 32;
private GameObject m_PrefabRoot;
private RawImageTestHook m_image;
private Texture2D m_defaultTexture;
const string kPrefabPath = "Assets/Resources/RawImageUpdatePrefab.prefab";
public void Setup()
{
#if UNITY_EDITOR
var rootGO = new GameObject("Root");
var canvasGO = new GameObject("Canvas", typeof(Canvas));
var canvas = canvasGO.GetComponent<Canvas>();
canvas.renderMode = RenderMode.WorldSpace;
canvasGO.transform.SetParent(rootGO.transform);
var imageGO = new GameObject("Image", typeof(RectTransform), typeof(RawImageTestHook));
var imageTransform = imageGO.GetComponent<RectTransform>();
imageTransform.SetParent(canvas.transform);
imageTransform.anchoredPosition = Vector2.zero;
if (!Directory.Exists("Assets/Resources/"))
Directory.CreateDirectory("Assets/Resources/");
PrefabUtility.SaveAsPrefabAsset(rootGO, kPrefabPath);
GameObject.DestroyImmediate(rootGO);
#endif
}
[SetUp]
public void TestSetup()
{
m_PrefabRoot = Object.Instantiate(Resources.Load("RawImageUpdatePrefab")) as GameObject;
m_image = m_PrefabRoot.transform.Find("Canvas/Image").GetComponent<RawImageTestHook>();
m_defaultTexture = new Texture2D(Width, Height);
m_image.texture = m_defaultTexture;
}
[UnityTest]
public IEnumerator Sprite_Material()
{
m_image.ResetTest();
// can test only on texture change, same texture is bypass by RawImage property
m_image.texture = new Texture2D(Width, Height);
yield return new WaitUntil(() => m_image.isGeometryUpdated);
// validate that layout change rebuild is called
Assert.IsTrue(m_image.isMaterialRebuild);
}
[TearDown]
public void TearDown()
{
GameObject.DestroyImmediate(m_PrefabRoot);
#if UNITY_EDITOR
AssetDatabase.DeleteAsset(kPrefabPath);
#endif
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: acfa3573efc38c844be021fdaa8cf8a6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,38 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class RawImageTestHook : RawImage
{
public bool isGeometryUpdated;
public bool isCacheUsed;
public bool isLayoutRebuild;
public bool isMaterialRebuild;
public void ResetTest()
{
isGeometryUpdated = false;
isLayoutRebuild = false;
isMaterialRebuild = false;
isCacheUsed = false;
}
public override void SetLayoutDirty()
{
base.SetLayoutDirty();
isLayoutRebuild = true;
}
public override void SetMaterialDirty()
{
base.SetMaterialDirty();
isMaterialRebuild = true;
}
protected override void UpdateGeometry()
{
base.UpdateGeometry();
isGeometryUpdated = true;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 40c83ba6a1a64cb4baac27028dd1acc1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,14 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class ToggleTestImageHook : Image
{
public float durationTween;
public override void CrossFadeColor(Color targetColor, float duration, bool ignoreTimeScale, bool useAlpha, bool useRGB)
{
durationTween = duration;
base.CrossFadeColor(targetColor, duration, ignoreTimeScale, useAlpha, useRGB);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5c004b1354944164fb076276c289afc1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 1091bc2ad06e3234aac2b2fa2841c09d
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,46 @@
using UnityEngine.UI;
using UnityEngine.TestTools;
using NUnit.Framework;
using System.Collections;
using UnityEngine;
[TestFixture]
[Category("RegressionTest")]
public class ImageFilledGenerateWork
{
GameObject m_CanvasGO;
GameObject m_ImageGO;
[SetUp]
public void SetUp()
{
m_CanvasGO = new GameObject("Canvas");
m_ImageGO = new GameObject("Image");
}
[Test]
public void ImageFilledGenerateWorks()
{
m_CanvasGO.AddComponent<Canvas>();
m_ImageGO.transform.SetParent(m_CanvasGO.transform);
var image = m_ImageGO.AddComponent<TestableImage>();
image.type = Image.Type.Filled;
var texture = new Texture2D(32, 32);
image.sprite = Sprite.Create(texture, new Rect(0, 0, 32, 32), Vector2.zero);
image.fillMethod = Image.FillMethod.Horizontal;
image.fillAmount = 0.5f;
// Generate the image data now.
VertexHelper vh = new VertexHelper();
// Image is a "TestableImage" which has the Assert in the GenerateImageData as we need to validate
// the data which is protected.
image.GenerateImageData(vh);
}
[TearDown]
public void TearDown()
{
GameObject.DestroyImmediate(m_CanvasGO);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1a70a790a43cd0d4a96f75746841f764
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,138 @@
using UnityEngine;
using UnityEngine.TestTools;
using NUnit.Framework;
using System.Collections;
using UnityEngine.UI;
using System.Reflection;
public class ImageTests
{
private const int Width = 32;
private const int Height = 32;
GameObject m_CanvasGO;
TestableImage m_Image;
private Texture2D m_defaultTexture;
private bool m_dirtyLayout;
private bool m_dirtyMaterial;
[SetUp]
public void SetUp()
{
m_CanvasGO = new GameObject("Canvas", typeof(Canvas));
GameObject imageObject = new GameObject("Image", typeof(TestableImage));
imageObject.transform.SetParent(m_CanvasGO.transform);
m_Image = imageObject.GetComponent<TestableImage>();
m_Image.RegisterDirtyLayoutCallback(() => m_dirtyLayout = true);
m_Image.RegisterDirtyMaterialCallback(() => m_dirtyMaterial = true);
m_defaultTexture = new Texture2D(Width, Height);
Color[] colors = new Color[Width * Height];
for (int i = 0; i < Width * Height; i++)
colors[i] = Color.magenta;
m_defaultTexture.Apply();
}
[Test]
public void TightMeshSpritePopulatedVertexHelperProperly()
{
Texture2D texture = new Texture2D(64, 64);
m_Image.sprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), new Vector2(0, 0));
m_Image.type = Image.Type.Simple;
m_Image.useSpriteMesh = true;
VertexHelper vh = new VertexHelper();
m_Image.GenerateImageData(vh);
Assert.AreEqual(vh.currentVertCount, m_Image.sprite.vertices.Length);
Assert.AreEqual(vh.currentIndexCount, m_Image.sprite.triangles.Length);
}
[UnityTest]
public IEnumerator CanvasCustomRefPixPerUnitToggleWillUpdateImageMesh()
{
var canvas = m_CanvasGO.GetComponent<Canvas>();
var canvasScaler = m_CanvasGO.AddComponent<CanvasScaler>();
canvasScaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize;
m_Image.transform.SetParent(m_CanvasGO.transform);
m_Image.type = Image.Type.Sliced;
var texture = new Texture2D(120, 120);
m_Image.sprite = Sprite.Create(texture, new Rect(0, 0, 120, 120), new Vector2(0.5f, 0.5f), 100, 1, SpriteMeshType.Tight, new Vector4(30, 30, 30, 30), true);
m_Image.fillCenter = true;
canvasScaler.referencePixelsPerUnit = 200;
yield return null; // skip frame to update canvas properly
//setup done
canvas.enabled = false;
yield return null;
canvas.enabled = true;
m_Image.isOnPopulateMeshCalled = false;
yield return null;
Assert.IsTrue(m_Image.isOnPopulateMeshCalled);
}
[UnityTest]
public IEnumerator Sprite_Layout()
{
m_Image.sprite = Sprite.Create(m_defaultTexture, new Rect(0, 0, Width, Height), Vector2.zero);
yield return null;
m_Image.isGeometryUpdated = false;
m_dirtyLayout = false;
var Texture = new Texture2D(Width * 2, Height * 2);
m_Image.sprite = Sprite.Create(Texture, new Rect(0, 0, Width, Height), Vector2.zero);
yield return new WaitUntil(() => m_Image.isGeometryUpdated);
// validate that layout change rebuil is not called
Assert.IsFalse(m_dirtyLayout);
m_Image.isGeometryUpdated = false;
m_dirtyLayout = false;
m_Image.sprite = Sprite.Create(Texture, new Rect(0, 0, Width / 2, Height / 2), Vector2.zero);
yield return new WaitUntil(() => m_Image.isGeometryUpdated);
// validate that layout change rebuil is called
Assert.IsTrue(m_dirtyLayout);
}
[UnityTest]
public IEnumerator Sprite_Material()
{
m_Image.sprite = Sprite.Create(m_defaultTexture, new Rect(0, 0, Width, Height), Vector2.zero);
yield return null;
m_Image.isGeometryUpdated = false;
m_dirtyMaterial = false;
m_Image.sprite = Sprite.Create(m_defaultTexture, new Rect(0, 0, Width / 2, Height / 2), Vector2.zero);
yield return new WaitUntil(() => m_Image.isGeometryUpdated);
// validate that material change rebuild is not called
Assert.IsFalse(m_dirtyMaterial);
m_Image.isGeometryUpdated = false;
m_dirtyMaterial = false;
var Texture = new Texture2D(Width * 2, Height * 2);
m_Image.sprite = Sprite.Create(Texture, new Rect(0, 0, Width / 2, Height / 2), Vector2.zero);
yield return new WaitUntil(() => m_Image.isGeometryUpdated);
// validate that layout change rebuil is called
Assert.IsTrue(m_dirtyMaterial);
}
[TearDown]
public void TearDown()
{
GameObject.DestroyImmediate(m_CanvasGO);
GameObject.DestroyImmediate(m_defaultTexture);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a598580d0cfc7224ebed8d2b627d9e00
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,28 @@
using NUnit.Framework;
using UnityEngine.UI;
using System.Reflection;
public class TestableImage : Image
{
public bool isOnPopulateMeshCalled = false;
public bool isGeometryUpdated = false;
// Hook into the mesh generation so we can do our check.
protected override void OnPopulateMesh(VertexHelper toFill)
{
base.OnPopulateMesh(toFill);
Assert.That(toFill.currentVertCount, Is.GreaterThan(0), "Expected the mesh to be filled but it was not. Should not have a mesh with zero vertices.");
isOnPopulateMeshCalled = true;
}
protected override void UpdateGeometry()
{
base.UpdateGeometry();
isGeometryUpdated = true;
}
public void GenerateImageData(VertexHelper vh)
{
OnPopulateMesh(vh);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9713795381722eb43b623dffba25d115
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 2a28c2fab6b1bb745a844ef6b908e7ee
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,82 @@
using System;
using System.Linq;
using NUnit.Framework;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.TestTools;
using System.Collections;
using System.IO;
using UnityEditor;
using UnityEngine.UI;
using System.Reflection;
namespace InputfieldTests
{
public class DesktopInputFieldTests : BaseInputFieldTests, IPrebuildSetup
{
protected const string kPrefabPath = "Assets/Resources/DesktopInputFieldPrefab.prefab";
public void Setup()
{
#if UNITY_EDITOR
CreateInputFieldAsset(kPrefabPath);
#endif
}
[SetUp]
public virtual void TestSetup()
{
m_PrefabRoot = UnityEngine.Object.Instantiate(Resources.Load("DesktopInputFieldPrefab")) as GameObject;
FieldInfo inputModule = typeof(EventSystem).GetField("m_CurrentInputModule", BindingFlags.NonPublic | BindingFlags.Instance);
inputModule.SetValue(m_PrefabRoot.GetComponentInChildren<EventSystem>(), m_PrefabRoot.GetComponentInChildren<FakeInputModule>());
}
[TearDown]
public virtual void TearDown()
{
GUIUtility.systemCopyBuffer = null;
FontUpdateTracker.UntrackText(m_PrefabRoot.GetComponentInChildren<Text>());
GameObject.DestroyImmediate(m_PrefabRoot);
}
[OneTimeTearDown]
public void OnetimeTearDown()
{
#if UNITY_EDITOR
AssetDatabase.DeleteAsset(kPrefabPath);
#endif
}
[Test]
[UnityPlatform(exclude = new[] { RuntimePlatform.Switch })] // Currently InputField.ActivateInputFieldInternal calls Switch SoftwareKeyboard screen ; without user input or a command to close the SoftwareKeyboard this blocks the tests suite
public void FocusOnPointerClickWithLeftButton()
{
InputField inputField = m_PrefabRoot.GetComponentInChildren<InputField>();
PointerEventData data = new PointerEventData(m_PrefabRoot.GetComponentInChildren<EventSystem>());
data.button = PointerEventData.InputButton.Left;
inputField.OnPointerClick(data);
MethodInfo lateUpdate = typeof(InputField).GetMethod("LateUpdate", BindingFlags.NonPublic | BindingFlags.Instance);
lateUpdate.Invoke(inputField, null);
Assert.IsTrue(inputField.isFocused);
}
[UnityTest]
public IEnumerator DoesNotFocusOnPointerClickWithRightOrMiddleButton()
{
InputField inputField = m_PrefabRoot.GetComponentInChildren<InputField>();
PointerEventData data = new PointerEventData(m_PrefabRoot.GetComponentInChildren<EventSystem>());
data.button = PointerEventData.InputButton.Middle;
inputField.OnPointerClick(data);
yield return null;
data.button = PointerEventData.InputButton.Right;
inputField.OnPointerClick(data);
yield return null;
Assert.IsFalse(inputField.isFocused);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e1b0ab339722791498cc804831a17ad3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,11 @@
using UnityEngine.EventSystems;
namespace InputfieldTests
{
public class FakeInputModule : BaseInputModule
{
public override void Process()
{
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 16c6414b77a90ff4098767dce485c495
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,294 @@
using System;
using System.Linq;
using NUnit.Framework;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.TestTools;
using System.Collections;
using System.IO;
using UnityEditor;
using UnityEngine.UI;
using System.Reflection;
namespace InputfieldTests
{
public class GenericInputFieldTests : BaseInputFieldTests, IPrebuildSetup
{
protected const string kPrefabPath = "Assets/Resources/GenericInputFieldPrefab.prefab";
public void Setup()
{
#if UNITY_EDITOR
CreateInputFieldAsset(kPrefabPath);
#endif
}
[SetUp]
public virtual void TestSetup()
{
m_PrefabRoot = UnityEngine.Object.Instantiate(Resources.Load("GenericInputFieldPrefab")) as GameObject;
}
[TearDown]
public virtual void TearDown()
{
FontUpdateTracker.UntrackText(m_PrefabRoot.GetComponentInChildren<Text>());
GameObject.DestroyImmediate(m_PrefabRoot);
}
[OneTimeTearDown]
public void OnetimeTearDown()
{
#if UNITY_EDITOR
AssetDatabase.DeleteAsset(kPrefabPath);
#endif
}
[UnityTest]
public IEnumerator CannotFocusIfNotTextComponent()
{
InputField inputField = m_PrefabRoot.GetComponentInChildren<InputField>();
BaseEventData eventData = new BaseEventData(m_PrefabRoot.GetComponentInChildren<EventSystem>());
inputField.textComponent = null;
inputField.OnSelect(eventData);
yield return null;
Assert.False(inputField.isFocused);
}
[UnityTest]
public IEnumerator CannotFocusIfNullFont()
{
InputField inputField = m_PrefabRoot.GetComponentInChildren<InputField>();
BaseEventData eventData = new BaseEventData(m_PrefabRoot.GetComponentInChildren<EventSystem>());
inputField.textComponent.font = null;
inputField.OnSelect(eventData);
yield return null;
Assert.False(inputField.isFocused);
}
[UnityTest]
public IEnumerator CannotFocusIfNotActive()
{
InputField inputField = m_PrefabRoot.GetComponentInChildren<InputField>();
BaseEventData eventData = new BaseEventData(m_PrefabRoot.GetComponentInChildren<EventSystem>());
inputField.enabled = false;
inputField.OnSelect(eventData);
yield return null;
Assert.False(inputField.isFocused);
}
[UnityTest]
public IEnumerator CannotFocusWithoutEventSystem()
{
InputField inputField = m_PrefabRoot.GetComponentInChildren<InputField>();
UnityEngine.Object.DestroyImmediate(m_PrefabRoot.GetComponentInChildren<FakeInputModule>());
yield return null;
UnityEngine.Object.DestroyImmediate(m_PrefabRoot.GetComponentInChildren<EventSystem>());
BaseEventData eventData = new BaseEventData(null);
yield return null;
inputField.OnSelect(eventData);
yield return null;
Assert.False(inputField.isFocused);
}
[Test]
[UnityPlatform(exclude = new[] { RuntimePlatform.Switch })] // Currently InputField.ActivateInputFieldInternal calls Switch SoftwareKeyboard screen ; without user input or a command to close the SoftwareKeyboard this blocks the tests suite
public void FocusesOnSelect()
{
InputField inputField = m_PrefabRoot.GetComponentInChildren<InputField>();
BaseEventData eventData = new BaseEventData(m_PrefabRoot.GetComponentInChildren<EventSystem>());
inputField.OnSelect(eventData);
MethodInfo lateUpdate = typeof(InputField).GetMethod("LateUpdate", BindingFlags.NonPublic | BindingFlags.Instance);
lateUpdate.Invoke(inputField, null);
Assert.True(inputField.isFocused);
}
[Test]
public void DoesNotFocusesOnSelectWhenShouldActivateOnSelect_IsFalse()
{
InputField inputField = m_PrefabRoot.GetComponentInChildren<InputField>();
inputField.shouldActivateOnSelect = false;
BaseEventData eventData = new BaseEventData(m_PrefabRoot.GetComponentInChildren<EventSystem>());
inputField.OnSelect(eventData);
MethodInfo lateUpdate = typeof(InputField).GetMethod("LateUpdate", BindingFlags.NonPublic | BindingFlags.Instance);
lateUpdate.Invoke(inputField, null);
Assert.False(inputField.isFocused);
}
[Test]
public void InputFieldSetTextWithoutNotifyWillNotNotify()
{
InputField i = m_PrefabRoot.GetComponentInChildren<InputField>();
i.text = "Hello";
bool calledOnValueChanged = false;
i.onValueChanged.AddListener(s => { calledOnValueChanged = true; });
i.SetTextWithoutNotify("Goodbye");
Assert.IsTrue(i.text == "Goodbye");
Assert.IsFalse(calledOnValueChanged);
}
[Test]
public void ContentTypeSetsValues()
{
InputField inputField = m_PrefabRoot.GetComponentInChildren<InputField>();
inputField.contentType = InputField.ContentType.Standard;
Assert.AreEqual(InputField.InputType.Standard, inputField.inputType);
Assert.AreEqual(TouchScreenKeyboardType.Default, inputField.keyboardType);
Assert.AreEqual(InputField.CharacterValidation.None, inputField.characterValidation);
inputField.contentType = InputField.ContentType.Autocorrected;
Assert.AreEqual(InputField.InputType.AutoCorrect, inputField.inputType);
Assert.AreEqual(TouchScreenKeyboardType.Default, inputField.keyboardType);
Assert.AreEqual(InputField.CharacterValidation.None, inputField.characterValidation);
inputField.contentType = InputField.ContentType.IntegerNumber;
Assert.AreEqual(InputField.LineType.SingleLine, inputField.lineType);
Assert.AreEqual(InputField.InputType.Standard, inputField.inputType);
Assert.AreEqual(TouchScreenKeyboardType.NumberPad, inputField.keyboardType);
Assert.AreEqual(InputField.CharacterValidation.Integer, inputField.characterValidation);
inputField.contentType = InputField.ContentType.DecimalNumber;
Assert.AreEqual(InputField.LineType.SingleLine, inputField.lineType);
Assert.AreEqual(InputField.InputType.Standard, inputField.inputType);
Assert.AreEqual(TouchScreenKeyboardType.NumbersAndPunctuation, inputField.keyboardType);
Assert.AreEqual(InputField.CharacterValidation.Decimal, inputField.characterValidation);
inputField.contentType = InputField.ContentType.Alphanumeric;
Assert.AreEqual(InputField.LineType.SingleLine, inputField.lineType);
Assert.AreEqual(InputField.InputType.Standard, inputField.inputType);
Assert.AreEqual(TouchScreenKeyboardType.ASCIICapable, inputField.keyboardType);
Assert.AreEqual(InputField.CharacterValidation.Alphanumeric, inputField.characterValidation);
inputField.contentType = InputField.ContentType.Name;
Assert.AreEqual(InputField.LineType.SingleLine, inputField.lineType);
Assert.AreEqual(InputField.InputType.Standard, inputField.inputType);
Assert.AreEqual(TouchScreenKeyboardType.NamePhonePad, inputField.keyboardType);
Assert.AreEqual(InputField.CharacterValidation.Name, inputField.characterValidation);
inputField.contentType = InputField.ContentType.EmailAddress;
Assert.AreEqual(InputField.LineType.SingleLine, inputField.lineType);
Assert.AreEqual(InputField.InputType.Standard, inputField.inputType);
Assert.AreEqual(TouchScreenKeyboardType.EmailAddress, inputField.keyboardType);
Assert.AreEqual(InputField.CharacterValidation.EmailAddress, inputField.characterValidation);
inputField.contentType = InputField.ContentType.Password;
Assert.AreEqual(InputField.LineType.SingleLine, inputField.lineType);
Assert.AreEqual(InputField.InputType.Password, inputField.inputType);
Assert.AreEqual(TouchScreenKeyboardType.Default, inputField.keyboardType);
Assert.AreEqual(InputField.CharacterValidation.None, inputField.characterValidation);
inputField.contentType = InputField.ContentType.Pin;
Assert.AreEqual(InputField.LineType.SingleLine, inputField.lineType);
Assert.AreEqual(InputField.InputType.Password, inputField.inputType);
Assert.AreEqual(TouchScreenKeyboardType.NumberPad, inputField.keyboardType);
Assert.AreEqual(InputField.CharacterValidation.Integer, inputField.characterValidation);
}
[Test]
public void SettingLineTypeDoesNotChangesContentTypeToCustom([Values(InputField.ContentType.Standard, InputField.ContentType.Autocorrected)] InputField.ContentType type)
{
InputField inputField = m_PrefabRoot.GetComponentInChildren<InputField>();
inputField.contentType = type;
inputField.lineType = InputField.LineType.MultiLineNewline;
Assert.AreEqual(type, inputField.contentType);
}
[Test]
public void SettingLineTypeChangesContentTypeToCustom()
{
InputField inputField = m_PrefabRoot.GetComponentInChildren<InputField>();
inputField.contentType = InputField.ContentType.Name;
inputField.lineType = InputField.LineType.MultiLineNewline;
Assert.AreEqual(InputField.ContentType.Custom, inputField.contentType);
}
[Test]
public void SettingInputChangesContentTypeToCustom()
{
InputField inputField = m_PrefabRoot.GetComponentInChildren<InputField>();
inputField.contentType = InputField.ContentType.Name;
inputField.inputType = InputField.InputType.Password;
Assert.AreEqual(InputField.ContentType.Custom, inputField.contentType);
}
[Test]
public void SettingCharacterValidationChangesContentTypeToCustom()
{
InputField inputField = m_PrefabRoot.GetComponentInChildren<InputField>();
inputField.contentType = InputField.ContentType.Name;
inputField.characterValidation = InputField.CharacterValidation.None;
Assert.AreEqual(InputField.ContentType.Custom, inputField.contentType);
}
[Test]
public void SettingKeyboardTypeChangesContentTypeToCustom()
{
InputField inputField = m_PrefabRoot.GetComponentInChildren<InputField>();
inputField.contentType = InputField.ContentType.Name;
inputField.keyboardType = TouchScreenKeyboardType.ASCIICapable;
Assert.AreEqual(InputField.ContentType.Custom, inputField.contentType);
}
[UnityTest]
public IEnumerator CaretRectSameSizeAsTextRect()
{
InputField inputfield = m_PrefabRoot.GetComponentInChildren<InputField>();
HorizontalLayoutGroup lg = inputfield.gameObject.AddComponent<HorizontalLayoutGroup>();
lg.childControlWidth = true;
lg.childControlHeight = false;
lg.childForceExpandWidth = true;
lg.childForceExpandHeight = true;
ContentSizeFitter csf = inputfield.gameObject.AddComponent<ContentSizeFitter>();
csf.horizontalFit = ContentSizeFitter.FitMode.PreferredSize;
csf.verticalFit = ContentSizeFitter.FitMode.Unconstrained;
inputfield.text = "Hello World!";
yield return new WaitForSeconds(1.0f);
Rect prevTextRect = inputfield.textComponent.rectTransform.rect;
Rect prevCaretRect = (inputfield.textComponent.transform.parent.GetChild(0) as RectTransform).rect;
inputfield.text = "Hello World!Hello World!Hello World!";
LayoutRebuilder.MarkLayoutForRebuild(inputfield.transform as RectTransform);
yield return new WaitForSeconds(1.0f);
Rect newTextRect = inputfield.textComponent.rectTransform.rect;
Rect newCaretRect = (inputfield.textComponent.transform.parent.GetChild(0) as RectTransform).rect;
Assert.IsFalse(prevTextRect == newTextRect);
Assert.IsTrue(prevTextRect == prevCaretRect);
Assert.IsFalse(prevCaretRect == newCaretRect);
Assert.IsTrue(newTextRect == newCaretRect);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 513613320b52fdb40a26dd5b73d89afe
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,54 @@
using System;
using System.Linq;
using NUnit.Framework;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.TestTools;
using System.Collections;
using System.IO;
using UnityEditor;
using UnityEngine.UI;
using System.Reflection;
namespace InputfieldTests
{
public class BaseInputFieldTests
{
protected GameObject m_PrefabRoot;
public void CreateInputFieldAsset(string prefabPath)
{
#if UNITY_EDITOR
var rootGO = new GameObject("rootGo");
var canvasGO = new GameObject("Canvas", typeof(Canvas));
canvasGO.transform.SetParent(rootGO.transform);
var canvas = canvasGO.GetComponent<Canvas>();
canvas.referencePixelsPerUnit = 100;
GameObject inputFieldGO = new GameObject("InputField", typeof(RectTransform), typeof(InputField));
inputFieldGO.transform.SetParent(canvasGO.transform);
GameObject textGO = new GameObject("Text", typeof(RectTransform), typeof(Text));
textGO.transform.SetParent(inputFieldGO.transform);
GameObject eventSystemGO = new GameObject("EventSystem", typeof(EventSystem), typeof(FakeInputModule));
eventSystemGO.transform.SetParent(rootGO.transform);
InputField inputField = inputFieldGO.GetComponent<InputField>();
inputField.interactable = true;
inputField.enabled = true;
inputField.textComponent = textGO.GetComponent<Text>();
inputField.textComponent.fontSize = 12;
inputField.textComponent.supportRichText = false;
if (!Directory.Exists("Assets/Resources/"))
Directory.CreateDirectory("Assets/Resources/");
PrefabUtility.SaveAsPrefabAsset(rootGO, prefabPath);
GameObject.DestroyImmediate(rootGO);
#endif
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3371106faf8d06f47a73979a3c8d82a1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

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