testss
This commit is contained in:
@@ -0,0 +1,149 @@
|
||||
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
|
||||
}
|
||||
|
||||
#region Press
|
||||
|
||||
[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);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Submit
|
||||
|
||||
[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);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Submit Transition
|
||||
|
||||
[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);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
@@ -0,0 +1,30 @@
|
||||
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; } }
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
@@ -0,0 +1,9 @@
|
||||
using UnityEngine;
|
||||
|
||||
public class BridgeScriptForRetainingObjects : MonoBehaviour
|
||||
{
|
||||
public const string bridgeObjectName = "BridgeGameObject";
|
||||
|
||||
public GameObject canvasGO;
|
||||
public GameObject nestedCanvasGO;
|
||||
}
|
@@ -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());
|
||||
}
|
||||
}
|
@@ -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);
|
||||
}
|
||||
}
|
@@ -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
|
||||
}
|
||||
}
|
@@ -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;
|
||||
}
|
||||
}
|
@@ -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");
|
||||
}
|
||||
}
|
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@@ -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
|
||||
}
|
||||
}
|
@@ -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
|
||||
}
|
||||
}
|
@@ -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);
|
||||
}
|
||||
}
|
@@ -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/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
|
||||
}
|
||||
}
|
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@@ -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
|
||||
}
|
||||
}
|
@@ -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;
|
||||
}
|
||||
}
|
@@ -0,0 +1,148 @@
|
||||
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);
|
||||
#endif
|
||||
}
|
||||
|
||||
[SetUp]
|
||||
public void TestSetup()
|
||||
{
|
||||
m_PrefabRoot = Object.Instantiate(Resources.Load("DropdownPrefab")) as GameObject;
|
||||
m_CameraGO = new GameObject("Camera", typeof(Camera));
|
||||
#if UNITY_EDITOR
|
||||
// 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
|
||||
}
|
||||
|
||||
// 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>();
|
||||
dropdown.Show();
|
||||
yield return null;
|
||||
var dropdownList = dropdown.transform.Find("Dropdown List");
|
||||
var dropdownListCanvas = dropdownList.GetComponentInChildren<Canvas>();
|
||||
Assert.AreEqual(rootCanvas.sortingLayerID, dropdownListCanvas.sortingLayerID);
|
||||
dropdown.Hide();
|
||||
yield return new WaitForSeconds(1f); // hide is not instantaneous
|
||||
rootCanvas.sortingLayerName = "test layer";
|
||||
dropdown.Show();
|
||||
yield return null;
|
||||
dropdownList = dropdown.transform.Find("Dropdown List");
|
||||
dropdownListCanvas = dropdownList.GetComponentInChildren<Canvas>();
|
||||
Assert.AreEqual(rootCanvas.sortingLayerID, dropdownListCanvas.sortingLayerID);
|
||||
}
|
||||
|
||||
// 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);
|
||||
#endif
|
||||
}
|
||||
}
|
@@ -0,0 +1,132 @@
|
||||
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 ");
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
Object.DestroyImmediate(m_Camera.gameObject);
|
||||
Object.DestroyImmediate(m_EventSystem.gameObject);
|
||||
Object.DestroyImmediate(m_Canvas.gameObject);
|
||||
}
|
||||
}
|
@@ -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);
|
||||
}
|
||||
}
|
@@ -0,0 +1,157 @@
|
||||
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;
|
||||
|
||||
[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;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
GameObject.DestroyImmediate(m_EventSystem.gameObject);
|
||||
GameObject.DestroyImmediate(m_Canvas.gameObject);
|
||||
}
|
||||
}
|
@@ -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.
|
||||
}
|
||||
}
|
@@ -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;
|
||||
}
|
||||
}
|
@@ -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;
|
||||
}
|
||||
}
|
@@ -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;
|
||||
}
|
||||
}
|
@@ -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);
|
||||
}
|
||||
}
|
@@ -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
|
||||
}
|
||||
}
|
@@ -0,0 +1,439 @@
|
||||
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 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(null);
|
||||
Assert.True(selectable.isStateHighlighted);
|
||||
selectable.interactable = false;
|
||||
selectable.InvokeOnPointerExit(null);
|
||||
selectable.interactable = true;
|
||||
Assert.False(selectable.isStateHighlighted);
|
||||
Assert.True(selectable.isStateNormal);
|
||||
}
|
||||
|
||||
[Test]// regression test 861736
|
||||
public void PointerEnterThenSetNotInteractableThenSetInteractableShouldStayHighlighted()
|
||||
{
|
||||
Assert.True(selectable.isStateNormal);
|
||||
selectable.InvokeOnPointerEnter(null);
|
||||
Assert.True(selectable.isStateHighlighted);
|
||||
selectable.interactable = false;
|
||||
selectable.interactable = true;
|
||||
Assert.True(selectable.isStateHighlighted);
|
||||
}
|
||||
|
||||
#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(null);
|
||||
Assert.True(selectable.isStateHighlighted);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void PointerEnterOnSelectedObjectShouldHighlight()
|
||||
{
|
||||
selectable.InvokeOnSelect(null);
|
||||
Assert.True(selectable.isStateSelected);
|
||||
selectable.InvokeOnPointerEnter(null);
|
||||
Assert.True(selectable.isStateHighlighted);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void PointerEnterAndRightClickShouldHighlightNotPress()
|
||||
{
|
||||
Assert.True(selectable.isStateNormal);
|
||||
selectable.InvokeOnPointerEnter(null);
|
||||
selectable.InvokeOnPointerDown(new PointerEventData(EventSystem.current)
|
||||
{
|
||||
button = PointerEventData.InputButton.Right
|
||||
});
|
||||
Assert.True(selectable.isStateHighlighted);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void PointerEnterAndRightClickShouldPress()
|
||||
{
|
||||
Assert.True(selectable.isStateNormal);
|
||||
selectable.InvokeOnPointerEnter(null);
|
||||
selectable.InvokeOnPointerDown(new PointerEventData(EventSystem.current));
|
||||
Assert.True(selectable.isStatePressed);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void PointerEnterLeftClickExitShouldPress()
|
||||
{
|
||||
Assert.True(selectable.isStateNormal);
|
||||
selectable.InvokeOnPointerEnter(null);
|
||||
selectable.InvokeOnPointerDown(new PointerEventData(EventSystem.current));
|
||||
selectable.InvokeOnPointerExit(null);
|
||||
Assert.True(selectable.isStatePressed);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void PointerEnterLeftClickExitReleaseShouldSelect()
|
||||
{
|
||||
Assert.True(selectable.isStateNormal);
|
||||
selectable.InvokeOnPointerEnter(null);
|
||||
selectable.InvokeOnPointerDown(new PointerEventData(EventSystem.current));
|
||||
selectable.InvokeOnPointerExit(null);
|
||||
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(null);
|
||||
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
|
||||
}
|
||||
}
|
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,517 @@
|
||||
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 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);
|
||||
}
|
||||
}
|
||||
}
|
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
@@ -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;
|
||||
}
|
||||
}
|
@@ -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);
|
||||
}
|
||||
}
|
@@ -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);
|
||||
}
|
||||
}
|
@@ -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);
|
||||
}
|
||||
}
|
@@ -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);
|
||||
}
|
||||
}
|
@@ -0,0 +1,81 @@
|
||||
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]
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
using UnityEngine.EventSystems;
|
||||
|
||||
namespace InputfieldTests
|
||||
{
|
||||
public class FakeInputModule : BaseInputModule
|
||||
{
|
||||
public override void Process()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,293 @@
|
||||
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]
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,216 @@
|
||||
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 TouchInputFieldTests : BaseInputFieldTests, IPrebuildSetup
|
||||
{
|
||||
protected const string kPrefabPath = "Assets/Resources/TouchInputFieldPrefab.prefab";
|
||||
|
||||
public void Setup()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
CreateInputFieldAsset(kPrefabPath);
|
||||
#endif
|
||||
}
|
||||
|
||||
[SetUp]
|
||||
public void TestSetup()
|
||||
{
|
||||
m_PrefabRoot = UnityEngine.Object.Instantiate(Resources.Load("TouchInputFieldPrefab")) 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 void TearDown()
|
||||
{
|
||||
InputField inputField = m_PrefabRoot.GetComponentInChildren<InputField>();
|
||||
TouchScreenKeyboard.hideInput = false;
|
||||
FontUpdateTracker.UntrackText(m_PrefabRoot.GetComponentInChildren<Text>());
|
||||
GameObject.DestroyImmediate(m_PrefabRoot);
|
||||
}
|
||||
|
||||
[OneTimeTearDown]
|
||||
public void OnetimeTearDown()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
AssetDatabase.DeleteAsset(kPrefabPath);
|
||||
#endif
|
||||
}
|
||||
|
||||
protected const string kDefaultInputStr = "foobar";
|
||||
|
||||
const string kEmailSpecialCharacters = "!#$%&'*+-/=?^_`{|}~";
|
||||
|
||||
public struct CharValidationTestData
|
||||
{
|
||||
public string input, output;
|
||||
public InputField.CharacterValidation validation;
|
||||
|
||||
public CharValidationTestData(string input, string output, InputField.CharacterValidation validation)
|
||||
{
|
||||
this.input = input;
|
||||
this.output = output;
|
||||
this.validation = validation;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
// these won't properly show up if test runners UI if we don't replace it
|
||||
string input = this.input.Replace(kEmailSpecialCharacters, "specialchars");
|
||||
string output = this.output.Replace(kEmailSpecialCharacters, "specialchars");
|
||||
return string.Format("input={0}, output={1}, validation={2}", input, output, validation);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCase("*Azé09", "*Azé09", InputField.CharacterValidation.None)]
|
||||
[TestCase("*Azé09?.", "Az09", InputField.CharacterValidation.Alphanumeric)]
|
||||
[TestCase("Abc10x", "10", InputField.CharacterValidation.Integer)]
|
||||
[TestCase("-10", "-10", InputField.CharacterValidation.Integer)]
|
||||
[TestCase("10.0", "100", InputField.CharacterValidation.Integer)]
|
||||
[TestCase("10.0", "10.0", InputField.CharacterValidation.Decimal)]
|
||||
[TestCase(" -10.0x", "-10.0", InputField.CharacterValidation.Decimal)]
|
||||
[TestCase("10,0", "10,0", InputField.CharacterValidation.Decimal)]
|
||||
[TestCase(" -10,0x", "-10,0", InputField.CharacterValidation.Decimal)]
|
||||
[TestCase("A10,0 ", "10,0", InputField.CharacterValidation.Decimal)]
|
||||
[TestCase("A'a aaa aaa", "A'a Aaa Aaa", InputField.CharacterValidation.Name)]
|
||||
[TestCase("Unity-Editor", "Unity-Editor", InputField.CharacterValidation.Name)]
|
||||
[TestCase("Unity--Editor", "Unity-Editor", InputField.CharacterValidation.Name)]
|
||||
[TestCase("-UnityEditor", "Unityeditor", InputField.CharacterValidation.Name)]
|
||||
[TestCase(" _JOHN* (Doe)", "John Doe", InputField.CharacterValidation.Name)]
|
||||
[TestCase("johndoe@unity3d.com", "johndoe@unity3d.com", InputField.CharacterValidation.EmailAddress)]
|
||||
[TestCase(">john doe\\@unity3d.com", "johndoe@unity3d.com", InputField.CharacterValidation.EmailAddress)]
|
||||
[TestCase(kEmailSpecialCharacters + "@unity3d.com", kEmailSpecialCharacters + "@unity3d.com", InputField.CharacterValidation.EmailAddress)]
|
||||
public void HonorsCharacterValidationSettingsAssignment(string input, string output, InputField.CharacterValidation validation)
|
||||
{
|
||||
InputField inputField = m_PrefabRoot.GetComponentInChildren<InputField>();
|
||||
inputField.characterValidation = validation;
|
||||
inputField.text = input;
|
||||
Assert.AreEqual(output, inputField.text, string.Format("Failed character validation: input ={0}, output ={1}, validation ={2}",
|
||||
input.Replace(kEmailSpecialCharacters, "specialchars"),
|
||||
output.Replace(kEmailSpecialCharacters, "specialchars"),
|
||||
validation));
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
[TestCase("*Azé09", "*Azé09", InputField.CharacterValidation.None, ExpectedResult = null)]
|
||||
[TestCase("*Azé09?.", "Az09", InputField.CharacterValidation.Alphanumeric, ExpectedResult = null)]
|
||||
[TestCase("Abc10x", "10", InputField.CharacterValidation.Integer, ExpectedResult = null)]
|
||||
[TestCase("-10", "-10", InputField.CharacterValidation.Integer, ExpectedResult = null)]
|
||||
[TestCase("10.0", "100", InputField.CharacterValidation.Integer, ExpectedResult = null)]
|
||||
[TestCase("10.0", "10.0", InputField.CharacterValidation.Decimal, ExpectedResult = null)]
|
||||
[TestCase(" -10.0x", "-10.0", InputField.CharacterValidation.Decimal, ExpectedResult = null)]
|
||||
[TestCase("10,0", "10,0", InputField.CharacterValidation.Decimal, ExpectedResult = null)]
|
||||
[TestCase(" -10,0x", "-10,0", InputField.CharacterValidation.Decimal, ExpectedResult = null)]
|
||||
[TestCase("A10,0 ", "10,0", InputField.CharacterValidation.Decimal, ExpectedResult = null)]
|
||||
[TestCase("A'a aaa aaa", "A'a Aaa Aaa", InputField.CharacterValidation.Name, ExpectedResult = null)]
|
||||
[TestCase(" _JOHN* (Doe)", "John Doe", InputField.CharacterValidation.Name, ExpectedResult = null)]
|
||||
[TestCase("johndoe@unity3d.com", "johndoe@unity3d.com", InputField.CharacterValidation.EmailAddress, ExpectedResult = null)]
|
||||
[TestCase(">john doe\\@unity3d.com", "johndoe@unity3d.com", InputField.CharacterValidation.EmailAddress, ExpectedResult = null)]
|
||||
[TestCase(kEmailSpecialCharacters + "@unity3d.com", kEmailSpecialCharacters + "@unity3d.com", InputField.CharacterValidation.EmailAddress, ExpectedResult = null)]
|
||||
public IEnumerator HonorsCharacterValidationSettingsTypingWithSelection(string input, string output, InputField.CharacterValidation validation)
|
||||
{
|
||||
if (!TouchScreenKeyboard.isSupported)
|
||||
yield break;
|
||||
InputField inputField = m_PrefabRoot.GetComponentInChildren<InputField>();
|
||||
BaseEventData eventData = new BaseEventData(m_PrefabRoot.GetComponentInChildren<EventSystem>());
|
||||
inputField.characterValidation = validation;
|
||||
inputField.text = input;
|
||||
|
||||
inputField.OnSelect(eventData);
|
||||
yield return null;
|
||||
|
||||
Assert.AreEqual(output, inputField.text, string.Format("Failed character validation: input ={0}, output ={1}, validation ={2}",
|
||||
input.Replace(kEmailSpecialCharacters, "specialchars"),
|
||||
output.Replace(kEmailSpecialCharacters, "specialchars"),
|
||||
validation));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AssignmentAgainstCharacterLimit([Values("ABC", "abcdefghijkl")] string text)
|
||||
{
|
||||
InputField inputField = m_PrefabRoot.GetComponentInChildren<InputField>();
|
||||
// test assignment
|
||||
inputField.characterLimit = 5;
|
||||
inputField.text = text;
|
||||
Assert.AreEqual(text.Substring(0, Math.Min(text.Length, inputField.characterLimit)), inputField.text);
|
||||
}
|
||||
|
||||
[Test] // regression test 793119
|
||||
public void AssignmentAgainstCharacterLimitWithContentType([Values("Abc", "Abcdefghijkl")] string text)
|
||||
{
|
||||
InputField inputField = m_PrefabRoot.GetComponentInChildren<InputField>();
|
||||
// test assignment
|
||||
inputField.characterLimit = 5;
|
||||
inputField.contentType = InputField.ContentType.Name;
|
||||
inputField.text = text;
|
||||
Assert.AreEqual(text.Substring(0, Math.Min(text.Length, inputField.characterLimit)), inputField.text);
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator SendsEndEditEventOnDeselect()
|
||||
{
|
||||
InputField inputField = m_PrefabRoot.GetComponentInChildren<InputField>();
|
||||
BaseEventData eventData = new BaseEventData(m_PrefabRoot.GetComponentInChildren<EventSystem>());
|
||||
inputField.OnSelect(eventData);
|
||||
yield return null;
|
||||
var called = false;
|
||||
inputField.onEndEdit.AddListener((s) => { called = true; });
|
||||
|
||||
inputField.OnDeselect(eventData);
|
||||
|
||||
Assert.IsTrue(called, "Expected invocation of onEndEdit");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void StripsNullCharacters2()
|
||||
{
|
||||
InputField inputField = m_PrefabRoot.GetComponentInChildren<InputField>();
|
||||
inputField.text = "a\0b";
|
||||
Assert.AreEqual("ab", inputField.text, "\\0 characters should be stripped");
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator FocusOpensTouchScreenKeyboard()
|
||||
{
|
||||
if (!TouchScreenKeyboard.isSupported)
|
||||
yield break;
|
||||
InputField inputField = m_PrefabRoot.GetComponentInChildren<InputField>();
|
||||
BaseEventData eventData = new BaseEventData(m_PrefabRoot.GetComponentInChildren<EventSystem>());
|
||||
inputField.OnSelect(eventData);
|
||||
yield return null;
|
||||
|
||||
Assert.NotNull(inputField.touchScreenKeyboard, "Expect a keyboard to be opened");
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator AssignsShouldHideInput()
|
||||
{
|
||||
if (Application.platform == RuntimePlatform.Android || Application.platform == RuntimePlatform.IPhonePlayer)
|
||||
{
|
||||
InputField inputField = m_PrefabRoot.GetComponentInChildren<InputField>();
|
||||
BaseEventData eventData = new BaseEventData(m_PrefabRoot.GetComponentInChildren<EventSystem>());
|
||||
|
||||
inputField.shouldHideMobileInput = false;
|
||||
|
||||
inputField.OnSelect(eventData);
|
||||
yield return null;
|
||||
|
||||
Assert.IsFalse(inputField.shouldHideMobileInput);
|
||||
Assert.IsFalse(TouchScreenKeyboard.hideInput, "Expect TouchScreenKeyboard.hideInput to be set");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,109 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using NUnit.Framework;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.TestTools;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.UI.Tests;
|
||||
|
||||
namespace LayoutTests
|
||||
{
|
||||
class AspectRatioFitterTests : IPrebuildSetup
|
||||
{
|
||||
const string kPrefabPath = "Assets/Resources/AspectRatioFitterTestsEnvelopeParent.prefab";
|
||||
const string kPrefabPath2 = "Assets/Resources/AspectRatioFitterTestsFitInParent.prefab";
|
||||
|
||||
private GameObject m_PrefabRoot;
|
||||
private AspectRatioFitter m_AspectRatioFitter;
|
||||
private RectTransform m_RectTransform;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
var cameraGo = new GameObject("Cam").AddComponent<Camera>();
|
||||
|
||||
var panelGO = new GameObject("PanelObject", typeof(RectTransform));
|
||||
var panelRT = panelGO.GetComponent<RectTransform>();
|
||||
panelRT.sizeDelta = new Vector2(200, 200);
|
||||
|
||||
var panelGO2 = new GameObject("PanelObject", typeof(RectTransform));
|
||||
var panelRT2 = panelGO2.GetComponent<RectTransform>();
|
||||
panelRT2.sizeDelta = new Vector2(200, 200);
|
||||
|
||||
var testGO = new GameObject("TestObject", typeof(RectTransform), typeof(AspectRatioFitter));
|
||||
var image = testGO.AddComponent<Image>();
|
||||
image.sprite = AssetDatabase.LoadAssetAtPath<Sprite>("Assets\\download.jpeg");
|
||||
m_AspectRatioFitter = testGO.GetComponent<AspectRatioFitter>();
|
||||
m_AspectRatioFitter.aspectMode = AspectRatioFitter.AspectMode.EnvelopeParent;
|
||||
m_AspectRatioFitter.aspectRatio = 1.5f;
|
||||
testGO.transform.SetParent(panelGO.transform);
|
||||
|
||||
var testGO2 = new GameObject("TestObject", typeof(RectTransform), typeof(AspectRatioFitter));
|
||||
var image2 = testGO2.AddComponent<Image>();
|
||||
image2.sprite = AssetDatabase.LoadAssetAtPath<Sprite>("Assets\\download.jpeg");
|
||||
m_AspectRatioFitter = testGO2.GetComponent<AspectRatioFitter>();
|
||||
m_AspectRatioFitter.aspectMode = AspectRatioFitter.AspectMode.FitInParent;
|
||||
m_AspectRatioFitter.aspectRatio = 1.5f;
|
||||
testGO2.transform.SetParent(panelGO2.transform);
|
||||
|
||||
var testRT = testGO.GetComponent<RectTransform>();
|
||||
testRT.sizeDelta = new Vector2(150, 100);
|
||||
|
||||
var testRT2 = testGO2.GetComponent<RectTransform>();
|
||||
testRT2.sizeDelta = new Vector2(150, 100);
|
||||
|
||||
if (!Directory.Exists("Assets/Resources/"))
|
||||
Directory.CreateDirectory("Assets/Resources/");
|
||||
|
||||
PrefabUtility.SaveAsPrefabAsset(panelGO, kPrefabPath);
|
||||
PrefabUtility.SaveAsPrefabAsset(panelGO2, kPrefabPath2);
|
||||
GameObject.DestroyImmediate(panelGO);
|
||||
GameObject.DestroyImmediate(panelGO2);
|
||||
#endif
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
GameObject.DestroyImmediate(m_PrefabRoot);
|
||||
m_PrefabRoot = null;
|
||||
m_AspectRatioFitter = null;
|
||||
m_RectTransform = null;
|
||||
}
|
||||
|
||||
[OneTimeTearDown]
|
||||
public void OneTimeTearDown()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
AssetDatabase.DeleteAsset(kPrefabPath);
|
||||
AssetDatabase.DeleteAsset(kPrefabPath2);
|
||||
#endif
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestEnvelopParent()
|
||||
{
|
||||
m_PrefabRoot = Object.Instantiate(Resources.Load("AspectRatioFitterTestsEnvelopeParent")) as GameObject;
|
||||
m_AspectRatioFitter = m_PrefabRoot.GetComponentInChildren<AspectRatioFitter>();
|
||||
|
||||
m_AspectRatioFitter.enabled = true;
|
||||
|
||||
m_RectTransform = m_AspectRatioFitter.GetComponent<RectTransform>();
|
||||
Assert.AreEqual(300, m_RectTransform.rect.width);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestFitInParent()
|
||||
{
|
||||
m_PrefabRoot = Object.Instantiate(Resources.Load("AspectRatioFitterTestsFitInParent")) as GameObject;
|
||||
m_AspectRatioFitter = m_PrefabRoot.GetComponentInChildren<AspectRatioFitter>();
|
||||
|
||||
m_AspectRatioFitter.enabled = true;
|
||||
|
||||
m_RectTransform = m_AspectRatioFitter.GetComponent<RectTransform>();
|
||||
Assert.AreEqual(200, m_RectTransform.rect.width);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,138 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using NUnit.Framework;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.TestTools;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.UI.Tests;
|
||||
|
||||
namespace LayoutTests
|
||||
{
|
||||
class ContentSizeFitterTests : IPrebuildSetup
|
||||
{
|
||||
const string kPrefabPath = "Assets/Resources/ContentSizeFitterTests.prefab";
|
||||
|
||||
private GameObject m_PrefabRoot;
|
||||
private ContentSizeFitter m_ContentSizeFitter;
|
||||
private RectTransform m_RectTransform;
|
||||
|
||||
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 testGO = new GameObject("TestObject", typeof(RectTransform), typeof(ContentSizeFitter));
|
||||
testGO.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("ContentSizeFitterTests")) as GameObject;
|
||||
m_ContentSizeFitter = m_PrefabRoot.GetComponentInChildren<ContentSizeFitter>();
|
||||
|
||||
m_ContentSizeFitter.enabled = true;
|
||||
|
||||
m_RectTransform = m_ContentSizeFitter.GetComponent<RectTransform>();
|
||||
m_RectTransform.sizeDelta = new Vector2(50, 50);
|
||||
|
||||
GameObject testObject = m_ContentSizeFitter.gameObject;
|
||||
// set up components
|
||||
var componentA = testObject.AddComponent<LayoutElement>();
|
||||
componentA.minWidth = 5;
|
||||
componentA.minHeight = 10;
|
||||
componentA.preferredWidth = 100;
|
||||
componentA.preferredHeight = 105;
|
||||
componentA.flexibleWidth = 0;
|
||||
componentA.flexibleHeight = 0;
|
||||
componentA.enabled = true;
|
||||
|
||||
var componentB = testObject.AddComponent<LayoutElement>();
|
||||
componentB.minWidth = 15;
|
||||
componentB.minHeight = 20;
|
||||
componentB.preferredWidth = 110;
|
||||
componentB.preferredHeight = 115;
|
||||
componentB.flexibleWidth = 0;
|
||||
componentB.flexibleHeight = 0;
|
||||
componentB.enabled = true;
|
||||
|
||||
var componentC = testObject.AddComponent<LayoutElement>();
|
||||
componentC.minWidth = 25;
|
||||
componentC.minHeight = 30;
|
||||
componentC.preferredWidth = 120;
|
||||
componentC.preferredHeight = 125;
|
||||
componentC.flexibleWidth = 0;
|
||||
componentC.flexibleHeight = 0;
|
||||
componentC.enabled = true;
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
GameObject.DestroyImmediate(m_PrefabRoot);
|
||||
m_PrefabRoot = null;
|
||||
m_ContentSizeFitter = null;
|
||||
m_RectTransform = null;
|
||||
}
|
||||
|
||||
[OneTimeTearDown]
|
||||
public void OneTimeTearDown()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
AssetDatabase.DeleteAsset(kPrefabPath);
|
||||
#endif
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestFitModeUnconstrained()
|
||||
{
|
||||
m_ContentSizeFitter.horizontalFit = ContentSizeFitter.FitMode.Unconstrained;
|
||||
m_ContentSizeFitter.verticalFit = ContentSizeFitter.FitMode.Unconstrained;
|
||||
|
||||
m_ContentSizeFitter.SetLayoutHorizontal();
|
||||
m_ContentSizeFitter.SetLayoutVertical();
|
||||
|
||||
Assert.AreEqual(50, m_RectTransform.rect.width);
|
||||
Assert.AreEqual(50, m_RectTransform.rect.height);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestFitModeMinSize()
|
||||
{
|
||||
m_ContentSizeFitter.horizontalFit = ContentSizeFitter.FitMode.MinSize;
|
||||
m_ContentSizeFitter.verticalFit = ContentSizeFitter.FitMode.MinSize;
|
||||
|
||||
m_ContentSizeFitter.SetLayoutHorizontal();
|
||||
m_ContentSizeFitter.SetLayoutVertical();
|
||||
|
||||
Assert.AreEqual(25, m_RectTransform.rect.width);
|
||||
Assert.AreEqual(30, m_RectTransform.rect.height);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestFitModePreferredSize()
|
||||
{
|
||||
m_ContentSizeFitter.horizontalFit = ContentSizeFitter.FitMode.PreferredSize;
|
||||
m_ContentSizeFitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
|
||||
|
||||
m_ContentSizeFitter.SetLayoutHorizontal();
|
||||
m_ContentSizeFitter.SetLayoutVertical();
|
||||
|
||||
Assert.AreEqual(120, m_RectTransform.rect.width);
|
||||
Assert.AreEqual(125, m_RectTransform.rect.height);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,385 @@
|
||||
using NUnit.Framework;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.TestTools;
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
|
||||
class GridLayoutGroupTests : IPrebuildSetup
|
||||
{
|
||||
const string kPrefabPath = "Assets/Resources/GridLayoutGroupTests.prefab";
|
||||
private GameObject m_PrefabRoot;
|
||||
private GridLayoutGroup m_LayoutGroup;
|
||||
|
||||
public void Setup()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
var rootGO = new GameObject("rootGo");
|
||||
|
||||
var canvasGO = new GameObject("Canvas");
|
||||
canvasGO.transform.SetParent(rootGO.transform);
|
||||
Canvas canvas = canvasGO.AddComponent<Canvas>();
|
||||
canvas.referencePixelsPerUnit = 100;
|
||||
|
||||
var groupGO = new GameObject("Group", typeof(RectTransform), typeof(GridLayoutGroup));
|
||||
groupGO.transform.SetParent(canvas.transform);
|
||||
|
||||
var rectTransform = groupGO.GetComponent<RectTransform>();
|
||||
rectTransform.sizeDelta = new Vector2(400, 500);
|
||||
rectTransform.anchoredPosition = new Vector2(0, 0);
|
||||
rectTransform.pivot = new Vector2(0, 0);
|
||||
|
||||
var layoutGroup = groupGO.GetComponent<GridLayoutGroup>();
|
||||
layoutGroup.spacing = new Vector2(10, 0);
|
||||
layoutGroup.startCorner = GridLayoutGroup.Corner.UpperLeft;
|
||||
layoutGroup.cellSize = new Vector2(90, 50);
|
||||
layoutGroup.constraint = GridLayoutGroup.Constraint.Flexible;
|
||||
layoutGroup.startAxis = GridLayoutGroup.Axis.Horizontal;
|
||||
layoutGroup.childAlignment = TextAnchor.UpperLeft;
|
||||
layoutGroup.enabled = false;
|
||||
layoutGroup.enabled = true;
|
||||
|
||||
var el1 = new GameObject("Element1");
|
||||
el1.transform.SetParent(rectTransform);
|
||||
var element1 = el1.AddComponent<LayoutElement>();
|
||||
(el1.transform as RectTransform).pivot = Vector2.zero;
|
||||
element1.minWidth = 5;
|
||||
element1.minHeight = 10;
|
||||
element1.preferredWidth = 100;
|
||||
element1.preferredHeight = 50;
|
||||
element1.flexibleWidth = 0;
|
||||
element1.flexibleHeight = 0;
|
||||
element1.enabled = true;
|
||||
|
||||
var el2 = new GameObject("Element2");
|
||||
el2.transform.SetParent(rectTransform);
|
||||
var element2 = el2.AddComponent<LayoutElement>();
|
||||
(el2.transform as RectTransform).pivot = Vector2.zero;
|
||||
element2.minWidth = 10;
|
||||
element2.minHeight = 5;
|
||||
element2.preferredWidth = -1;
|
||||
element2.preferredHeight = -1;
|
||||
element2.flexibleWidth = 0;
|
||||
element2.flexibleHeight = 0;
|
||||
element2.enabled = true;
|
||||
|
||||
var el3 = new GameObject("Element3");
|
||||
el3.transform.SetParent(rectTransform);
|
||||
var element3 = el3.AddComponent<LayoutElement>();
|
||||
(el3.transform as RectTransform).pivot = Vector2.zero;
|
||||
element3.minWidth = 60;
|
||||
element3.minHeight = 25;
|
||||
element3.preferredWidth = 120;
|
||||
element3.preferredHeight = 40;
|
||||
element3.flexibleWidth = 1;
|
||||
element3.flexibleHeight = 1;
|
||||
element3.enabled = true;
|
||||
|
||||
var el4 = new GameObject("Element4");
|
||||
el4.transform.SetParent(rectTransform);
|
||||
var element4 = el4.AddComponent<LayoutElement>();
|
||||
(el4.transform as RectTransform).pivot = Vector2.zero;
|
||||
element4.minWidth = 60;
|
||||
element4.minHeight = 25;
|
||||
element4.preferredWidth = 120;
|
||||
element4.preferredHeight = 40;
|
||||
element4.flexibleWidth = 1;
|
||||
element4.flexibleHeight = 1;
|
||||
element4.enabled = true;
|
||||
|
||||
var el5 = new GameObject("Element5");
|
||||
el5.transform.SetParent(rectTransform);
|
||||
var element5 = el5.AddComponent<LayoutElement>();
|
||||
(el5.transform as RectTransform).pivot = Vector2.zero;
|
||||
element5.minWidth = 60;
|
||||
element5.minHeight = 25;
|
||||
element5.preferredWidth = 120;
|
||||
element5.preferredHeight = 40;
|
||||
element5.flexibleWidth = 1;
|
||||
element5.flexibleHeight = 1;
|
||||
element5.enabled = true;
|
||||
|
||||
var el6 = new GameObject("Element6");
|
||||
el6.transform.SetParent(rectTransform);
|
||||
var element6 = el6.AddComponent<LayoutElement>();
|
||||
(el6.transform as RectTransform).pivot = Vector2.zero;
|
||||
element6.minWidth = 60;
|
||||
element6.minHeight = 25;
|
||||
element6.preferredWidth = 120;
|
||||
element6.preferredHeight = 40;
|
||||
element6.flexibleWidth = 1;
|
||||
element6.flexibleHeight = 1;
|
||||
element6.enabled = true;
|
||||
|
||||
var el7 = new GameObject("Element7");
|
||||
el7.transform.SetParent(rectTransform);
|
||||
var element7 = el7.AddComponent<LayoutElement>();
|
||||
(el7.transform as RectTransform).pivot = Vector2.zero;
|
||||
element7.minWidth = 60;
|
||||
element7.minHeight = 25;
|
||||
element7.preferredWidth = 120;
|
||||
element7.preferredHeight = 40;
|
||||
element7.flexibleWidth = 1;
|
||||
element7.flexibleHeight = 1;
|
||||
element7.enabled = true;
|
||||
|
||||
var el8 = new GameObject("Element8");
|
||||
el8.transform.SetParent(rectTransform);
|
||||
var element8 = el8.AddComponent<LayoutElement>();
|
||||
(el8.transform as RectTransform).pivot = Vector2.zero;
|
||||
element8.minWidth = 60;
|
||||
element8.minHeight = 25;
|
||||
element8.preferredWidth = 120;
|
||||
element8.preferredHeight = 40;
|
||||
element8.flexibleWidth = 1;
|
||||
element8.flexibleHeight = 1;
|
||||
element8.enabled = true;
|
||||
|
||||
var el9 = new GameObject("Element9");
|
||||
el9.transform.SetParent(rectTransform);
|
||||
var element9 = el9.AddComponent<LayoutElement>();
|
||||
(el9.transform as RectTransform).pivot = Vector2.zero;
|
||||
element9.minWidth = 500;
|
||||
element9.minHeight = 300;
|
||||
element9.preferredWidth = 1000;
|
||||
element9.preferredHeight = 600;
|
||||
element9.flexibleWidth = 1;
|
||||
element9.flexibleHeight = 1;
|
||||
element9.enabled = true;
|
||||
element9.ignoreLayout = true;
|
||||
|
||||
if (!Directory.Exists("Assets/Resources/"))
|
||||
Directory.CreateDirectory("Assets/Resources/");
|
||||
|
||||
PrefabUtility.SaveAsPrefabAsset(rootGO, kPrefabPath);
|
||||
GameObject.DestroyImmediate(rootGO);
|
||||
#endif
|
||||
}
|
||||
|
||||
[SetUp]
|
||||
public void TestSetup()
|
||||
{
|
||||
m_PrefabRoot = GameObject.Instantiate(Resources.Load("GridLayoutGroupTests")) as GameObject;
|
||||
m_LayoutGroup = m_PrefabRoot.GetComponentInChildren<GridLayoutGroup>();
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
GameObject.DestroyImmediate(m_PrefabRoot);
|
||||
m_LayoutGroup = null;
|
||||
}
|
||||
|
||||
[OneTimeTearDown]
|
||||
public void OneTimeTearDown()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
AssetDatabase.DeleteAsset(kPrefabPath);
|
||||
#endif
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestFlexibleCalculateLayout()
|
||||
{
|
||||
m_LayoutGroup.constraint = GridLayoutGroup.Constraint.Flexible;
|
||||
Assert.AreEqual(GridLayoutGroup.Constraint.Flexible, m_LayoutGroup.constraint);
|
||||
LayoutRebuilder.ForceRebuildLayoutImmediate(m_LayoutGroup.GetComponent<RectTransform>());
|
||||
|
||||
Assert.AreEqual(90, m_LayoutGroup.minWidth);
|
||||
Assert.AreEqual(100, m_LayoutGroup.minHeight);
|
||||
Assert.AreEqual(290, m_LayoutGroup.preferredWidth);
|
||||
Assert.AreEqual(100, m_LayoutGroup.preferredHeight);
|
||||
Assert.AreEqual(-1, m_LayoutGroup.flexibleWidth);
|
||||
Assert.AreEqual(-1, m_LayoutGroup.flexibleHeight);
|
||||
|
||||
Vector2[] expectedPositions =
|
||||
{
|
||||
new Vector2(0, -50),
|
||||
new Vector2(100, -50),
|
||||
new Vector2(200, -50),
|
||||
new Vector2(300, -50),
|
||||
new Vector2(0, -100),
|
||||
new Vector2(100, -100),
|
||||
new Vector2(200, -100),
|
||||
new Vector2(300, -100),
|
||||
};
|
||||
|
||||
Vector2 expectedSize = new Vector2(90, 50);
|
||||
|
||||
for (int i = 0; i < expectedPositions.Length; ++i)
|
||||
{
|
||||
var element = m_LayoutGroup.transform.Find("Element" + (i + 1));
|
||||
var rectTransform = element.GetComponent<RectTransform>();
|
||||
|
||||
Assert.AreEqual(expectedPositions[i], rectTransform.anchoredPosition);
|
||||
Assert.AreEqual(expectedSize, rectTransform.sizeDelta);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestHorizontallyContrainedCalculateLayoutHorizontal()
|
||||
{
|
||||
m_LayoutGroup.constraint = GridLayoutGroup.Constraint.FixedColumnCount;
|
||||
m_LayoutGroup.constraintCount = 2;
|
||||
Assert.AreEqual(GridLayoutGroup.Constraint.FixedColumnCount, m_LayoutGroup.constraint);
|
||||
Assert.AreEqual(2, m_LayoutGroup.constraintCount);
|
||||
LayoutRebuilder.ForceRebuildLayoutImmediate(m_LayoutGroup.GetComponent<RectTransform>());
|
||||
|
||||
Assert.AreEqual(190, m_LayoutGroup.minWidth);
|
||||
Assert.AreEqual(200, m_LayoutGroup.minHeight);
|
||||
Assert.AreEqual(190, m_LayoutGroup.preferredWidth);
|
||||
Assert.AreEqual(200, m_LayoutGroup.preferredHeight);
|
||||
Assert.AreEqual(-1, m_LayoutGroup.flexibleWidth);
|
||||
Assert.AreEqual(-1, m_LayoutGroup.flexibleHeight);
|
||||
|
||||
Vector2[] expectedPositions =
|
||||
{
|
||||
new Vector2(0, -50),
|
||||
new Vector2(100, -50),
|
||||
new Vector2(0, -100),
|
||||
new Vector2(100, -100),
|
||||
new Vector2(0, -150),
|
||||
new Vector2(100, -150),
|
||||
new Vector2(0, -200),
|
||||
new Vector2(100, -200),
|
||||
};
|
||||
|
||||
Vector2 expectedSize = new Vector2(90, 50);
|
||||
|
||||
for (int i = 0; i < expectedPositions.Length; ++i)
|
||||
{
|
||||
var element = m_LayoutGroup.transform.Find("Element" + (i + 1));
|
||||
var rectTransform = element.GetComponent<RectTransform>();
|
||||
|
||||
Assert.AreEqual(expectedPositions[i], rectTransform.anchoredPosition);
|
||||
Assert.AreEqual(expectedSize, rectTransform.sizeDelta);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestVerticallyContrainedCalculateLayoutHorizontal()
|
||||
{
|
||||
m_LayoutGroup.constraint = GridLayoutGroup.Constraint.FixedRowCount;
|
||||
m_LayoutGroup.constraintCount = 2;
|
||||
Assert.AreEqual(GridLayoutGroup.Constraint.FixedRowCount, m_LayoutGroup.constraint);
|
||||
Assert.AreEqual(2, m_LayoutGroup.constraintCount);
|
||||
LayoutRebuilder.ForceRebuildLayoutImmediate(m_LayoutGroup.GetComponent<RectTransform>());
|
||||
|
||||
Assert.AreEqual(390, m_LayoutGroup.minWidth);
|
||||
Assert.AreEqual(100, m_LayoutGroup.minHeight);
|
||||
Assert.AreEqual(390, m_LayoutGroup.preferredWidth);
|
||||
Assert.AreEqual(100, m_LayoutGroup.preferredHeight);
|
||||
Assert.AreEqual(-1, m_LayoutGroup.flexibleWidth);
|
||||
Assert.AreEqual(-1, m_LayoutGroup.flexibleHeight);
|
||||
|
||||
Vector2[] expectedPositions =
|
||||
{
|
||||
new Vector2(0, -50),
|
||||
new Vector2(100, -50),
|
||||
new Vector2(200, -50),
|
||||
new Vector2(300, -50),
|
||||
new Vector2(0, -100),
|
||||
new Vector2(100, -100),
|
||||
new Vector2(200, -100),
|
||||
new Vector2(300, -100),
|
||||
};
|
||||
|
||||
Vector2 expectedSize = new Vector2(90, 50);
|
||||
|
||||
for (int i = 0; i < expectedPositions.Length; ++i)
|
||||
{
|
||||
var element = m_LayoutGroup.transform.Find("Element" + (i + 1));
|
||||
var rectTransform = element.GetComponent<RectTransform>();
|
||||
|
||||
Assert.AreEqual(expectedPositions[i], rectTransform.anchoredPosition);
|
||||
Assert.AreEqual(expectedSize, rectTransform.sizeDelta);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestHorizontallyContrainedCalculateLayoutVertical()
|
||||
{
|
||||
m_LayoutGroup.constraint = GridLayoutGroup.Constraint.FixedColumnCount;
|
||||
m_LayoutGroup.constraintCount = 2;
|
||||
m_LayoutGroup.startAxis = GridLayoutGroup.Axis.Vertical;
|
||||
Assert.AreEqual(GridLayoutGroup.Constraint.FixedColumnCount, m_LayoutGroup.constraint);
|
||||
Assert.AreEqual(2, m_LayoutGroup.constraintCount);
|
||||
LayoutRebuilder.ForceRebuildLayoutImmediate(m_LayoutGroup.GetComponent<RectTransform>());
|
||||
|
||||
Assert.AreEqual(190, m_LayoutGroup.minWidth);
|
||||
Assert.AreEqual(200, m_LayoutGroup.minHeight);
|
||||
Assert.AreEqual(190, m_LayoutGroup.preferredWidth);
|
||||
Assert.AreEqual(200, m_LayoutGroup.preferredHeight);
|
||||
Assert.AreEqual(-1, m_LayoutGroup.flexibleWidth);
|
||||
Assert.AreEqual(-1, m_LayoutGroup.flexibleHeight);
|
||||
|
||||
Vector2[] expectedPositions =
|
||||
{
|
||||
new Vector2(0, -50),
|
||||
new Vector2(0, -100),
|
||||
new Vector2(0, -150),
|
||||
new Vector2(0, -200),
|
||||
new Vector2(100, -50),
|
||||
new Vector2(100, -100),
|
||||
new Vector2(100, -150),
|
||||
new Vector2(100, -200),
|
||||
};
|
||||
|
||||
Vector2 expectedSize = new Vector2(90, 50);
|
||||
|
||||
for (int i = 0; i < expectedPositions.Length; ++i)
|
||||
{
|
||||
var element = m_LayoutGroup.transform.Find("Element" + (i + 1));
|
||||
var rectTransform = element.GetComponent<RectTransform>();
|
||||
|
||||
Assert.AreEqual(expectedPositions[i], rectTransform.anchoredPosition);
|
||||
Assert.AreEqual(expectedSize, rectTransform.sizeDelta);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestVerticallyContrainedCalculateLayoutVertical()
|
||||
{
|
||||
m_LayoutGroup.constraint = GridLayoutGroup.Constraint.FixedRowCount;
|
||||
m_LayoutGroup.constraintCount = 2;
|
||||
m_LayoutGroup.startAxis = GridLayoutGroup.Axis.Vertical;
|
||||
m_LayoutGroup.startCorner = GridLayoutGroup.Corner.LowerRight;
|
||||
Assert.AreEqual(GridLayoutGroup.Constraint.FixedRowCount, m_LayoutGroup.constraint);
|
||||
Assert.AreEqual(2, m_LayoutGroup.constraintCount);
|
||||
m_LayoutGroup.CalculateLayoutInputHorizontal();
|
||||
m_LayoutGroup.SetLayoutHorizontal();
|
||||
m_LayoutGroup.CalculateLayoutInputVertical();
|
||||
m_LayoutGroup.SetLayoutVertical();
|
||||
|
||||
Assert.AreEqual(390, m_LayoutGroup.minWidth);
|
||||
Assert.AreEqual(100, m_LayoutGroup.minHeight);
|
||||
Assert.AreEqual(390, m_LayoutGroup.preferredWidth);
|
||||
Assert.AreEqual(100, m_LayoutGroup.preferredHeight);
|
||||
Assert.AreEqual(-1, m_LayoutGroup.flexibleWidth);
|
||||
Assert.AreEqual(-1, m_LayoutGroup.flexibleHeight);
|
||||
|
||||
Vector2[] expectedPositions =
|
||||
{
|
||||
new Vector2(300, -100),
|
||||
new Vector2(300, -50),
|
||||
new Vector2(200, -100),
|
||||
new Vector2(200, -50),
|
||||
new Vector2(100, -100),
|
||||
new Vector2(100, -50),
|
||||
new Vector2(0, -100),
|
||||
new Vector2(0, -50),
|
||||
};
|
||||
|
||||
Vector2 expectedSize = new Vector2(90, 50);
|
||||
|
||||
for (int i = 0; i < expectedPositions.Length; ++i)
|
||||
{
|
||||
var element = m_LayoutGroup.transform.Find("Element" + (i + 1));
|
||||
var rectTransform = element.GetComponent<RectTransform>();
|
||||
|
||||
Assert.AreEqual(expectedPositions[i], rectTransform.anchoredPosition);
|
||||
Assert.AreEqual(expectedSize, rectTransform.sizeDelta);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,165 @@
|
||||
using System.IO;
|
||||
using NUnit.Framework;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.TestTools;
|
||||
|
||||
|
||||
namespace LayoutTests
|
||||
{
|
||||
public class HorizontalLayoutGroupTests : IPrebuildSetup
|
||||
{
|
||||
GameObject m_PrefabRoot;
|
||||
const string kPrefabPath = "Assets/Resources/HorizontalLayoutGroupPrefab.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 groupGO = new GameObject("Group", typeof(RectTransform), typeof(HorizontalLayoutGroup));
|
||||
groupGO.transform.SetParent(canvasGO.transform);
|
||||
var horizontalLayoutGroup = groupGO.GetComponent<HorizontalLayoutGroup>();
|
||||
horizontalLayoutGroup.padding = new RectOffset(2, 4, 3, 5);
|
||||
horizontalLayoutGroup.spacing = 1;
|
||||
horizontalLayoutGroup.childForceExpandWidth = false;
|
||||
horizontalLayoutGroup.childForceExpandHeight = false;
|
||||
horizontalLayoutGroup.childControlWidth = true;
|
||||
horizontalLayoutGroup.childControlHeight = true;
|
||||
|
||||
var element1GO = new GameObject("Element1", typeof(RectTransform), typeof(LayoutElement));
|
||||
element1GO.transform.SetParent(groupGO.transform);
|
||||
var layoutElement1 = element1GO.GetComponent<LayoutElement>();
|
||||
layoutElement1.minWidth = 5;
|
||||
layoutElement1.minHeight = 10;
|
||||
layoutElement1.preferredWidth = 100;
|
||||
layoutElement1.preferredHeight = 50;
|
||||
layoutElement1.flexibleWidth = 0;
|
||||
layoutElement1.flexibleHeight = 0;
|
||||
|
||||
var element2GO = new GameObject("Element2", typeof(RectTransform), typeof(LayoutElement));
|
||||
element2GO.transform.SetParent(groupGO.transform);
|
||||
var layoutElement2 = element2GO.GetComponent<LayoutElement>();
|
||||
layoutElement2.minWidth = 10;
|
||||
layoutElement2.minHeight = 5;
|
||||
layoutElement2.preferredWidth = -1;
|
||||
layoutElement2.preferredHeight = -1;
|
||||
layoutElement2.flexibleWidth = 0;
|
||||
layoutElement2.flexibleHeight = 0;
|
||||
|
||||
var element3GO = new GameObject("Element3", typeof(RectTransform), typeof(LayoutElement));
|
||||
element3GO.transform.SetParent(groupGO.transform);
|
||||
var layoutElement3 = element3GO.GetComponent<LayoutElement>();
|
||||
layoutElement3.minWidth = 25;
|
||||
layoutElement3.minHeight = 15;
|
||||
layoutElement3.preferredWidth = 200;
|
||||
layoutElement3.preferredHeight = 80;
|
||||
layoutElement3.flexibleWidth = 1;
|
||||
layoutElement3.flexibleHeight = 1;
|
||||
|
||||
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("HorizontalLayoutGroupPrefab")) as GameObject;
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
GameObject.DestroyImmediate(m_PrefabRoot);
|
||||
}
|
||||
|
||||
[OneTimeTearDown]
|
||||
public void OneTimeTearDown()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
AssetDatabase.DeleteAsset(kPrefabPath);
|
||||
#endif
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestCalculateLayoutInputHorizontal()
|
||||
{
|
||||
HorizontalLayoutGroup layoutGroup = m_PrefabRoot.GetComponentInChildren<HorizontalLayoutGroup>();
|
||||
layoutGroup.CalculateLayoutInputHorizontal();
|
||||
layoutGroup.SetLayoutHorizontal();
|
||||
layoutGroup.CalculateLayoutInputVertical();
|
||||
layoutGroup.SetLayoutVertical();
|
||||
|
||||
Assert.AreEqual(48, layoutGroup.minWidth);
|
||||
Assert.AreEqual(318, layoutGroup.preferredWidth);
|
||||
Assert.AreEqual(1, layoutGroup.flexibleWidth);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestCalculateLayoutInputVertical()
|
||||
{
|
||||
HorizontalLayoutGroup layoutGroup = m_PrefabRoot.GetComponentInChildren<HorizontalLayoutGroup>();
|
||||
layoutGroup.CalculateLayoutInputHorizontal();
|
||||
layoutGroup.SetLayoutHorizontal();
|
||||
layoutGroup.CalculateLayoutInputVertical();
|
||||
layoutGroup.SetLayoutVertical();
|
||||
|
||||
Assert.AreEqual(23, layoutGroup.minHeight);
|
||||
Assert.AreEqual(88, layoutGroup.preferredHeight);
|
||||
Assert.AreEqual(1, layoutGroup.flexibleHeight);
|
||||
Assert.AreEqual(1, layoutGroup.flexibleHeight);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestCalculateLayoutHorizontal()
|
||||
{
|
||||
var parentGO = m_PrefabRoot.transform.GetChild(0).GetChild(0);
|
||||
var element1GO = parentGO.GetChild(0);
|
||||
var element1Trans = element1GO.GetComponent<RectTransform>();
|
||||
var element2GO = parentGO.GetChild(1);
|
||||
var element2Trans = element2GO.GetComponent<RectTransform>();
|
||||
var element3GO = parentGO.GetChild(2);
|
||||
var element3Trans = element3GO.GetComponent<RectTransform>();
|
||||
|
||||
HorizontalLayoutGroup layoutGroup = m_PrefabRoot.GetComponentInChildren<HorizontalLayoutGroup>();
|
||||
layoutGroup.CalculateLayoutInputHorizontal();
|
||||
layoutGroup.SetLayoutHorizontal();
|
||||
layoutGroup.CalculateLayoutInputVertical();
|
||||
layoutGroup.SetLayoutVertical();
|
||||
|
||||
Assert.AreEqual(13.6f, element1Trans.anchoredPosition.x, 0.1f);
|
||||
Assert.AreEqual(31.3f, element2Trans.anchoredPosition.x, 0.1f);
|
||||
Assert.AreEqual(66.6f, element3Trans.anchoredPosition.x, 0.1f);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestCalculateLayoutHorizontalReversed()
|
||||
{
|
||||
var parentGO = m_PrefabRoot.transform.GetChild(0).GetChild(0);
|
||||
var element1GO = parentGO.GetChild(0);
|
||||
var element1Trans = element1GO.GetComponent<RectTransform>();
|
||||
var element2GO = parentGO.GetChild(1);
|
||||
var element2Trans = element2GO.GetComponent<RectTransform>();
|
||||
var element3GO = parentGO.GetChild(2);
|
||||
var element3Trans = element3GO.GetComponent<RectTransform>();
|
||||
|
||||
HorizontalLayoutGroup layoutGroup = m_PrefabRoot.GetComponentInChildren<HorizontalLayoutGroup>();
|
||||
layoutGroup.reverseArrangement = true;
|
||||
layoutGroup.CalculateLayoutInputHorizontal();
|
||||
layoutGroup.SetLayoutHorizontal();
|
||||
layoutGroup.CalculateLayoutInputVertical();
|
||||
layoutGroup.SetLayoutVertical();
|
||||
|
||||
Assert.AreEqual(84.4f, element1Trans.anchoredPosition.x, 0.1f);
|
||||
Assert.AreEqual(66.7f, element2Trans.anchoredPosition.x, 0.1f);
|
||||
Assert.AreEqual(31.4f, element3Trans.anchoredPosition.x, 0.1f);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,103 @@
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using NUnit.Framework;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.TestTools;
|
||||
using UnityEngine.UI;
|
||||
|
||||
// test for case 879374 - Checks that layout group children scale properly when scaleWidth / scaleHeight are toggled
|
||||
namespace LayoutTests
|
||||
{
|
||||
public class LayoutGroupScaling : IPrebuildSetup
|
||||
{
|
||||
GameObject m_PrefabRoot;
|
||||
GameObject m_CameraGO;
|
||||
|
||||
const string kPrefabPath = "Assets/Resources/LayoutGroupScalingPrefab.prefab";
|
||||
|
||||
public void Setup()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
var rootGO = new GameObject("RootGO");
|
||||
var rootCanvasGO = new GameObject("Canvas", typeof(Canvas), typeof(CanvasScaler));
|
||||
rootCanvasGO.GetComponent<Canvas>().renderMode = RenderMode.ScreenSpaceOverlay;
|
||||
rootCanvasGO.transform.SetParent(rootGO.transform);
|
||||
|
||||
var layoutGroupGO = new GameObject("LayoutGroup");
|
||||
layoutGroupGO.transform.SetParent(rootCanvasGO.transform);
|
||||
HorizontalLayoutGroup layoutGroup = layoutGroupGO.AddComponent<HorizontalLayoutGroup>();
|
||||
layoutGroup.childControlHeight = true;
|
||||
layoutGroup.childControlWidth = true;
|
||||
ContentSizeFitter contentSizeFitter = layoutGroupGO.AddComponent<ContentSizeFitter>();
|
||||
contentSizeFitter.horizontalFit = ContentSizeFitter.FitMode.PreferredSize;
|
||||
contentSizeFitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
|
||||
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
var elementGO = new GameObject("image(" + i + ")", typeof(Image));
|
||||
var layoutElement = elementGO.AddComponent<LayoutElement>();
|
||||
layoutElement.preferredWidth = 50;
|
||||
layoutElement.preferredHeight = 50;
|
||||
elementGO.transform.localScale = new Vector3(0.5f, 0.5f, 0.5f);
|
||||
elementGO.transform.SetParent(layoutGroupGO.transform);
|
||||
}
|
||||
|
||||
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("LayoutGroupScalingPrefab")) as GameObject;
|
||||
m_CameraGO = new GameObject("Camera", typeof(Camera));
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator LayoutGroup_CorrectChildScaling()
|
||||
{
|
||||
GameObject layoutGroupGO = m_PrefabRoot.GetComponentInChildren<HorizontalLayoutGroup>().gameObject;
|
||||
Rect dimentions = (layoutGroupGO.transform as RectTransform).rect;
|
||||
layoutGroupGO.GetComponent<HorizontalLayoutGroup>().childScaleWidth = true;
|
||||
layoutGroupGO.GetComponent<HorizontalLayoutGroup>().childScaleHeight = true;
|
||||
yield return null;
|
||||
Rect newDimentions = (layoutGroupGO.transform as RectTransform).rect;
|
||||
Assert.IsTrue(Mathf.Approximately(dimentions.width * 0.5f, newDimentions.width));
|
||||
Assert.IsTrue(Mathf.Approximately(dimentions.height * 0.5f, newDimentions.height));
|
||||
yield return null;
|
||||
Object.DestroyImmediate(layoutGroupGO.GetComponent<HorizontalLayoutGroup>());
|
||||
VerticalLayoutGroup layoutGroup = layoutGroupGO.AddComponent<VerticalLayoutGroup>();
|
||||
layoutGroup.childControlHeight = true;
|
||||
layoutGroup.childControlWidth = true;
|
||||
yield return null;
|
||||
dimentions = (layoutGroupGO.transform as RectTransform).rect;
|
||||
layoutGroup.childScaleWidth = true;
|
||||
layoutGroup.childScaleHeight = true;
|
||||
yield return null;
|
||||
newDimentions = (layoutGroupGO.transform as RectTransform).rect;
|
||||
Assert.IsTrue(Mathf.Approximately(dimentions.width * 0.5f, newDimentions.width));
|
||||
Assert.IsTrue(Mathf.Approximately(dimentions.height * 0.5f, newDimentions.height));
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
Object.DestroyImmediate(m_PrefabRoot);
|
||||
GameObject.DestroyImmediate(m_CameraGO);
|
||||
}
|
||||
|
||||
[OneTimeTearDown]
|
||||
public void OneTimeTearDown()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
AssetDatabase.DeleteAsset(kPrefabPath);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,177 @@
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
using NUnit.Framework;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.TestTools;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.UI.Tests;
|
||||
|
||||
namespace LayoutTests
|
||||
{
|
||||
public class VerticalLayoutGroupTests : IPrebuildSetup
|
||||
{
|
||||
GameObject m_PrefabRoot;
|
||||
const string kPrefabPath = "Assets/Resources/VerticalLayoutGroupPrefab.prefab";
|
||||
|
||||
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 groupGO = new GameObject("Group", typeof(RectTransform), typeof(VerticalLayoutGroup));
|
||||
groupGO.transform.SetParent(canvasGO.transform);
|
||||
|
||||
var element1GO = new GameObject("Element1", typeof(RectTransform), typeof(LayoutElement));
|
||||
element1GO.transform.SetParent(groupGO.transform);
|
||||
|
||||
var element2GO = new GameObject("Element2", typeof(RectTransform), typeof(LayoutElement));
|
||||
element2GO.transform.SetParent(groupGO.transform);
|
||||
|
||||
var element3GO = new GameObject("Element3", typeof(RectTransform), typeof(LayoutElement));
|
||||
element3GO.transform.SetParent(groupGO.transform);
|
||||
|
||||
VerticalLayoutGroup layoutGroup = groupGO.GetComponent<VerticalLayoutGroup>();
|
||||
layoutGroup.padding = new RectOffset(2, 4, 3, 5);
|
||||
layoutGroup.spacing = 1;
|
||||
layoutGroup.childForceExpandWidth = false;
|
||||
layoutGroup.childForceExpandHeight = false;
|
||||
layoutGroup.childControlWidth = true;
|
||||
layoutGroup.childControlHeight = true;
|
||||
|
||||
var element1 = element1GO.GetComponent<LayoutElement>();
|
||||
element1.minWidth = 5;
|
||||
element1.minHeight = 10;
|
||||
element1.preferredWidth = 100;
|
||||
element1.preferredHeight = 50;
|
||||
element1.flexibleWidth = 0;
|
||||
element1.flexibleHeight = 0;
|
||||
element1.enabled = true;
|
||||
|
||||
var element2 = element2GO.GetComponent<LayoutElement>();
|
||||
element2.minWidth = 10;
|
||||
element2.minHeight = 5;
|
||||
element2.preferredWidth = -1;
|
||||
element2.preferredHeight = -1;
|
||||
element2.flexibleWidth = 0;
|
||||
element2.flexibleHeight = 0;
|
||||
element2.enabled = true;
|
||||
|
||||
var element3 = element3GO.GetComponent<LayoutElement>();
|
||||
element3.minWidth = 25;
|
||||
element3.minHeight = 15;
|
||||
element3.preferredWidth = 200;
|
||||
element3.preferredHeight = 80;
|
||||
element3.flexibleWidth = 1;
|
||||
element3.flexibleHeight = 1;
|
||||
element3.enabled = true;
|
||||
|
||||
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("VerticalLayoutGroupPrefab")) as GameObject;
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
Object.DestroyImmediate(m_PrefabRoot);
|
||||
}
|
||||
|
||||
[OneTimeTearDown]
|
||||
public void OneTimeTearDown()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
AssetDatabase.DeleteAsset(kPrefabPath);
|
||||
#endif
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestCalculateLayoutInputHorizontal()
|
||||
{
|
||||
var layoutGroup = m_PrefabRoot.GetComponentInChildren<VerticalLayoutGroup>();
|
||||
layoutGroup.CalculateLayoutInputHorizontal();
|
||||
layoutGroup.SetLayoutHorizontal();
|
||||
layoutGroup.CalculateLayoutInputVertical();
|
||||
layoutGroup.SetLayoutVertical();
|
||||
|
||||
Assert.AreEqual(31, layoutGroup.minWidth);
|
||||
Assert.AreEqual(206, layoutGroup.preferredWidth);
|
||||
Assert.AreEqual(1, layoutGroup.flexibleWidth);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestCalculateLayoutInputVertical()
|
||||
{
|
||||
var layoutGroup = m_PrefabRoot.GetComponentInChildren<VerticalLayoutGroup>();
|
||||
layoutGroup.CalculateLayoutInputHorizontal();
|
||||
layoutGroup.SetLayoutHorizontal();
|
||||
layoutGroup.CalculateLayoutInputVertical();
|
||||
layoutGroup.SetLayoutVertical();
|
||||
|
||||
Assert.AreEqual(40, layoutGroup.minHeight);
|
||||
Assert.AreEqual(145, layoutGroup.preferredHeight);
|
||||
Assert.AreEqual(1, layoutGroup.flexibleHeight);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestCalculateLayoutVertical()
|
||||
{
|
||||
var parentGO = m_PrefabRoot.transform.GetChild(0).GetChild(0);
|
||||
var element1GO = parentGO.GetChild(0);
|
||||
var element1Trans = element1GO.GetComponent<RectTransform>();
|
||||
var element2GO = parentGO.GetChild(1);
|
||||
var element2Trans = element2GO.GetComponent<RectTransform>();
|
||||
var element3GO = parentGO.GetChild(2);
|
||||
var element3Trans = element3GO.GetComponent<RectTransform>();
|
||||
|
||||
var layoutGroup = m_PrefabRoot.GetComponentInChildren<VerticalLayoutGroup>();
|
||||
layoutGroup.CalculateLayoutInputHorizontal();
|
||||
layoutGroup.SetLayoutHorizontal();
|
||||
layoutGroup.CalculateLayoutInputVertical();
|
||||
layoutGroup.SetLayoutVertical();
|
||||
|
||||
Assert.AreEqual(-19.4f, element1Trans.anchoredPosition.y, 0.1f);
|
||||
Assert.AreEqual(-39.4f, element2Trans.anchoredPosition.y, 0.1f);
|
||||
Assert.AreEqual(-68.9f, element3Trans.anchoredPosition.y, 0.1f);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestCalculateLayoutVerticalReversed()
|
||||
{
|
||||
var parentGO = m_PrefabRoot.transform.GetChild(0).GetChild(0);
|
||||
var element1GO = parentGO.GetChild(0);
|
||||
var element1Trans = element1GO.GetComponent<RectTransform>();
|
||||
var element2GO = parentGO.GetChild(1);
|
||||
var element2Trans = element2GO.GetComponent<RectTransform>();
|
||||
var element3GO = parentGO.GetChild(2);
|
||||
var element3Trans = element3GO.GetComponent<RectTransform>();
|
||||
|
||||
var layoutGroup = m_PrefabRoot.GetComponentInChildren<VerticalLayoutGroup>();
|
||||
layoutGroup.reverseArrangement = true;
|
||||
layoutGroup.CalculateLayoutInputHorizontal();
|
||||
layoutGroup.SetLayoutHorizontal();
|
||||
layoutGroup.CalculateLayoutInputVertical();
|
||||
layoutGroup.SetLayoutVertical();
|
||||
|
||||
|
||||
//Assert.AreEqual(-78.6f, element1Trans.anchoredPosition.y, 0.1f);
|
||||
Assert.AreEqual(-58.6f, element2Trans.anchoredPosition.y, 0.1f);
|
||||
Assert.AreEqual(-29.1f, element3Trans.anchoredPosition.y, 0.1f);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,94 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using NUnit.Framework;
|
||||
using UnityEngine;
|
||||
using UnityEngine.TestTools;
|
||||
using UnityEngine.UI;
|
||||
|
||||
[TestFixture]
|
||||
public class LayoutGroupArrangement
|
||||
{
|
||||
const float k_LayoutDefaultSize = 100f;
|
||||
|
||||
GameObject m_Canvas;
|
||||
GameObject m_LayoutGameObject;
|
||||
RectTransform m_Child1;
|
||||
RectTransform m_Child2;
|
||||
|
||||
[SetUp]
|
||||
public void TestSetup()
|
||||
{
|
||||
m_Canvas = new GameObject("Canvas", typeof(Canvas));
|
||||
m_LayoutGameObject = new GameObject("LayoutGroup", typeof(RectTransform));
|
||||
m_LayoutGameObject.transform.SetParent(m_Canvas.transform, false);
|
||||
m_LayoutGameObject.GetComponent<RectTransform>().sizeDelta =
|
||||
new Vector2(k_LayoutDefaultSize, k_LayoutDefaultSize);
|
||||
|
||||
m_Child1 = new GameObject("Child1").AddComponent<RectTransform>();
|
||||
m_Child1.SetParent(m_LayoutGameObject.transform, false);
|
||||
|
||||
m_Child2 = new GameObject("Child2").AddComponent<RectTransform>();
|
||||
m_Child2.SetParent(m_LayoutGameObject.transform, false);
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
[Category("RegressionTest")]
|
||||
[Description("Nested GameObjects without a Layout Element will effect a Layout Group's arrangement (case 1026779)")]
|
||||
public IEnumerator LayoutGroup_ShouldResizeChildren_AfterDisablingAndEnablingAnyChild(
|
||||
[Values(typeof(HorizontalLayoutGroup), typeof(VerticalLayoutGroup))]
|
||||
Type layoutGroup)
|
||||
{
|
||||
var layoutComponent = (HorizontalOrVerticalLayoutGroup)m_LayoutGameObject.AddComponent(layoutGroup);
|
||||
layoutComponent.childForceExpandHeight = true;
|
||||
layoutComponent.childForceExpandWidth = true;
|
||||
layoutComponent.childControlHeight = true;
|
||||
layoutComponent.childControlWidth = true;
|
||||
|
||||
Assert.That(m_LayoutGameObject.GetComponent<RectTransform>().sizeDelta,
|
||||
Is.EqualTo(Vector2.one * k_LayoutDefaultSize),
|
||||
"Layout's size should not change after adding the " + layoutGroup.Name);
|
||||
|
||||
yield return null;
|
||||
|
||||
// HorizontalLayoutGroup will rearrange the children to have width equal to half the layout's width.
|
||||
var expectedWidth = layoutGroup == typeof(HorizontalLayoutGroup)
|
||||
? k_LayoutDefaultSize / 2
|
||||
: k_LayoutDefaultSize;
|
||||
|
||||
// VerticalLayoutGroup will rearrange the children to have height equal to half the layout's height.
|
||||
var expectedHeight = layoutGroup == typeof(VerticalLayoutGroup) ? k_LayoutDefaultSize / 2 : k_LayoutDefaultSize;
|
||||
|
||||
Assert.That(m_Child1.sizeDelta.x, Is.EqualTo(expectedWidth),
|
||||
"Adding " + layoutGroup.Name + " did not resize the first child.");
|
||||
Assert.That(m_Child1.sizeDelta.y, Is.EqualTo(expectedHeight),
|
||||
"Adding " + layoutGroup.Name + " did not resize the first child.");
|
||||
Assert.That(m_Child2.sizeDelta, Is.EqualTo(m_Child1.sizeDelta), "Both children should be of the same size.");
|
||||
|
||||
// Disable the second child and verify that the first child is resized to have size equal to the layout's size.
|
||||
m_Child2.gameObject.SetActive(false);
|
||||
|
||||
yield return null;
|
||||
|
||||
Assert.That(m_Child1.sizeDelta.x, Is.EqualTo(k_LayoutDefaultSize),
|
||||
layoutGroup.Name + " did not resize the first child after disabling the second child.");
|
||||
Assert.That(m_Child1.sizeDelta.y, Is.EqualTo(k_LayoutDefaultSize),
|
||||
layoutGroup.Name + " did not resize the first child after disabling the second child.");
|
||||
|
||||
// Enable the second child and verify that the first child is resized to the expected width/height.
|
||||
m_Child2.gameObject.SetActive(true);
|
||||
|
||||
yield return null;
|
||||
|
||||
Assert.That(m_Child1.sizeDelta.x, Is.EqualTo(expectedWidth),
|
||||
layoutGroup.Name + " did not resize the first child after enabling the second child.");
|
||||
Assert.That(m_Child1.sizeDelta.y, Is.EqualTo(expectedHeight),
|
||||
layoutGroup.Name + " did not resize the first child after enabling the second child.");
|
||||
Assert.That(m_Child2.sizeDelta, Is.EqualTo(m_Child1.sizeDelta), "Both children should be of the same size.");
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
GameObject.DestroyImmediate(m_Canvas);
|
||||
}
|
||||
}
|
@@ -0,0 +1,109 @@
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.TestTools;
|
||||
using NUnit.Framework;
|
||||
using System.Collections;
|
||||
using UnityEditor;
|
||||
|
||||
/*
|
||||
This test checks that a maskableGraphic within a RectMask2D will be properly clipped.
|
||||
Test for case (1013182 - [RectMask2D] Child gameObject is masked if there are less than 2 corners of GO that matches RectMask's x position)
|
||||
*/
|
||||
namespace UnityEngine.UI.Tests
|
||||
{
|
||||
public class RectMask2DClipping : IPrebuildSetup
|
||||
{
|
||||
GameObject m_PrefabRoot;
|
||||
GameObject m_CameraGO;
|
||||
|
||||
const string kPrefabPath = "Assets/Resources/Mask2DRectCullingPrefab.prefab";
|
||||
|
||||
public void Setup()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
var rootGO = new GameObject("RootGO");
|
||||
var rootCanvasGO = new GameObject("Canvas", typeof(Canvas), typeof(CanvasScaler));
|
||||
rootCanvasGO.GetComponent<Canvas>().renderMode = RenderMode.ScreenSpaceOverlay;
|
||||
rootCanvasGO.transform.SetParent(rootGO.transform);
|
||||
|
||||
var maskGO = new GameObject("Mask", typeof(RectTransform), typeof(RectMask2D));
|
||||
var maskTransform = maskGO.GetComponent<RectTransform>();
|
||||
maskTransform.SetParent(rootCanvasGO.transform);
|
||||
maskTransform.localPosition = Vector3.zero;
|
||||
maskTransform.sizeDelta = new Vector2(200, 200);
|
||||
maskTransform.localScale = Vector3.one;
|
||||
|
||||
var imageGO = new GameObject("Image", typeof(RectTransform), typeof(ImageHook));
|
||||
var imageTransform = imageGO.GetComponent<RectTransform>();
|
||||
imageTransform.SetParent(maskTransform);
|
||||
imageTransform.localPosition = new Vector3(-125, 0, 0);
|
||||
imageTransform.sizeDelta = new Vector2(100, 100);
|
||||
imageTransform.localScale = Vector3.one;
|
||||
|
||||
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("Mask2DRectCullingPrefab")) as GameObject;
|
||||
m_CameraGO = new GameObject("Camera", typeof(Camera));
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator Mask2DRect_CorrectClipping()
|
||||
{
|
||||
//root->canvas->mask->image
|
||||
RectTransform t = m_PrefabRoot.transform.GetChild(0).GetChild(0).GetChild(0) as RectTransform;
|
||||
CanvasRenderer cr = t.GetComponent<CanvasRenderer>();
|
||||
bool cull = false;
|
||||
for (int i = 0; i < 360; i += 45)
|
||||
{
|
||||
t.localEulerAngles = new Vector3(0, 0, i);
|
||||
cull |= cr.cull;
|
||||
yield return null;
|
||||
}
|
||||
|
||||
Assert.IsFalse(cull);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Mask2DRect_NonZeroPaddingMasksProperly()
|
||||
{
|
||||
var mask = m_PrefabRoot.GetComponentInChildren<RectMask2D>();
|
||||
mask.padding = new Vector4(10, 10, 10, 10);
|
||||
|
||||
Canvas.ForceUpdateCanvases();
|
||||
|
||||
var image = m_PrefabRoot.GetComponentInChildren<ImageHook>();
|
||||
|
||||
// The mask rect is 200, and padding of 10 all around makes it so its 180 in size.
|
||||
Assert.AreEqual(180, image.cachedClipRect.height);
|
||||
Assert.AreEqual(180, image.cachedClipRect.width);
|
||||
|
||||
Assert.AreEqual(-90f, image.cachedClipRect.x);
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
Object.DestroyImmediate(m_PrefabRoot);
|
||||
GameObject.DestroyImmediate(m_CameraGO);
|
||||
}
|
||||
|
||||
[OneTimeTearDown]
|
||||
public void OneTimeTearDown()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
AssetDatabase.DeleteAsset(kPrefabPath);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,13 @@
|
||||
using NUnit.Framework;
|
||||
using UnityEngine;
|
||||
using UnityEngine.TestTools.Utils;
|
||||
|
||||
public class SceneWithNestedLayoutElementsLoadScript : MonoBehaviour
|
||||
{
|
||||
public bool isStartCalled { get; private set; }
|
||||
|
||||
protected void Start()
|
||||
{
|
||||
isStartCalled = true;
|
||||
}
|
||||
}
|
@@ -0,0 +1,171 @@
|
||||
using System;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.TestTools;
|
||||
using NUnit.Framework;
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
using UnityEditor;
|
||||
|
||||
[TestFixture]
|
||||
[Category("RegressionTest")]
|
||||
public class SceneWithNestedLayoutElementsLoad : IPrebuildSetup
|
||||
{
|
||||
Scene m_InitScene;
|
||||
const string aspectRatioFitterSceneName = "AspectRatioFitter";
|
||||
const string contentSizeFitterSceneName = "ContentSizeFitter";
|
||||
const string layoutGroupSceneName = "LayoutGroup";
|
||||
|
||||
public void Setup()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
Action aspectRatioFitterSceneCreation = delegate()
|
||||
{
|
||||
var canvasGO = new GameObject("Canvas", typeof(Canvas), typeof(CanvasScaler));
|
||||
var panelGO = new GameObject("Panel", typeof(UnityEngine.UI.Image), typeof(AspectRatioFitter));
|
||||
var imageGO = new GameObject("Image", typeof(UnityEngine.UI.RawImage), typeof(AspectRatioFitter));
|
||||
panelGO.transform.SetParent(canvasGO.transform);
|
||||
imageGO.transform.SetParent(panelGO.transform);
|
||||
|
||||
var panelARF = panelGO.GetComponent<AspectRatioFitter>();
|
||||
panelARF.aspectMode = AspectRatioFitter.AspectMode.EnvelopeParent;
|
||||
panelARF.aspectRatio = 1.98f;
|
||||
|
||||
var iamgeARF = imageGO.GetComponent<AspectRatioFitter>();
|
||||
iamgeARF.aspectMode = AspectRatioFitter.AspectMode.None;
|
||||
iamgeARF.aspectRatio = 1f;
|
||||
|
||||
new GameObject("GameObject", typeof(SceneWithNestedLayoutElementsLoadScript));
|
||||
};
|
||||
CreateSceneUtility.CreateScene(aspectRatioFitterSceneName, aspectRatioFitterSceneCreation);
|
||||
|
||||
Action contentSizeFitterSceneCreation = delegate()
|
||||
{
|
||||
var canvasGO = new GameObject("Canvas", typeof(Canvas), typeof(CanvasScaler));
|
||||
var panelGO = new GameObject("Panel", typeof(UnityEngine.UI.Image), typeof(ContentSizeFitter), typeof(LayoutElement));
|
||||
var imageGO = new GameObject("Image", typeof(UnityEngine.UI.RawImage), typeof(ContentSizeFitter), typeof(LayoutElement));
|
||||
panelGO.transform.SetParent(canvasGO.transform);
|
||||
imageGO.transform.SetParent(panelGO.transform);
|
||||
|
||||
var panelCSF = panelGO.GetComponent<ContentSizeFitter>();
|
||||
panelCSF.horizontalFit = ContentSizeFitter.FitMode.PreferredSize;
|
||||
panelCSF.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
|
||||
|
||||
var panelLE = panelGO.GetComponent<LayoutElement>();
|
||||
panelLE.preferredWidth = 200f;
|
||||
panelLE.preferredHeight = 200f;
|
||||
|
||||
var imageCSF = imageGO.GetComponent<ContentSizeFitter>();
|
||||
imageCSF.horizontalFit = ContentSizeFitter.FitMode.PreferredSize;
|
||||
imageCSF.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
|
||||
|
||||
var imageLE = imageGO.GetComponent<LayoutElement>();
|
||||
imageLE.preferredWidth = 100f;
|
||||
imageLE.preferredHeight = 100f;
|
||||
|
||||
new GameObject("GameObject", typeof(SceneWithNestedLayoutElementsLoadScript));
|
||||
};
|
||||
CreateSceneUtility.CreateScene(contentSizeFitterSceneName, contentSizeFitterSceneCreation);
|
||||
|
||||
Action layoutGroupSceneCreation = delegate()
|
||||
{
|
||||
var canvasGO = new GameObject("Canvas", typeof(Canvas), typeof(CanvasScaler), typeof(GridLayoutGroup));
|
||||
var panelGO = new GameObject("Panel (0)", typeof(UnityEngine.UI.Image), typeof(GridLayoutGroup), typeof(LayoutElement));
|
||||
var imageGOOne = new GameObject("Image", typeof(UnityEngine.UI.RawImage), typeof(LayoutElement));
|
||||
var imageGOTwo = new GameObject("Image", typeof(UnityEngine.UI.RawImage), typeof(LayoutElement));
|
||||
panelGO.transform.SetParent(canvasGO.transform);
|
||||
imageGOOne.transform.SetParent(panelGO.transform);
|
||||
imageGOTwo.transform.SetParent(panelGO.transform);
|
||||
|
||||
var panelLE = panelGO.GetComponent<LayoutElement>();
|
||||
panelLE.preferredWidth = 100f;
|
||||
panelLE.preferredHeight = 100f;
|
||||
|
||||
var imageOneLE = imageGOOne.GetComponent<LayoutElement>();
|
||||
imageOneLE.preferredWidth = 100f;
|
||||
imageOneLE.preferredHeight = 100f;
|
||||
|
||||
var imageTwoLE = imageGOOne.GetComponent<LayoutElement>();
|
||||
imageTwoLE.preferredWidth = 100f;
|
||||
imageTwoLE.preferredHeight = 100f;
|
||||
|
||||
// Duplicate the first panel we created.
|
||||
GameObject.Instantiate(panelGO, canvasGO.transform);
|
||||
|
||||
new GameObject("GameObject", typeof(SceneWithNestedLayoutElementsLoadScript));
|
||||
};
|
||||
CreateSceneUtility.CreateScene(layoutGroupSceneName, layoutGroupSceneCreation);
|
||||
#endif
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator SceneWithNestedAspectRatioFitterLoads()
|
||||
{
|
||||
AsyncOperation operation = SceneManager.LoadSceneAsync(aspectRatioFitterSceneName, LoadSceneMode.Additive);
|
||||
yield return operation;
|
||||
|
||||
SceneManager.SetActiveScene(SceneManager.GetSceneByName(aspectRatioFitterSceneName));
|
||||
var go = GameObject.Find("GameObject");
|
||||
var component = go.GetComponent<SceneWithNestedLayoutElementsLoadScript>();
|
||||
|
||||
yield return new WaitUntil(() => component.isStartCalled);
|
||||
|
||||
operation = SceneManager.UnloadSceneAsync(aspectRatioFitterSceneName);
|
||||
yield return operation;
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator SceneWithNestedContentSizeFitterLoads()
|
||||
{
|
||||
AsyncOperation operation = SceneManager.LoadSceneAsync(contentSizeFitterSceneName, LoadSceneMode.Additive);
|
||||
yield return operation;
|
||||
|
||||
SceneManager.SetActiveScene(SceneManager.GetSceneByName(contentSizeFitterSceneName));
|
||||
var go = GameObject.Find("GameObject");
|
||||
var component = go.GetComponent<SceneWithNestedLayoutElementsLoadScript>();
|
||||
|
||||
yield return new WaitUntil(() => component.isStartCalled);
|
||||
|
||||
operation = SceneManager.UnloadSceneAsync(contentSizeFitterSceneName);
|
||||
yield return operation;
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator SceneWithNestedLayoutGroupLoads()
|
||||
{
|
||||
AsyncOperation operation = SceneManager.LoadSceneAsync(layoutGroupSceneName, LoadSceneMode.Additive);
|
||||
yield return operation;
|
||||
|
||||
SceneManager.SetActiveScene(SceneManager.GetSceneByName(layoutGroupSceneName));
|
||||
var go = GameObject.Find("GameObject");
|
||||
var component = go.GetComponent<SceneWithNestedLayoutElementsLoadScript>();
|
||||
|
||||
yield return new WaitUntil(() => component.isStartCalled);
|
||||
|
||||
operation = SceneManager.UnloadSceneAsync(layoutGroupSceneName);
|
||||
yield return operation;
|
||||
}
|
||||
|
||||
[SetUp]
|
||||
public void TestSetup()
|
||||
{
|
||||
m_InitScene = SceneManager.GetActiveScene();
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
SceneManager.SetActiveScene(m_InitScene);
|
||||
}
|
||||
|
||||
[OneTimeTearDown]
|
||||
public void OnTimeTearDown()
|
||||
{
|
||||
//Manually add Assets/ and .unity as CreateSceneUtility does that for you.
|
||||
#if UNITY_EDITOR
|
||||
AssetDatabase.DeleteAsset("Assets/" + aspectRatioFitterSceneName + ".unity");
|
||||
AssetDatabase.DeleteAsset("Assets/" + contentSizeFitterSceneName + ".unity");
|
||||
AssetDatabase.DeleteAsset("Assets/" + layoutGroupSceneName + ".unity");
|
||||
#endif
|
||||
}
|
||||
}
|
@@ -0,0 +1,129 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.TestTools;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using NUnit.Framework;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEditor;
|
||||
|
||||
public class ScrollBarClamp : IPrebuildSetup
|
||||
{
|
||||
// This test tests that setting scrollBar.value will not be clamped (case 802330 - Scrollbar stops velocity of 'Scroll Rect' unexpectedly)
|
||||
GameObject m_PrefabRoot;
|
||||
GameObject m_CameraGO;
|
||||
|
||||
const string kPrefabPath = "Assets/Resources/ScrollBarClampPrefab.prefab";
|
||||
|
||||
public void Setup()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
var rootGO = new GameObject("RootGO");
|
||||
var rootCanvasGO = new GameObject("Canvas", typeof(Canvas));
|
||||
var canvas = rootCanvasGO.GetComponent<Canvas>();
|
||||
canvas.renderMode = RenderMode.ScreenSpaceOverlay;
|
||||
rootCanvasGO.transform.SetParent(rootGO.transform);
|
||||
|
||||
var scrollRectGo = new GameObject("Scroll View", typeof(RectTransform), typeof(ScrollRect), typeof(RectMask2D));
|
||||
var scrollRectTransform = scrollRectGo.GetComponent<RectTransform>();
|
||||
scrollRectTransform.SetParent(rootCanvasGO.transform);
|
||||
scrollRectTransform.anchorMin = Vector2.zero;
|
||||
scrollRectTransform.anchorMax = Vector2.one;
|
||||
scrollRectTransform.sizeDelta = Vector2.zero;
|
||||
scrollRectTransform.anchoredPosition = Vector2.zero;
|
||||
var scrollRect = scrollRectGo.GetComponent<ScrollRect>();
|
||||
scrollRect.movementType = ScrollRect.MovementType.Elastic;
|
||||
|
||||
var scrollbarGo = new GameObject("Scrollbar", typeof(RectTransform), typeof(Scrollbar));
|
||||
var scrollbarTransform = scrollbarGo.GetComponent<RectTransform>();
|
||||
scrollbarTransform.SetParent(scrollRectTransform);
|
||||
scrollbarTransform.anchorMin = new Vector2(1, 0);
|
||||
scrollbarTransform.anchorMax = new Vector2(1, 1);
|
||||
scrollbarTransform.anchoredPosition = Vector2.zero;
|
||||
scrollbarTransform.pivot = new Vector2(1, 0.5f);
|
||||
scrollbarTransform.sizeDelta = new Vector2(20, 0);
|
||||
var scrollbar = scrollbarGo.GetComponent<Scrollbar>();
|
||||
|
||||
scrollRect.verticalScrollbar = scrollbar;
|
||||
|
||||
var contentGo = new GameObject("Content", typeof(RectTransform), typeof(VerticalLayoutGroup));
|
||||
var contentTransform = contentGo.GetComponent<RectTransform>();
|
||||
contentTransform.SetParent(scrollRectTransform);
|
||||
contentTransform.anchorMin = new Vector2(0, 1);
|
||||
contentTransform.anchorMax = new Vector2(1, 1);
|
||||
contentTransform.anchoredPosition = Vector2.zero;
|
||||
contentTransform.pivot = new Vector2(0.5f, 1);
|
||||
contentTransform.sizeDelta = new Vector2(0, 1135);
|
||||
|
||||
scrollRect.content = contentTransform;
|
||||
|
||||
var layoutGroup = contentGo.GetComponent<VerticalLayoutGroup>();
|
||||
layoutGroup.padding = new RectOffset(10, 10, 0, 0);
|
||||
layoutGroup.childAlignment = TextAnchor.UpperLeft;
|
||||
layoutGroup.childControlHeight = true;
|
||||
layoutGroup.childControlWidth = true;
|
||||
layoutGroup.childForceExpandHeight = false;
|
||||
layoutGroup.childForceExpandWidth = false;
|
||||
|
||||
for (int i = 0; i < 20; i++)
|
||||
{
|
||||
var item = new GameObject("Item" + i, typeof(RectTransform), typeof(LayoutElement));
|
||||
var itemTransform = item.GetComponent<RectTransform>();
|
||||
itemTransform.pivot = new Vector2(0.5f, 1);
|
||||
itemTransform.SetParent(contentTransform);
|
||||
var layoutElement = item.GetComponent<LayoutElement>();
|
||||
layoutElement.minWidth = 620;
|
||||
layoutElement.minHeight = 100;
|
||||
layoutElement.preferredWidth = 620;
|
||||
layoutElement.preferredHeight = 100;
|
||||
}
|
||||
|
||||
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("ScrollBarClampPrefab")) as GameObject;
|
||||
m_CameraGO = new GameObject("Camera", typeof(Camera));
|
||||
Canvas.ForceUpdateCanvases();
|
||||
}
|
||||
|
||||
//tests that setting the scrollbar value will not be clamped, but the private scrollbar functions will be clamped
|
||||
[Test]
|
||||
public void Scrollbar_clamp()
|
||||
{
|
||||
var scrollBar = m_PrefabRoot.GetComponentInChildren<Scrollbar>();
|
||||
scrollBar.value = 1.5f;
|
||||
Assert.Greater(scrollBar.value, 1f);
|
||||
scrollBar.value = -0.5f;
|
||||
Assert.Less(scrollBar.value, 0f);
|
||||
MethodInfo method = typeof(Scrollbar).GetMethod("DoUpdateDrag", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
method.Invoke(scrollBar, new object[] { new Vector2(1.5f, 1.5f), 1f });
|
||||
Assert.LessOrEqual(scrollBar.value, 1f);
|
||||
method.Invoke(scrollBar, new object[] { new Vector2(-0.5f, -0.5f), 1f });
|
||||
Assert.GreaterOrEqual(scrollBar.value, 0f);
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
Object.DestroyImmediate(m_PrefabRoot);
|
||||
GameObject.DestroyImmediate(m_CameraGO);
|
||||
}
|
||||
|
||||
[OneTimeTearDown]
|
||||
public void OneTimeTearDown()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
AssetDatabase.DeleteAsset(kPrefabPath);
|
||||
#endif
|
||||
}
|
||||
}
|
@@ -0,0 +1,64 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using NUnit.Framework;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.TestTools;
|
||||
using UnityEngine.UI;
|
||||
|
||||
public class ScrollBarTests : IPrebuildSetup
|
||||
{
|
||||
GameObject m_PrefabRoot;
|
||||
const string kPrefabPath = "Assets/Resources/ScrollBarPrefab.prefab";
|
||||
|
||||
public void Setup()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
var rootGO = new GameObject("rootGo");
|
||||
|
||||
var canvasGO = new GameObject("Canvas", typeof(RectTransform), typeof(Canvas));
|
||||
canvasGO.transform.SetParent(rootGO.transform);
|
||||
|
||||
var scrollBarGo = new GameObject("ScrollBar", typeof(Scrollbar));
|
||||
scrollBarGo.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 = UnityEngine.Object.Instantiate(Resources.Load("ScrollBarPrefab")) as GameObject;
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ScrollBarSetValueWithoutNotifyWillNotNotify()
|
||||
{
|
||||
Scrollbar s = m_PrefabRoot.GetComponentInChildren<Scrollbar>();
|
||||
s.value = 0;
|
||||
|
||||
bool calledOnValueChanged = false;
|
||||
|
||||
s.onValueChanged.AddListener(b => { calledOnValueChanged = true; });
|
||||
|
||||
s.SetValueWithoutNotify(1);
|
||||
|
||||
Assert.IsTrue(s.value == 1);
|
||||
Assert.IsFalse(calledOnValueChanged);
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
GameObject.DestroyImmediate(m_PrefabRoot);
|
||||
#if UNITY_EDITOR
|
||||
AssetDatabase.DeleteAsset(kPrefabPath);
|
||||
#endif
|
||||
}
|
||||
}
|
@@ -0,0 +1,101 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.TestTools;
|
||||
using NUnit.Framework;
|
||||
using System.Collections;
|
||||
|
||||
public class ScrollRectClamp
|
||||
{
|
||||
// Prefab has the following hierarchy:
|
||||
// - PrefabRoot
|
||||
// - Canvas
|
||||
// - Root
|
||||
// - Scroll View
|
||||
// - Content
|
||||
// - Scrollbar
|
||||
GameObject m_PrefabRoot;
|
||||
RectTransform Root { get; set; }
|
||||
ScrollRect Scroll { get; set; }
|
||||
RectTransform ScrollTransform { get; set; }
|
||||
RectTransform Content { get; set; }
|
||||
|
||||
float ScrollSizeY { get { return ScrollTransform.rect.size.y; } }
|
||||
float ContentSizeY { get { return Content.rect.size.y; } }
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
// We setup the ScrollRect so that it will vertically resize with the Root object, to simulate
|
||||
// a change in screen size
|
||||
m_PrefabRoot = new GameObject("ScrollRectClamp");
|
||||
|
||||
GameObject CanvasGO = new GameObject("Canvas");
|
||||
CanvasGO.transform.SetParent(m_PrefabRoot.transform);
|
||||
|
||||
GameObject RootGO = new GameObject("Root", typeof(RectTransform));
|
||||
RootGO.transform.SetParent(CanvasGO.transform);
|
||||
Root = RootGO.GetComponent<RectTransform>();
|
||||
Root.pivot = Root.anchorMin = Root.anchorMax = new Vector2(0.5f, 0.5f);
|
||||
Root.sizeDelta = new Vector2(150.0f, 200.0f);
|
||||
|
||||
GameObject ScrollViewGO = new GameObject("Scroll View", typeof(RectTransform), typeof(ScrollRect), typeof(Image));
|
||||
ScrollViewGO.transform.SetParent(Root);
|
||||
Scroll = ScrollViewGO.GetComponent<ScrollRect>();
|
||||
ScrollTransform = ScrollViewGO.GetComponent<RectTransform>();
|
||||
Scroll.viewport = ScrollTransform;
|
||||
Scroll.movementType = ScrollRect.MovementType.Clamped;
|
||||
Scroll.verticalScrollbarVisibility = ScrollRect.ScrollbarVisibility.AutoHide;
|
||||
|
||||
ScrollTransform.pivot = ScrollTransform.anchorMax = new Vector2(0.0f, 1.0f);
|
||||
ScrollTransform.anchorMin = Vector2.zero;
|
||||
ScrollTransform.sizeDelta = new Vector2(150.0f, 0.0f);
|
||||
ScrollTransform.localPosition = Vector3.zero;
|
||||
|
||||
GameObject ContentGO = new GameObject("Content", typeof(RectTransform));
|
||||
Content = ContentGO.GetComponent<RectTransform>();
|
||||
Content.SetParent(ScrollTransform);
|
||||
Scroll.content = Content;
|
||||
Content.pivot = Content.anchorMin = new Vector2(0.0f, 1.0f);
|
||||
Content.anchorMax = new Vector2(1.0f, 1.0f);
|
||||
Content.sizeDelta = new Vector2(0.0f, 300.0f);
|
||||
Content.anchoredPosition = Vector2.zero;
|
||||
|
||||
GameObject ScrollbarGO = new GameObject("Scrollbar", typeof(RectTransform), typeof(Image), typeof(Scrollbar));
|
||||
ScrollbarGO.transform.SetParent(ScrollTransform);
|
||||
Scroll.verticalScrollbar = ScrollbarGO.GetComponent<Scrollbar>();
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
Object.DestroyImmediate(m_PrefabRoot);
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator ScrollRect_CorrectClampOnResize()
|
||||
{
|
||||
Assert.IsNotNull(Scroll.verticalScrollbar);
|
||||
|
||||
Scroll.verticalNormalizedPosition = 1.0f;
|
||||
yield return null;
|
||||
Assert.IsTrue(Mathf.Approximately(0.0f, Content.anchoredPosition.y));
|
||||
|
||||
Scroll.verticalNormalizedPosition = 0.0f;
|
||||
yield return null;
|
||||
// The content is vertically bigger than the viewport.
|
||||
Assert.IsTrue(Mathf.Approximately(Content.anchoredPosition.y, ContentSizeY - ScrollSizeY));
|
||||
|
||||
// Resizing the root will resize the viewport accordingly.
|
||||
Root.sizeDelta = new Vector2(150.0f, 300.0f);
|
||||
yield return null;
|
||||
// The content is vertically the same size as the viewport
|
||||
Assert.IsTrue(Mathf.Approximately(ContentSizeY, ScrollSizeY));
|
||||
Assert.False(Scroll.verticalScrollbar.gameObject.activeSelf);
|
||||
Assert.IsTrue(Mathf.Approximately(0.0f, Scroll.verticalNormalizedPosition));
|
||||
Assert.IsTrue(Mathf.Approximately(0.0f, Content.anchoredPosition.y));
|
||||
|
||||
Root.sizeDelta = new Vector2(150.0f, 200.0f);
|
||||
yield return null;
|
||||
Assert.IsTrue(Mathf.Approximately(1.0f, Scroll.verticalNormalizedPosition));
|
||||
}
|
||||
}
|
@@ -0,0 +1,104 @@
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
using UnityEngine.TestTools;
|
||||
using NUnit.Framework;
|
||||
using System.Collections;
|
||||
using UnityEngine.UI;
|
||||
using UnityEditor;
|
||||
|
||||
public class ScrollRectScale : IPrebuildSetup
|
||||
{
|
||||
const string kPrefabPath = "Assets/Resources/ScrollRectScalePrefab.prefab";
|
||||
public void Setup()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
var rootGO = new GameObject("Canvas", typeof(Canvas), typeof(CanvasScaler));
|
||||
rootGO.transform.SetParent(rootGO.transform);
|
||||
var rootGOTransform = rootGO.transform as RectTransform;
|
||||
rootGOTransform.anchoredPosition3D = new Vector3(679, -122, 783);
|
||||
rootGOTransform.sizeDelta = new Vector2(1165, 765);
|
||||
rootGOTransform.localRotation = Quaternion.Euler(20, 30, 0);
|
||||
|
||||
|
||||
var bodyGO = new GameObject("Body", typeof(RectTransform), typeof(Image), typeof(ScrollRect));
|
||||
bodyGO.transform.SetParent(rootGO.transform);
|
||||
var bodyGORectTransform = bodyGO.transform as RectTransform;
|
||||
bodyGORectTransform.localRotation = Quaternion.identity;
|
||||
bodyGORectTransform.anchorMin = Vector2.zero;
|
||||
bodyGORectTransform.anchorMax = Vector2.one;
|
||||
bodyGORectTransform.localPosition = Vector3.zero;
|
||||
bodyGORectTransform.anchoredPosition = new Vector2(8, -8);
|
||||
bodyGORectTransform.sizeDelta = new Vector2(-16, -16);
|
||||
bodyGORectTransform.pivot = new Vector2(0, 1);
|
||||
|
||||
var sizer = new GameObject("Sizer", typeof(RectTransform));
|
||||
var sizerTransform = sizer.transform as RectTransform;
|
||||
sizerTransform.SetParent(bodyGO.transform);
|
||||
sizerTransform.localRotation = Quaternion.identity;
|
||||
sizerTransform.sizeDelta = new Vector2(1149, 3700);
|
||||
sizerTransform.anchoredPosition3D = Vector3.zero;
|
||||
sizerTransform.anchorMin = new Vector2(0, 1);
|
||||
sizerTransform.anchorMax = new Vector2(0, 1);
|
||||
sizerTransform.pivot = new Vector2(0, 1);
|
||||
|
||||
var bodyGOScrollRect = bodyGO.GetComponent<ScrollRect>();
|
||||
bodyGOScrollRect.content = sizerTransform;
|
||||
bodyGOScrollRect.movementType = ScrollRect.MovementType.Clamped;
|
||||
bodyGOScrollRect.decelerationRate = 0.135f;
|
||||
|
||||
for (int i = 0; i < 19; ++i)
|
||||
{
|
||||
var row = new GameObject("Row" + i, typeof(Image));
|
||||
var rowTransform = row.transform as RectTransform;
|
||||
rowTransform.SetParent(sizer.transform);
|
||||
rowTransform.localRotation = Quaternion.identity;
|
||||
rowTransform.anchorMin = new Vector2(0, 1);
|
||||
rowTransform.anchorMax = new Vector2(0, 1);
|
||||
rowTransform.pivot = new Vector2(0, 1);
|
||||
rowTransform.sizeDelta = new Vector2(1149, 37);
|
||||
rowTransform.anchoredPosition3D = new Vector3(0, i * -37, 0);
|
||||
}
|
||||
|
||||
if (!Directory.Exists("Assets/Resources/"))
|
||||
Directory.CreateDirectory("Assets/Resources/");
|
||||
|
||||
UnityEditor.PrefabUtility.SaveAsPrefabAsset(rootGO, kPrefabPath);
|
||||
GameObject.DestroyImmediate(rootGO);
|
||||
#endif
|
||||
}
|
||||
|
||||
GameObject m_CanvasGO;
|
||||
|
||||
[SetUp]
|
||||
public void TestSetup()
|
||||
{
|
||||
m_CanvasGO = Object.Instantiate(Resources.Load("ScrollRectScalePrefab")) as GameObject;
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
[Description("Rect Transform position values are set to NaN, when Rect Transform is created via script and canvas is scaled to 0.01(case 893559)")]
|
||||
public IEnumerator SmallScaleDoesNotCauseInvalidContentPosition()
|
||||
{
|
||||
var canvas = m_CanvasGO.GetComponent<Canvas>();
|
||||
var scrollRect = canvas.GetComponentInChildren<ScrollRect>();
|
||||
var contentRt = scrollRect.content.GetComponent<RectTransform>();
|
||||
var contentLocalPosition = contentRt.localPosition;
|
||||
|
||||
var rt = canvas.GetComponent<RectTransform>();
|
||||
rt.localScale = new Vector3(0.1f, 0.1f, 0.1f);
|
||||
yield return null;
|
||||
|
||||
Assert.AreEqual(contentLocalPosition.x, contentRt.localPosition.x, 0.001f);
|
||||
Assert.AreEqual(contentLocalPosition.y, contentRt.localPosition.y, 0.001f);
|
||||
Assert.AreEqual(contentLocalPosition.z, contentRt.localPosition.z, 0.001f);
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
GameObject.DestroyImmediate(m_CanvasGO);
|
||||
#if UNITY_EDITOR
|
||||
AssetDatabase.DeleteAsset(kPrefabPath);
|
||||
#endif
|
||||
}
|
||||
}
|
@@ -0,0 +1,128 @@
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.TestTools;
|
||||
using NUnit.Framework;
|
||||
using System.Collections;
|
||||
using UnityEditor;
|
||||
|
||||
/*
|
||||
This test checks if a clamped scrollRect with a content rect that has the same width and a canvas with scaling will stay stable for 5 frames.
|
||||
Test for case (1010178-Clamped ScrollRect with scalling cause a large spike in performance)
|
||||
*/
|
||||
|
||||
public class ScrollRectStableLayout : IPrebuildSetup
|
||||
{
|
||||
GameObject m_PrefabRoot;
|
||||
GameObject m_CameraGO;
|
||||
|
||||
const string kPrefabPath = "Assets/Resources/ScrollRectStableLayoutPrefab.prefab";
|
||||
|
||||
public void Setup()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
var rootGO = new GameObject("RootGO");
|
||||
var rootCanvasGO = new GameObject("Canvas", typeof(Canvas), typeof(CanvasScaler));
|
||||
rootCanvasGO.transform.SetParent(rootGO.transform);
|
||||
var canvas = rootCanvasGO.GetComponent<Canvas>();
|
||||
canvas.renderMode = RenderMode.ScreenSpaceOverlay;
|
||||
var canvasScaler = rootCanvasGO.GetComponent<CanvasScaler>();
|
||||
canvasScaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize;
|
||||
canvasScaler.referenceResolution = new Vector2(3840, 2160);
|
||||
canvasScaler.referencePixelsPerUnit = 128;
|
||||
|
||||
var scrollRectGo = new GameObject("Scroll View", typeof(ScrollRect));
|
||||
var scrollRectTransform = scrollRectGo.GetComponent<RectTransform>();
|
||||
scrollRectTransform.SetParent(rootCanvasGO.transform);
|
||||
scrollRectTransform.localPosition = Vector3.zero;
|
||||
scrollRectTransform.sizeDelta = new Vector2(1000, 1000);
|
||||
scrollRectTransform.localScale = Vector3.one * 1.000005f;
|
||||
var scrollRect = scrollRectGo.GetComponent<ScrollRect>();
|
||||
scrollRect.horizontal = true;
|
||||
scrollRect.vertical = true;
|
||||
scrollRect.movementType = ScrollRect.MovementType.Clamped;
|
||||
scrollRect.inertia = true;
|
||||
|
||||
var viewportTransform = new GameObject("Viewport", typeof(RectTransform)).GetComponent<RectTransform>();
|
||||
viewportTransform.SetParent(scrollRectTransform);
|
||||
viewportTransform.localPosition = Vector3.zero;
|
||||
viewportTransform.localScale = Vector3.one;
|
||||
viewportTransform.sizeDelta = new Vector2(-17, 0);
|
||||
viewportTransform.anchorMin = new Vector2(0, 0);
|
||||
viewportTransform.anchorMax = new Vector2(1, 1);
|
||||
viewportTransform.pivot = new Vector2(0, 1);
|
||||
scrollRect.viewport = viewportTransform;
|
||||
|
||||
var contentGo = new GameObject("Content", typeof(GridLayoutGroup));
|
||||
var contentTransform = contentGo.GetComponent<RectTransform>();
|
||||
contentTransform.SetParent(viewportTransform);
|
||||
contentTransform.localPosition = Vector3.zero;
|
||||
contentTransform.localScale = Vector3.one;
|
||||
contentTransform.sizeDelta = new Vector2(0, 300);
|
||||
contentTransform.anchorMin = new Vector2(0, 1);
|
||||
contentTransform.anchorMax = new Vector2(1, 1);
|
||||
contentTransform.pivot = new Vector2(0, 1);
|
||||
var gridLayout = contentGo.GetComponent<GridLayoutGroup>();
|
||||
gridLayout.cellSize = new Vector2(100, 100);
|
||||
gridLayout.startCorner = GridLayoutGroup.Corner.UpperLeft;
|
||||
gridLayout.startAxis = GridLayoutGroup.Axis.Horizontal;
|
||||
gridLayout.childAlignment = TextAnchor.UpperLeft;
|
||||
gridLayout.constraint = GridLayoutGroup.Constraint.Flexible;
|
||||
scrollRect.content = contentTransform;
|
||||
|
||||
for (int i = 0; i < 20; i++)
|
||||
{
|
||||
var go = new GameObject("GameObject (" + i + ")", typeof(RectTransform));
|
||||
var t = go.GetComponent<RectTransform>();
|
||||
t.SetParent(contentTransform);
|
||||
t.localScale = Vector3.one;
|
||||
t.pivot = new Vector2(0.5f, 0.5f);
|
||||
}
|
||||
|
||||
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("ScrollRectStableLayoutPrefab")) as GameObject;
|
||||
m_CameraGO = new GameObject("Camera", typeof(Camera));
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator ScrollRect_StableWhenStatic()
|
||||
{
|
||||
//root->canvas->scroll view->viewport->content
|
||||
RectTransform t = m_PrefabRoot.transform.GetChild(0).GetChild(0).GetChild(0).GetChild(0) as RectTransform;
|
||||
float[] values = new float[5];
|
||||
for (int i = 0; i < values.Length; i++)
|
||||
{
|
||||
values[i] = t.localPosition.y;
|
||||
yield return null;
|
||||
}
|
||||
Assert.AreEqual(values[0], values[1]);
|
||||
Assert.AreEqual(values[1], values[2]);
|
||||
Assert.AreEqual(values[2], values[3]);
|
||||
Assert.AreEqual(values[3], values[4]);
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
Object.DestroyImmediate(m_PrefabRoot);
|
||||
GameObject.DestroyImmediate(m_CameraGO);
|
||||
}
|
||||
|
||||
[OneTimeTearDown]
|
||||
public void OneTimeTearDown()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
AssetDatabase.DeleteAsset(kPrefabPath);
|
||||
#endif
|
||||
}
|
||||
}
|
@@ -0,0 +1,414 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Reflection;
|
||||
using System.IO;
|
||||
using NUnit.Framework;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.TestTools;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
public class ScrollRectTests : IPrebuildSetup
|
||||
{
|
||||
const int ScrollSensitivity = 3;
|
||||
GameObject m_PrefabRoot;
|
||||
const string kPrefabPath = "Assets/Resources/ScrollRectPrefab.prefab";
|
||||
|
||||
public void Setup()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
var rootGO = new GameObject("rootGo");
|
||||
GameObject eventSystemGO = new GameObject("EventSystem", typeof(EventSystem));
|
||||
eventSystemGO.transform.SetParent(rootGO.transform);
|
||||
|
||||
var canvasGO = new GameObject("Canvas", typeof(Canvas));
|
||||
canvasGO.transform.SetParent(rootGO.transform);
|
||||
var canvas = canvasGO.GetComponent<Canvas>();
|
||||
canvas.referencePixelsPerUnit = 100;
|
||||
|
||||
GameObject scrollRectGO = new GameObject("ScrollRect", typeof(RectTransform), typeof(ScrollRect));
|
||||
scrollRectGO.transform.SetParent(canvasGO.transform);
|
||||
|
||||
GameObject contentGO = new GameObject("Content", typeof(RectTransform));
|
||||
contentGO.transform.SetParent(scrollRectGO.transform);
|
||||
|
||||
GameObject horizontalScrollBarGO = new GameObject("HorizontalScrollBar", typeof(Scrollbar));
|
||||
horizontalScrollBarGO.transform.SetParent(scrollRectGO.transform);
|
||||
|
||||
GameObject verticalScrollBarGO = new GameObject("VerticalScrollBar", typeof(Scrollbar));
|
||||
verticalScrollBarGO.transform.SetParent(scrollRectGO.transform);
|
||||
|
||||
ScrollRect scrollRect = scrollRectGO.GetComponent<ScrollRect>();
|
||||
scrollRect.transform.position = Vector3.zero;
|
||||
scrollRect.transform.rotation = Quaternion.identity;
|
||||
scrollRect.transform.localScale = Vector3.one;
|
||||
(scrollRect.transform as RectTransform).sizeDelta = new Vector3(0.5f, 0.5f);
|
||||
scrollRect.horizontalScrollbar = horizontalScrollBarGO.GetComponent<Scrollbar>();
|
||||
scrollRect.verticalScrollbar = verticalScrollBarGO.GetComponent<Scrollbar>();
|
||||
scrollRect.content = contentGO.GetComponent<RectTransform>();
|
||||
scrollRect.content.anchoredPosition = Vector2.zero;
|
||||
scrollRect.content.sizeDelta = new Vector2(3, 3);
|
||||
scrollRect.scrollSensitivity = ScrollSensitivity;
|
||||
scrollRect.GetComponent<RectTransform>().sizeDelta = new Vector2(1, 1);
|
||||
|
||||
if (!Directory.Exists("Assets/Resources/"))
|
||||
Directory.CreateDirectory("Assets/Resources/");
|
||||
|
||||
PrefabUtility.SaveAsPrefabAsset(rootGO, kPrefabPath);
|
||||
GameObject.DestroyImmediate(rootGO);
|
||||
#endif
|
||||
}
|
||||
|
||||
[SetUp]
|
||||
public void TestSetup()
|
||||
{
|
||||
m_PrefabRoot = UnityEngine.Object.Instantiate(Resources.Load("ScrollRectPrefab")) as GameObject;
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
GameObject.DestroyImmediate(m_PrefabRoot);
|
||||
}
|
||||
|
||||
[OneTimeTearDown]
|
||||
public void OneTimeTearDown()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
AssetDatabase.DeleteAsset(kPrefabPath);
|
||||
#endif
|
||||
}
|
||||
|
||||
#region Enable disable scrollbars
|
||||
|
||||
[UnityTest]
|
||||
[TestCase(true, ExpectedResult = null)]
|
||||
[TestCase(false, ExpectedResult = null)]
|
||||
public IEnumerator OnEnableShouldAddListeners(bool isHorizontal)
|
||||
{
|
||||
ScrollRect scrollRect = m_PrefabRoot.GetComponentInChildren<ScrollRect>();
|
||||
Scrollbar scrollbar = isHorizontal ? scrollRect.horizontalScrollbar : scrollRect.verticalScrollbar;
|
||||
|
||||
scrollRect.enabled = false;
|
||||
|
||||
yield return null;
|
||||
|
||||
FieldInfo field = scrollbar.onValueChanged.GetType().BaseType.BaseType.GetField("m_Calls", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
object invokeableCallList = field.GetValue(scrollbar.onValueChanged);
|
||||
PropertyInfo property = invokeableCallList.GetType().GetProperty("Count", BindingFlags.Public | BindingFlags.Instance);
|
||||
|
||||
int callCount = (int)property.GetValue(invokeableCallList, null);
|
||||
|
||||
scrollRect.enabled = true;
|
||||
|
||||
yield return null;
|
||||
Assert.AreEqual(callCount + 1, (int)property.GetValue(invokeableCallList, null));
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
[TestCase(true, ExpectedResult = null)]
|
||||
[TestCase(false, ExpectedResult = null)]
|
||||
public IEnumerator OnDisableShouldRemoveListeners(bool isHorizontal)
|
||||
{
|
||||
ScrollRect scrollRect = m_PrefabRoot.GetComponentInChildren<ScrollRect>();
|
||||
Scrollbar scrollbar = isHorizontal ? scrollRect.horizontalScrollbar : scrollRect.verticalScrollbar;
|
||||
|
||||
scrollRect.enabled = true;
|
||||
yield return null;
|
||||
|
||||
FieldInfo field = scrollbar.onValueChanged.GetType().BaseType.BaseType.GetField("m_Calls", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
object invokeableCallList = field.GetValue(scrollbar.onValueChanged);
|
||||
PropertyInfo property = invokeableCallList.GetType().GetProperty("Count", BindingFlags.Public | BindingFlags.Instance);
|
||||
|
||||
Assert.AreNotEqual(0, (int)property.GetValue(invokeableCallList, null));
|
||||
|
||||
scrollRect.enabled = false;
|
||||
yield return null;
|
||||
Assert.AreEqual(0, (int)property.GetValue(invokeableCallList, null));
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCase(true)]
|
||||
[TestCase(false)]
|
||||
public void SettingScrollbarShouldRemoveThenAddListeners(bool testHorizontal)
|
||||
{
|
||||
ScrollRect scrollRect = m_PrefabRoot.GetComponentInChildren<ScrollRect>();
|
||||
Scrollbar scrollbar = testHorizontal ? scrollRect.horizontalScrollbar : scrollRect.verticalScrollbar;
|
||||
|
||||
GameObject scrollBarGO = new GameObject("scrollBar", typeof(RectTransform), typeof(Scrollbar));
|
||||
scrollBarGO.transform.SetParent(scrollRect.transform);
|
||||
Scrollbar newScrollbar = scrollBarGO.GetComponent<Scrollbar>();
|
||||
|
||||
FieldInfo field = newScrollbar.onValueChanged.GetType().BaseType.BaseType.GetField("m_Calls", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
PropertyInfo property = field.GetValue(newScrollbar.onValueChanged).GetType().GetProperty("Count", BindingFlags.Public | BindingFlags.Instance);
|
||||
|
||||
int newCallCount = (int)property.GetValue(field.GetValue(newScrollbar.onValueChanged), null);
|
||||
if (testHorizontal)
|
||||
scrollRect.horizontalScrollbar = newScrollbar;
|
||||
else
|
||||
scrollRect.verticalScrollbar = newScrollbar;
|
||||
|
||||
Assert.AreEqual(0, (int)property.GetValue(field.GetValue(scrollbar.onValueChanged), null), "The previous scrollbar should not have listeners anymore");
|
||||
Assert.AreEqual(newCallCount + 1, (int)property.GetValue(field.GetValue(newScrollbar.onValueChanged), null), "The new scrollbar should have listeners now");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Drag
|
||||
|
||||
[Test]
|
||||
[TestCase(PointerEventData.InputButton.Left, true)]
|
||||
[TestCase(PointerEventData.InputButton.Right, false)]
|
||||
[TestCase(PointerEventData.InputButton.Middle, false)]
|
||||
public void PotentialDragNeedsLeftClick(PointerEventData.InputButton button, bool expectedEqualsZero)
|
||||
{
|
||||
ScrollRect scrollRect = m_PrefabRoot.GetComponentInChildren<ScrollRect>();
|
||||
scrollRect.velocity = Vector2.one;
|
||||
Assert.AreNotEqual(Vector2.zero, scrollRect.velocity);
|
||||
|
||||
scrollRect.OnInitializePotentialDrag(new PointerEventData(m_PrefabRoot.GetComponentInChildren<EventSystem>()) { button = button });
|
||||
if (expectedEqualsZero)
|
||||
Assert.AreEqual(Vector2.zero, scrollRect.velocity);
|
||||
else
|
||||
Assert.AreNotEqual(Vector2.zero, scrollRect.velocity);
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCase(PointerEventData.InputButton.Left, true, true)]
|
||||
[TestCase(PointerEventData.InputButton.Left, false, false)]
|
||||
[TestCase(PointerEventData.InputButton.Right, true, false)]
|
||||
[TestCase(PointerEventData.InputButton.Middle, true, false)]
|
||||
public void LeftClickShouldStartDrag(PointerEventData.InputButton button, bool active, bool expectedIsDragging)
|
||||
{
|
||||
ScrollRect scrollRect = m_PrefabRoot.GetComponentInChildren<ScrollRect>();
|
||||
scrollRect.enabled = active;
|
||||
|
||||
scrollRect.velocity = Vector2.one;
|
||||
Assert.AreNotEqual(Vector2.zero, scrollRect.velocity);
|
||||
|
||||
var pointerEventData = new PointerEventData(m_PrefabRoot.GetComponentInChildren<EventSystem>()) { button = button };
|
||||
scrollRect.OnInitializePotentialDrag(pointerEventData);
|
||||
|
||||
FieldInfo field = typeof(ScrollRect).GetField("m_Dragging", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
|
||||
Assert.IsFalse((bool)field.GetValue(scrollRect));
|
||||
scrollRect.OnBeginDrag(pointerEventData);
|
||||
Assert.AreEqual(expectedIsDragging, (bool)field.GetValue(scrollRect));
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCase(PointerEventData.InputButton.Left, true, false)]
|
||||
[TestCase(PointerEventData.InputButton.Left, false, false)]
|
||||
[TestCase(PointerEventData.InputButton.Right, false, false)]
|
||||
[TestCase(PointerEventData.InputButton.Right, true, true)]
|
||||
[TestCase(PointerEventData.InputButton.Middle, true, true)]
|
||||
[TestCase(PointerEventData.InputButton.Middle, false, false)]
|
||||
public void LeftClickUpShouldEndDrag(PointerEventData.InputButton button, bool active, bool expectedIsDragging)
|
||||
{
|
||||
ScrollRect scrollRect = m_PrefabRoot.GetComponentInChildren<ScrollRect>();
|
||||
scrollRect.velocity = Vector2.one;
|
||||
Assert.AreNotEqual(Vector2.zero, scrollRect.velocity);
|
||||
|
||||
var startDragEventData = new PointerEventData(m_PrefabRoot.GetComponentInChildren<EventSystem>()) { button = PointerEventData.InputButton.Left };
|
||||
|
||||
scrollRect.OnInitializePotentialDrag(startDragEventData);
|
||||
|
||||
FieldInfo field = typeof(ScrollRect).GetField("m_Dragging", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
|
||||
Assert.IsFalse((bool)field.GetValue(scrollRect));
|
||||
scrollRect.OnBeginDrag(startDragEventData);
|
||||
Assert.IsTrue((bool)field.GetValue(scrollRect), "Prerequisite: dragging should be true to test if it is set to false later");
|
||||
|
||||
scrollRect.enabled = active;
|
||||
|
||||
var endDragEventData = new PointerEventData(m_PrefabRoot.GetComponentInChildren<EventSystem>()) { button = button };
|
||||
scrollRect.OnEndDrag(endDragEventData);
|
||||
Assert.AreEqual(expectedIsDragging, (bool)field.GetValue(scrollRect));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region LateUpdate
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator LateUpdateWithoutInertiaOrElasticShouldZeroVelocity()
|
||||
{
|
||||
ScrollRect scrollRect = m_PrefabRoot.GetComponentInChildren<ScrollRect>();
|
||||
scrollRect.velocity = Vector2.one;
|
||||
scrollRect.inertia = false;
|
||||
scrollRect.movementType = ScrollRect.MovementType.Clamped;
|
||||
yield return null;
|
||||
|
||||
Assert.AreEqual(Vector2.zero, scrollRect.velocity);
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator LateUpdateWithInertiaShouldDecelerate()
|
||||
{
|
||||
ScrollRect scrollRect = m_PrefabRoot.GetComponentInChildren<ScrollRect>();
|
||||
scrollRect.velocity = Vector2.one;
|
||||
scrollRect.inertia = true;
|
||||
scrollRect.movementType = ScrollRect.MovementType.Clamped;
|
||||
yield return null;
|
||||
Assert.Less(scrollRect.velocity.magnitude, 1);
|
||||
}
|
||||
|
||||
[UnityTest][Ignore("Fails")]
|
||||
public IEnumerator LateUpdateWithElasticShouldDecelerate()
|
||||
{
|
||||
ScrollRect scrollRect = m_PrefabRoot.GetComponentInChildren<ScrollRect>();
|
||||
scrollRect.velocity = Vector2.one;
|
||||
scrollRect.inertia = false;
|
||||
scrollRect.content.anchoredPosition = Vector2.one * 2;
|
||||
scrollRect.movementType = ScrollRect.MovementType.Elastic;
|
||||
|
||||
yield return null;
|
||||
Assert.AreNotEqual(1, scrollRect.velocity.magnitude);
|
||||
var newMagnitude = scrollRect.velocity.magnitude;
|
||||
|
||||
yield return null;
|
||||
Assert.AreNotEqual(newMagnitude, scrollRect.velocity.magnitude);
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator LateUpdateWithElasticNoOffsetShouldZeroVelocity()
|
||||
{
|
||||
ScrollRect scrollRect = m_PrefabRoot.GetComponentInChildren<ScrollRect>();
|
||||
scrollRect.velocity = Vector2.one;
|
||||
scrollRect.inertia = false;
|
||||
scrollRect.movementType = ScrollRect.MovementType.Elastic;
|
||||
yield return null;
|
||||
Assert.AreEqual(Vector2.zero, scrollRect.velocity);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
[Test]
|
||||
public void SetNormalizedPositionShouldSetContentLocalPosition()
|
||||
{
|
||||
ScrollRect scrollRect = m_PrefabRoot.GetComponentInChildren<ScrollRect>();
|
||||
scrollRect.normalizedPosition = Vector2.one;
|
||||
Assert.AreEqual(new Vector3(-1f, -1f, 0), scrollRect.content.localPosition);
|
||||
}
|
||||
|
||||
#region Scroll, offset, ...
|
||||
|
||||
[Test]
|
||||
[TestCase(1, 1, true, true, 1, -1, TestName = "Horizontal and vertical scroll")]
|
||||
[TestCase(1, 1, false, true, 0, -1, TestName = "Vertical scroll")]
|
||||
[TestCase(1, 1, true, false, 1, 0, TestName = "Horizontal scroll")]
|
||||
public void OnScrollClampedShouldMoveContentAnchoredPosition(int scrollDeltaX, int scrollDeltaY, bool horizontal,
|
||||
bool vertical, int expectedPosX, int expectedPosY)
|
||||
{
|
||||
ScrollRect scrollRect = m_PrefabRoot.GetComponentInChildren<ScrollRect>();
|
||||
Vector2 scrollDelta = new Vector2(scrollDeltaX, scrollDeltaY);
|
||||
var expected = new Vector2(expectedPosX, expectedPosY) * ScrollSensitivity;
|
||||
|
||||
scrollRect.horizontal = horizontal;
|
||||
scrollRect.vertical = vertical;
|
||||
|
||||
scrollRect.OnScroll(new PointerEventData(m_PrefabRoot.GetComponentInChildren<EventSystem>())
|
||||
{
|
||||
scrollDelta = scrollDelta
|
||||
});
|
||||
|
||||
Assert.AreEqual(expected, scrollRect.content.anchoredPosition);
|
||||
}
|
||||
|
||||
[Test][Ignore("Tests fail without mocking")]
|
||||
[TestCase(ScrollRect.MovementType.Clamped, 1f, 1f)]
|
||||
[TestCase(ScrollRect.MovementType.Unrestricted, 150, 150)]
|
||||
[TestCase(ScrollRect.MovementType.Elastic, 150, 150)]
|
||||
public void OnScrollClampedShouldClampContentAnchoredPosition(ScrollRect.MovementType movementType, float anchoredPosX,
|
||||
float anchoredPosY)
|
||||
{
|
||||
ScrollRect scrollRect = m_PrefabRoot.GetComponentInChildren<ScrollRect>();
|
||||
Vector2 scrollDelta = new Vector2(50, -50);
|
||||
scrollRect.movementType = movementType;
|
||||
scrollRect.content.anchoredPosition = new Vector2(2.5f, 2.5f);
|
||||
|
||||
scrollRect.OnScroll(new PointerEventData(m_PrefabRoot.GetComponentInChildren<EventSystem>())
|
||||
{
|
||||
scrollDelta = scrollDelta
|
||||
});
|
||||
Assert.AreEqual(new Vector2(anchoredPosX, anchoredPosY), scrollRect.content.anchoredPosition);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetBoundsShouldEncapsulateAllCorners()
|
||||
{
|
||||
Matrix4x4 matrix = Matrix4x4.identity;
|
||||
object[] arguments = new object[2]
|
||||
{
|
||||
new Vector3[] { Vector3.zero, Vector3.one, Vector3.one * 2, Vector3.one },
|
||||
matrix
|
||||
};
|
||||
MethodInfo method = typeof(ScrollRect).GetMethod("InternalGetBounds", BindingFlags.NonPublic | BindingFlags.Static);
|
||||
var bounds = (Bounds)method.Invoke(null, arguments);
|
||||
|
||||
Assert.AreEqual(Vector3.zero, bounds.min);
|
||||
Assert.AreEqual(Vector3.one * 2, bounds.max);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void UpdateBoundsShouldPad()
|
||||
{
|
||||
Bounds viewBounds = new Bounds(Vector3.zero, Vector3.one * 2);
|
||||
Vector3 contentSize = Vector3.one;
|
||||
Vector3 contentPos = Vector3.one;
|
||||
var contentPivot = new Vector2(0.5f, 0.5f);
|
||||
|
||||
object[] arguments = new object[] { viewBounds, contentPivot, contentSize, contentPos };
|
||||
MethodInfo method = typeof(ScrollRect).GetMethod("AdjustBounds", BindingFlags.NonPublic | BindingFlags.Static);
|
||||
method.Invoke(null, arguments);
|
||||
|
||||
//ScrollRect.AdjustBounds(ref viewBounds, ref contentPivot, ref contentSize, ref contentPos);
|
||||
Assert.AreEqual(new Vector3(2, 2, 1), arguments[2]);
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCase(true, true, 2, 4, -2, -2, TestName = "Should clamp offset")]
|
||||
[TestCase(false, true, 2, 4, 0, -2, TestName = "Vertical should clamp offset on one axis")]
|
||||
[TestCase(true, false, 2, 4, -2, 0, TestName = "Horizontal should clamp offset on one axis")]
|
||||
[TestCase(false, false, 2, 4, 0, 0, TestName = "No axis should not clamp offset")]
|
||||
[TestCase(true, true, 8, 10, 2, 2, TestName = "Should clamp negative offset")]
|
||||
[TestCase(false, true, 8, 10, 0, 2, TestName = "Vertical should clamp negative offset on one axis")]
|
||||
[TestCase(true, false, 8, 10, 2, 0, TestName = "Horizontal should clamp negative offset on one axis")]
|
||||
[TestCase(false, false, 8, 10, 0, 0, TestName = "No axis should not clamp negative offset")]
|
||||
public void CalculateOffsetShouldClamp(bool horizontal, bool vertical, int viewX, float viewY, float resX, float resY)
|
||||
{
|
||||
TestCalculateOffset(ScrollRect.MovementType.Clamped, horizontal, vertical, viewX, viewY, resX, resY, new Bounds(new Vector3(5, 7), new Vector3(4, 4)));
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCase(true, true, 2, 4, -2, -2, TestName = "Should clamp offset")]
|
||||
[TestCase(false, true, 2, 4, 0, -2, TestName = "Vertical should clamp offset on one axis")]
|
||||
[TestCase(true, false, 2, 4, -2, 0, TestName = "Horizontal should clamp offset on one axis")]
|
||||
[TestCase(false, false, 2, 4, 0, 0, TestName = "No axis should not clamp offset")]
|
||||
[TestCase(true, true, 8, 10, 2, 2, TestName = "Should clamp negative offset")]
|
||||
[TestCase(false, true, 8, 10, 0, 2, TestName = "Vertical should clamp negative offset on one axis")]
|
||||
[TestCase(true, false, 8, 10, 2, 0, TestName = "Horizontal should clamp negative offset on one axis")]
|
||||
[TestCase(false, false, 8, 10, 0, 0, TestName = "No axis should not clamp negative offset")]
|
||||
public void CalculateOffsetUnrestrictedShouldNotClamp(bool horizontal, bool vertical, int viewX, float viewY, float resX, float resY)
|
||||
{
|
||||
TestCalculateOffset(ScrollRect.MovementType.Unrestricted, horizontal, vertical, viewX, viewY, 0, 0, new Bounds(new Vector3(5, 7), new Vector3(4, 4)));
|
||||
}
|
||||
|
||||
private static void TestCalculateOffset(ScrollRect.MovementType movementType, bool horizontal, bool vertical, int viewX, float viewY, float resX, float resY, Bounds contentBounds)
|
||||
{
|
||||
Bounds viewBounds = new Bounds(new Vector3(viewX, viewY), new Vector3(2, 2));
|
||||
// content is south east of view
|
||||
Vector2 delta = Vector2.zero;
|
||||
|
||||
object[] arguments = new object[] { viewBounds, contentBounds, horizontal, vertical, movementType, delta };
|
||||
MethodInfo method = typeof(ScrollRect).GetMethod("InternalCalculateOffset", BindingFlags.NonPublic | BindingFlags.Static);
|
||||
var result = (Vector2)method.Invoke(null, arguments);
|
||||
|
||||
Console.WriteLine(result);
|
||||
Assert.AreEqual(new Vector2(resX, resY), result);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
@@ -0,0 +1,47 @@
|
||||
using NUnit.Framework;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine;
|
||||
|
||||
[Category("Slider")]
|
||||
public class SliderTests
|
||||
{
|
||||
private Slider slider;
|
||||
private GameObject emptyGO;
|
||||
private GameObject rootGO;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
rootGO = new GameObject("root child");
|
||||
rootGO.AddComponent<Canvas>();
|
||||
|
||||
var sliderGameObject = new GameObject("Slider");
|
||||
slider = sliderGameObject.AddComponent<Slider>();
|
||||
|
||||
emptyGO = new GameObject("base", typeof(RectTransform));
|
||||
|
||||
sliderGameObject.transform.SetParent(rootGO.transform);
|
||||
emptyGO.transform.SetParent(sliderGameObject.transform);
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
GameObject.DestroyImmediate(rootGO);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SetSliderValueWithoutNotifyWillNotNotify()
|
||||
{
|
||||
slider.value = 0;
|
||||
|
||||
bool calledOnValueChanged = false;
|
||||
|
||||
slider.onValueChanged.AddListener(f => { calledOnValueChanged = true; });
|
||||
|
||||
slider.SetValueWithoutNotify(1);
|
||||
|
||||
Assert.IsTrue(slider.value == 1);
|
||||
Assert.IsFalse(calledOnValueChanged);
|
||||
}
|
||||
}
|
@@ -0,0 +1,323 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using NUnit.Framework;
|
||||
using UnityEngine;
|
||||
using UnityEngine.TestTools;
|
||||
|
||||
public class TextEditorBackspaceDelete
|
||||
{
|
||||
private const string kFailedToRemoveCharacterMessage = "Backspace or Delete Failed To Remove The Expected Character";
|
||||
private const string kFailedToChangeCursor = "Backspace or Delete Failed To Move The Cursor To The Expected Index";
|
||||
private const string kFailedToChangeSelect = "Backspace or Delete Failed To Move The Selection Index To The Expected Index";
|
||||
|
||||
[Test]
|
||||
public void TextEditorWithUTF16_MiddleCursorOnBackspace_RemovesCharacter()
|
||||
{
|
||||
var textBox = new TextEditor()
|
||||
{
|
||||
text = "MikeDeRoy",
|
||||
cursorIndex = 4,
|
||||
selectIndex = 4,
|
||||
};
|
||||
|
||||
textBox.Backspace();
|
||||
|
||||
Assert.AreEqual("MikDeRoy", textBox.text, kFailedToRemoveCharacterMessage);
|
||||
Assert.AreEqual(3, textBox.cursorIndex, kFailedToChangeCursor);
|
||||
Assert.AreEqual(3, textBox.selectIndex, kFailedToChangeSelect);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TextEditorWithUTF16_MiddleCursorOnDelete_RemovesCharacter()
|
||||
{
|
||||
var textBox = new TextEditor()
|
||||
{
|
||||
text = "MikeDeRoy",
|
||||
cursorIndex = 3,
|
||||
selectIndex = 3,
|
||||
};
|
||||
|
||||
textBox.Delete();
|
||||
|
||||
Assert.AreEqual("MikDeRoy", textBox.text, kFailedToRemoveCharacterMessage);
|
||||
Assert.AreEqual(3, textBox.cursorIndex, kFailedToChangeCursor);
|
||||
Assert.AreEqual(3, textBox.selectIndex, kFailedToChangeSelect);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TextEditorWithUTF16_MiddleCursorOnBackspaceAndLeftSurrogate_RemovesBothSurrogates()
|
||||
{
|
||||
var textBox = new TextEditor()
|
||||
{
|
||||
text = "Mike🗘DeRoy",
|
||||
cursorIndex = 5,
|
||||
selectIndex = 5,
|
||||
};
|
||||
|
||||
textBox.Backspace();
|
||||
|
||||
Assert.AreEqual("MikeDeRoy", textBox.text, kFailedToRemoveCharacterMessage);
|
||||
Assert.AreEqual(4, textBox.cursorIndex, kFailedToChangeCursor);
|
||||
Assert.AreEqual(4, textBox.selectIndex, kFailedToChangeSelect);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TextEditorWithUTF16_MiddleCursorOnDeleteAndLeftSurrogate_RemovesBothSurrogates()
|
||||
{
|
||||
var textBox = new TextEditor()
|
||||
{
|
||||
text = "Mike🗘DeRoy",
|
||||
cursorIndex = 4,
|
||||
selectIndex = 4,
|
||||
};
|
||||
|
||||
textBox.Delete();
|
||||
|
||||
Assert.AreEqual("MikeDeRoy", textBox.text, kFailedToRemoveCharacterMessage);
|
||||
Assert.AreEqual(4, textBox.cursorIndex, kFailedToChangeCursor);
|
||||
Assert.AreEqual(4, textBox.selectIndex, kFailedToChangeSelect);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TextEditorWithUTF16_MiddleCursorOnBackspaceAndRightSurrogate_RemovesBothSurrogates()
|
||||
{
|
||||
var textBox = new TextEditor()
|
||||
{
|
||||
text = "Mike🗘DeRoy",
|
||||
cursorIndex = 6,
|
||||
selectIndex = 6,
|
||||
};
|
||||
|
||||
textBox.Backspace();
|
||||
|
||||
Assert.AreEqual("MikeDeRoy", textBox.text, kFailedToRemoveCharacterMessage);
|
||||
Assert.AreEqual(4, textBox.cursorIndex, kFailedToChangeCursor);
|
||||
Assert.AreEqual(4, textBox.selectIndex, kFailedToChangeSelect);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TextEditorWithUTF16_LeftCursorOnBackspace_DoesNotRemoveCharacter()
|
||||
{
|
||||
var textBox = new TextEditor()
|
||||
{
|
||||
text = "MikeDeRoy",
|
||||
cursorIndex = 0,
|
||||
selectIndex = 0,
|
||||
};
|
||||
|
||||
textBox.Backspace();
|
||||
|
||||
Assert.AreEqual("MikeDeRoy", textBox.text, kFailedToRemoveCharacterMessage);
|
||||
Assert.AreEqual(0, textBox.cursorIndex, kFailedToChangeCursor);
|
||||
Assert.AreEqual(0, textBox.selectIndex, kFailedToChangeSelect);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TextEditorWithUTF16_LeftCursorOnDelete_RemovesCharacter()
|
||||
{
|
||||
var textBox = new TextEditor()
|
||||
{
|
||||
text = "MikeDeRoy",
|
||||
cursorIndex = 0,
|
||||
selectIndex = 0,
|
||||
};
|
||||
|
||||
textBox.Delete();
|
||||
|
||||
Assert.AreEqual("ikeDeRoy", textBox.text, kFailedToRemoveCharacterMessage);
|
||||
Assert.AreEqual(0, textBox.cursorIndex, kFailedToChangeCursor);
|
||||
Assert.AreEqual(0, textBox.selectIndex, kFailedToChangeSelect);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TextEditorWithUTF16_LeftCursorOnBackspaceAndLeftSurrogate_RemovesBothSurrogates()
|
||||
{
|
||||
var textBox = new TextEditor()
|
||||
{
|
||||
text = "🗘MikeDeRoy",
|
||||
cursorIndex = 1,
|
||||
selectIndex = 1,
|
||||
};
|
||||
|
||||
textBox.Backspace();
|
||||
|
||||
Assert.AreEqual("MikeDeRoy", textBox.text, kFailedToRemoveCharacterMessage);
|
||||
Assert.AreEqual(0, textBox.cursorIndex, kFailedToChangeCursor);
|
||||
Assert.AreEqual(0, textBox.selectIndex, kFailedToChangeSelect);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TextEditorWithUTF16_LeftCursorOnDeleteAndLeftSurrogate_RemovesBothSurrogates()
|
||||
{
|
||||
var textBox = new TextEditor()
|
||||
{
|
||||
text = "🗘MikeDeRoy",
|
||||
cursorIndex = 0,
|
||||
selectIndex = 0,
|
||||
};
|
||||
|
||||
textBox.Delete();
|
||||
|
||||
Assert.AreEqual("MikeDeRoy", textBox.text, kFailedToRemoveCharacterMessage);
|
||||
Assert.AreEqual(0, textBox.cursorIndex, kFailedToChangeCursor);
|
||||
Assert.AreEqual(0, textBox.selectIndex, kFailedToChangeSelect);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TextEditorWithUTF16_LeftCursorOnBackspaceAndRightSurrogate_RemovesBothSurrogates()
|
||||
{
|
||||
var textBox = new TextEditor()
|
||||
{
|
||||
text = "🗘MikeDeRoy",
|
||||
cursorIndex = 2,
|
||||
selectIndex = 2,
|
||||
};
|
||||
|
||||
textBox.Backspace();
|
||||
|
||||
Assert.AreEqual("MikeDeRoy", textBox.text, kFailedToRemoveCharacterMessage);
|
||||
Assert.AreEqual(0, textBox.cursorIndex, kFailedToChangeCursor);
|
||||
Assert.AreEqual(0, textBox.selectIndex, kFailedToChangeSelect);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TextEditorWithUTF16_RightCursorOnBackspace_RemovesCharacters()
|
||||
{
|
||||
var textBox = new TextEditor()
|
||||
{
|
||||
text = "MikeDeRoy",
|
||||
cursorIndex = 9,
|
||||
selectIndex = 9,
|
||||
};
|
||||
|
||||
textBox.Backspace();
|
||||
|
||||
Assert.AreEqual("MikeDeRo", textBox.text, kFailedToRemoveCharacterMessage);
|
||||
Assert.AreEqual(8, textBox.cursorIndex, kFailedToChangeCursor);
|
||||
Assert.AreEqual(8, textBox.selectIndex, kFailedToChangeSelect);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TextEditorWithUTF16_RightCursorOnDelete_DoesNotRemoveCharacter()
|
||||
{
|
||||
var textBox = new TextEditor()
|
||||
{
|
||||
text = "MikeDeRoy",
|
||||
cursorIndex = 9,
|
||||
selectIndex = 9,
|
||||
};
|
||||
|
||||
textBox.Delete();
|
||||
|
||||
Assert.AreEqual("MikeDeRoy", textBox.text, kFailedToRemoveCharacterMessage);
|
||||
Assert.AreEqual(9, textBox.cursorIndex, kFailedToChangeCursor);
|
||||
Assert.AreEqual(9, textBox.selectIndex, kFailedToChangeSelect);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TextEditorWithUTF16_RightCursorOnBackspaceAndLeftSurrogate_RemovesBothSurrogates()
|
||||
{
|
||||
var textBox = new TextEditor()
|
||||
{
|
||||
text = "MikeDeRoy🗘",
|
||||
cursorIndex = 10,
|
||||
selectIndex = 10,
|
||||
};
|
||||
|
||||
textBox.Backspace();
|
||||
|
||||
Assert.AreEqual("MikeDeRoy", textBox.text, kFailedToRemoveCharacterMessage);
|
||||
Assert.AreEqual(9, textBox.cursorIndex, kFailedToChangeCursor);
|
||||
Assert.AreEqual(9, textBox.selectIndex, kFailedToChangeSelect);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TextEditorWithUTF16_RightCursorOnDeleteAndLeftSurrogate_RemovesBothSurrogates()
|
||||
{
|
||||
var textBox = new TextEditor()
|
||||
{
|
||||
text = "MikeDeRoy🗘",
|
||||
cursorIndex = 9,
|
||||
selectIndex = 9,
|
||||
};
|
||||
|
||||
textBox.Delete();
|
||||
|
||||
Assert.AreEqual("MikeDeRoy", textBox.text, kFailedToRemoveCharacterMessage);
|
||||
Assert.AreEqual(9, textBox.cursorIndex, kFailedToChangeCursor);
|
||||
Assert.AreEqual(9, textBox.selectIndex, kFailedToChangeSelect);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TextEditorWithUTF16_RightCursorOnBackspaceAndRightSurrogate_RemovesBothSurrogates()
|
||||
{
|
||||
var textBox = new TextEditor()
|
||||
{
|
||||
text = "MikeDeRoy🗘",
|
||||
cursorIndex = 11,
|
||||
selectIndex = 11,
|
||||
};
|
||||
|
||||
textBox.Backspace();
|
||||
|
||||
Assert.AreEqual("MikeDeRoy", textBox.text, kFailedToRemoveCharacterMessage);
|
||||
Assert.AreEqual(9, textBox.cursorIndex, kFailedToChangeCursor);
|
||||
Assert.AreEqual(9, textBox.selectIndex, kFailedToChangeSelect);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TextEditorWithUTF16_MiddleCursorOnBackspace_RemovesBothSurrogatesInSuccession()
|
||||
{
|
||||
var textBox = new TextEditor()
|
||||
{
|
||||
text = "Mike🗘🗘🗘DeRoy",
|
||||
cursorIndex = 8,
|
||||
selectIndex = 8,
|
||||
};
|
||||
|
||||
textBox.Backspace();
|
||||
|
||||
Assert.AreEqual("Mike🗘🗘DeRoy", textBox.text, kFailedToRemoveCharacterMessage);
|
||||
Assert.AreEqual(6, textBox.cursorIndex, kFailedToChangeCursor);
|
||||
Assert.AreEqual(6, textBox.selectIndex, kFailedToChangeSelect);
|
||||
|
||||
textBox.Backspace();
|
||||
|
||||
Assert.AreEqual("Mike🗘DeRoy", textBox.text, kFailedToRemoveCharacterMessage);
|
||||
Assert.AreEqual(4, textBox.cursorIndex, kFailedToChangeCursor);
|
||||
Assert.AreEqual(4, textBox.selectIndex, kFailedToChangeSelect);
|
||||
|
||||
textBox.Backspace();
|
||||
Assert.AreEqual("Mik🗘DeRoy", textBox.text, kFailedToRemoveCharacterMessage);
|
||||
Assert.AreEqual(3, textBox.cursorIndex, kFailedToChangeCursor);
|
||||
Assert.AreEqual(3, textBox.selectIndex, kFailedToChangeSelect);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TextEditorWithUTF16_MiddleCursorOnDelete_RemovesBothSurrogatesInSuccession()
|
||||
{
|
||||
var textBox = new TextEditor()
|
||||
{
|
||||
text = "Mike🗘🗘🗘DeRoy",
|
||||
cursorIndex = 6,
|
||||
selectIndex = 6,
|
||||
};
|
||||
|
||||
textBox.Delete();
|
||||
|
||||
Assert.AreEqual("Mike🗘🗘DeRoy", textBox.text, kFailedToRemoveCharacterMessage);
|
||||
Assert.AreEqual(6, textBox.cursorIndex, kFailedToChangeCursor);
|
||||
Assert.AreEqual(6, textBox.selectIndex, kFailedToChangeSelect);
|
||||
|
||||
textBox.Delete();
|
||||
|
||||
Assert.AreEqual("Mike🗘DeRoy", textBox.text, kFailedToRemoveCharacterMessage);
|
||||
Assert.AreEqual(6, textBox.cursorIndex, kFailedToChangeCursor);
|
||||
Assert.AreEqual(6, textBox.selectIndex, kFailedToChangeSelect);
|
||||
|
||||
textBox.Delete();
|
||||
Assert.AreEqual("Mike🗘eRoy", textBox.text, kFailedToRemoveCharacterMessage);
|
||||
Assert.AreEqual(6, textBox.cursorIndex, kFailedToChangeCursor);
|
||||
Assert.AreEqual(6, textBox.selectIndex, kFailedToChangeSelect);
|
||||
}
|
||||
}
|
@@ -0,0 +1,528 @@
|
||||
using System.Collections;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using UnityEngine;
|
||||
|
||||
public class TextEditorTests
|
||||
{
|
||||
TextEditor m_TextEditor;
|
||||
|
||||
static IEnumerable textWithCodePointBoundaryIndices
|
||||
{
|
||||
get
|
||||
{
|
||||
yield return new TestCaseData("", new[] { 0 });
|
||||
yield return new TestCaseData("abc", new[] { 0, 1, 2, 3 });
|
||||
yield return new TestCaseData("\U0001f642", new[] { 0, 2 }).SetName("(U+1F642)");
|
||||
yield return new TestCaseData("\U0001f642\U0001f643", new[] { 0, 2, 4 }).SetName("(U+1F642)(U+1F643)");
|
||||
yield return new TestCaseData("a\U0001f642b\U0001f643c", new[] { 0, 1, 3, 4, 6, 7 }).SetName("a(U+1F642)b(U+1F643)c");
|
||||
yield return new TestCaseData("Hello 😁 World", new[] { 0, 1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14 }).SetName("Hello (U+1F601) World");
|
||||
yield return new TestCaseData("見ざる🙈、聞かざる🙉、言わざる🙊", new[] { 0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 12, 13, 14, 15, 16, 17, 19 }).SetName("Three wise monkeys");
|
||||
}
|
||||
}
|
||||
|
||||
static IEnumerable textWithWordStartAndEndIndices
|
||||
{
|
||||
get
|
||||
{
|
||||
yield return new TestCaseData("", new int[0], new int[0]);
|
||||
yield return new TestCaseData(" ", new int[0], new int[0]);
|
||||
yield return new TestCaseData("one two three", new[] { 0, 4, 8 }, new[] { 3, 7, 13 });
|
||||
yield return new TestCaseData("\U00010000 \U00010001 \U00010002\U00010003", new[] { 0, 3, 6 }, new[] { 2, 5, 10 }).SetName("(U+10000) (U+10001) (U+10002)(U+10003)");
|
||||
yield return new TestCaseData("Hello 😁 World", new[] { 0, 6, 9 }, new[] { 5, 8, 14 }).SetName("Hello (U+1F601) World");
|
||||
yield return new TestCaseData("見ざる🙈、聞かざる🙉、言わざる🙊", new[] { 0, 3, 6, 10, 13, 17 }, new[] { 3, 6, 10, 13, 17, 19 }).SetName("Three wise monkeys");
|
||||
}
|
||||
}
|
||||
|
||||
// A sequences of punctuation characters is currently considered a word when deleting
|
||||
static IEnumerable textWithWordStartAndEndIndicesWherePunctuationIsAWord
|
||||
{
|
||||
get
|
||||
{
|
||||
yield return new TestCaseData(" ,. abc,. ", new[] { 1, 4, 7 }, new[] { 3, 7, 9 });
|
||||
}
|
||||
}
|
||||
|
||||
// but not when moving/selecting
|
||||
static IEnumerable textWithWordStartAndEndIndicesWherePunctuationIsNotAWord
|
||||
{
|
||||
get
|
||||
{
|
||||
yield return new TestCaseData(" ,. abc,. ", new[] { 4 }, new[] { 7 });
|
||||
}
|
||||
}
|
||||
|
||||
static IEnumerable textWithLineStartIndices
|
||||
{
|
||||
get
|
||||
{
|
||||
yield return new TestCaseData("\n\na\nbc\n\U0001f642\n\U0001f642\U0001f643\n\n ", new[] { 0, 1, 2, 4, 7, 10, 15, 16 }).SetName("(LF)(LF)a(LF)bc(LF)(U+1F642)(LF)(U+1F642)(U+1F643)(LF)(LF) ");
|
||||
yield return new TestCaseData("\n\na\nbc\n🙂\n🙂🙃\n\n ", new[] { 0, 1, 2, 4, 7, 10, 15, 16 }).SetName("(LF)(LF)a(LF)bc(LF)(U+1F642)(LF)(U+1F642)(U+1F643)(LF)(LF) ");
|
||||
}
|
||||
}
|
||||
|
||||
static IEnumerable textWithLineEndIndices
|
||||
{
|
||||
get
|
||||
{
|
||||
yield return new TestCaseData("\n\na\nbc\n\U0001f642\n\U0001f642\U0001f643\n\n ", new[] { 0, 1, 3, 6, 9, 14, 15, 17 }).SetName("(LF)(LF)a(LF)bc(LF)(U+1F642)(LF)(U+1F642)(U+1F643)(LF)(LF) ");
|
||||
yield return new TestCaseData("\n\na\nbc\n🙂\n🙂🙃\n\n ", new[] { 0, 1, 3, 6, 9, 14, 15, 17 }).SetName("(LF)(LF)a(LF)bc(LF)(U+1F642)(LF)(U+1F642)(U+1F643)(LF)(LF) ");
|
||||
}
|
||||
}
|
||||
|
||||
static IEnumerable textWithExpectedCursorAndSelectIndicesWhenSelectingCurrentWordAtIndex
|
||||
{
|
||||
get
|
||||
{
|
||||
yield return new TestCaseData("", new[] { 0 }, new[] { 0 });
|
||||
yield return new TestCaseData(" ", new[] { 1, 1 }, new[] { 0, 0 });
|
||||
yield return new TestCaseData("a", new[] { 1, 1 }, new[] { 0, 0 });
|
||||
yield return new TestCaseData("ab", new[] { 2, 2, 2 }, new[] { 0, 0, 0 });
|
||||
yield return new TestCaseData("ab cd", new[] { 2, 2, 4, 4, 6, 6, 6 }, new[] { 0, 0, 2, 2, 4, 4, 4 });
|
||||
yield return new TestCaseData("a,, ,, ,,b", new[] { 1, 3, 3, 5, 5, 7, 7, 9, 9, 11, 11, 12, 12 }, new[] { 0, 1, 1, 3, 3, 5, 5, 7, 7, 9, 9, 11, 11 });
|
||||
}
|
||||
}
|
||||
|
||||
[SetUp]
|
||||
public void TestSetup()
|
||||
{
|
||||
m_TextEditor = new TextEditor();
|
||||
m_TextEditor.DetectFocusChange();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SetText_MovesCursorAndSelectIndicesToNextCodePointIndexIfInvalid()
|
||||
{
|
||||
m_TextEditor.text = "ab";
|
||||
m_TextEditor.cursorIndex = m_TextEditor.selectIndex = 1;
|
||||
|
||||
m_TextEditor.text = "\U0001f642";
|
||||
|
||||
Assert.AreEqual(2, m_TextEditor.cursorIndex, "cursorIndex at invalid code point index");
|
||||
Assert.AreEqual(2, m_TextEditor.selectIndex, "selectIndex at invalid code point index");
|
||||
}
|
||||
|
||||
[Test, TestCaseSource("textWithCodePointBoundaryIndices")]
|
||||
public void SetCursorAndSelectIndices_MovesToNextCodePointIndexIfInvalid(string text, int[] codePointIndices)
|
||||
{
|
||||
m_TextEditor.text = text;
|
||||
|
||||
for (var index = 0; index <= text.Length; index++)
|
||||
{
|
||||
m_TextEditor.cursorIndex = m_TextEditor.selectIndex = index;
|
||||
|
||||
var nextCodePointIndex = index == text.Length ? index : codePointIndices.First(codePointIndex => codePointIndex > index);
|
||||
if (codePointIndices.Contains(index))
|
||||
Assert.AreEqual(index, m_TextEditor.cursorIndex, string.Format("cursorIndex {0} should not change if it's already at a valid code point index", index));
|
||||
else
|
||||
Assert.AreEqual(nextCodePointIndex, m_TextEditor.cursorIndex, string.Format("cursorIndex {0} did not move to next code point index", index));
|
||||
if (codePointIndices.Contains(index))
|
||||
Assert.AreEqual(index, m_TextEditor.selectIndex, string.Format("selectIndex {0} should not change if it's already at a valid code point index", index));
|
||||
else
|
||||
Assert.AreEqual(nextCodePointIndex, m_TextEditor.selectIndex, string.Format("selectIndex {0} did not move to next code point index", index));
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCaseSource("textWithWordStartAndEndIndices")]
|
||||
[TestCaseSource("textWithWordStartAndEndIndicesWherePunctuationIsAWord")]
|
||||
public void DeleteWordBack_DeletesBackToPreviousWordStart(string text, int[] wordStartIndices, int[] wordEndIndices)
|
||||
{
|
||||
for (var index = 0; index <= text.Length; index++)
|
||||
{
|
||||
m_TextEditor.text = text;
|
||||
m_TextEditor.cursorIndex = m_TextEditor.selectIndex = index;
|
||||
var oldCursorIndex = m_TextEditor.cursorIndex;
|
||||
var oldSelectIndex = m_TextEditor.selectIndex;
|
||||
|
||||
m_TextEditor.DeleteWordBack();
|
||||
|
||||
var previousWordStart = wordStartIndices.Reverse().FirstOrDefault(i => i < oldCursorIndex);
|
||||
Assert.AreEqual(previousWordStart, m_TextEditor.cursorIndex, string.Format("cursorIndex {0} did not move to previous word start", oldCursorIndex));
|
||||
Assert.AreEqual(previousWordStart, m_TextEditor.selectIndex, string.Format("selectIndex {0} did not move to previous word start", oldSelectIndex));
|
||||
Assert.AreEqual(text.Remove(previousWordStart, oldCursorIndex - previousWordStart), m_TextEditor.text, string.Format("wrong resulting text for cursorIndex {0}", oldCursorIndex));
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCaseSource("textWithWordStartAndEndIndices")]
|
||||
[TestCaseSource("textWithWordStartAndEndIndicesWherePunctuationIsAWord")]
|
||||
public void DeleteWordForward_DeletesForwardToNextWordStart(string text, int[] wordStartIndices, int[] wordEndIndices)
|
||||
{
|
||||
for (var index = 0; index <= text.Length; index++)
|
||||
{
|
||||
m_TextEditor.text = text;
|
||||
m_TextEditor.cursorIndex = m_TextEditor.selectIndex = index;
|
||||
var oldCursorIndex = m_TextEditor.cursorIndex;
|
||||
var oldSelectIndex = m_TextEditor.selectIndex;
|
||||
|
||||
m_TextEditor.DeleteWordForward();
|
||||
|
||||
var nextWordStart = oldCursorIndex == text.Length ? text.Length : wordStartIndices.Concat(new[] { text.Length }).First(i => i > oldCursorIndex);
|
||||
Assert.AreEqual(oldCursorIndex, m_TextEditor.cursorIndex, string.Format("cursorIndex {0} should not change", oldCursorIndex));
|
||||
Assert.AreEqual(oldSelectIndex, m_TextEditor.selectIndex, string.Format("selectIndex {0} should not change", oldSelectIndex));
|
||||
Assert.AreEqual(text.Remove(oldCursorIndex, nextWordStart - oldCursorIndex), m_TextEditor.text, string.Format("wrong resulting text for cursorIndex {0}", oldCursorIndex));
|
||||
}
|
||||
}
|
||||
|
||||
[Test, TestCaseSource("textWithCodePointBoundaryIndices")]
|
||||
public void Delete_RemovesCodePointRightOfCursor(string text, int[] codePointIndices)
|
||||
{
|
||||
for (var i = 0; i < codePointIndices.Length; i++)
|
||||
{
|
||||
var codePointIndex = codePointIndices[i];
|
||||
m_TextEditor.text = text;
|
||||
m_TextEditor.cursorIndex = m_TextEditor.selectIndex = codePointIndex;
|
||||
|
||||
m_TextEditor.Delete();
|
||||
|
||||
var nextCodePointIndex = i < codePointIndices.Length - 1 ? codePointIndices[i + 1] : codePointIndex;
|
||||
Assert.AreEqual(codePointIndex, m_TextEditor.cursorIndex, "cursorIndex should not change");
|
||||
Assert.AreEqual(codePointIndex, m_TextEditor.selectIndex, "selectIndex should not change");
|
||||
Assert.AreEqual(text.Remove(codePointIndex, nextCodePointIndex - codePointIndex), m_TextEditor.text, string.Format("wrong resulting text for cursorIndex {0}", codePointIndex));
|
||||
}
|
||||
}
|
||||
|
||||
[Test, TestCaseSource("textWithCodePointBoundaryIndices")]
|
||||
public void Backspace_RemovesCodePointLeftOfCursor(string text, int[] codePointIndices)
|
||||
{
|
||||
for (var i = codePointIndices.Length - 1; i >= 0; i--)
|
||||
{
|
||||
var codePointIndex = codePointIndices[i];
|
||||
m_TextEditor.text = text;
|
||||
m_TextEditor.cursorIndex = m_TextEditor.selectIndex = codePointIndex;
|
||||
var oldCursorIndex = m_TextEditor.cursorIndex;
|
||||
var oldSelectIndex = m_TextEditor.selectIndex;
|
||||
|
||||
m_TextEditor.Backspace();
|
||||
|
||||
var previousCodePointIndex = i > 0 ? codePointIndices[i - 1] : codePointIndex;
|
||||
var codePointLength = codePointIndex - previousCodePointIndex;
|
||||
Assert.AreEqual(oldCursorIndex - codePointLength, m_TextEditor.cursorIndex, string.Format("cursorIndex {0} did not move to before removed code point", oldCursorIndex));
|
||||
Assert.AreEqual(oldSelectIndex - codePointLength, m_TextEditor.selectIndex, string.Format("selectIndex {0} did not move to before removed code point", oldSelectIndex));
|
||||
Assert.AreEqual(text.Remove(previousCodePointIndex, codePointLength), m_TextEditor.text);
|
||||
}
|
||||
}
|
||||
|
||||
[Test, TestCaseSource("textWithCodePointBoundaryIndices")]
|
||||
public void MoveRight_SkipsInvalidCodePointIndices(string text, int[] codePointIndices)
|
||||
{
|
||||
m_TextEditor.text = text;
|
||||
m_TextEditor.cursorIndex = m_TextEditor.selectIndex = 0;
|
||||
|
||||
foreach (var expectedIndex in codePointIndices.Skip(1))
|
||||
{
|
||||
var oldCursorIndex = m_TextEditor.cursorIndex;
|
||||
var oldSelectIndex = m_TextEditor.selectIndex;
|
||||
|
||||
m_TextEditor.MoveRight();
|
||||
|
||||
Assert.AreEqual(expectedIndex, m_TextEditor.cursorIndex, string.Format("cursorIndex {0} did not move to next code point index", oldCursorIndex));
|
||||
Assert.AreEqual(expectedIndex, m_TextEditor.selectIndex, string.Format("selectIndex {0} did not move to next code point index", oldSelectIndex));
|
||||
}
|
||||
|
||||
Assert.AreEqual(text.Length, m_TextEditor.cursorIndex, "cursorIndex did not reach end");
|
||||
Assert.AreEqual(text.Length, m_TextEditor.selectIndex, "selectIndex did not reach end");
|
||||
|
||||
m_TextEditor.MoveRight();
|
||||
|
||||
Assert.AreEqual(text.Length, m_TextEditor.cursorIndex, "cursorIndex at end should not change");
|
||||
Assert.AreEqual(text.Length, m_TextEditor.selectIndex, "selectIndex at end should not change");
|
||||
}
|
||||
|
||||
[Test, TestCaseSource("textWithCodePointBoundaryIndices")]
|
||||
public void MoveLeft_SkipsInvalidCodePointIndices(string text, int[] codePointIndices)
|
||||
{
|
||||
m_TextEditor.text = text;
|
||||
m_TextEditor.cursorIndex = m_TextEditor.selectIndex = text.Length;
|
||||
|
||||
foreach (var expectedIndex in codePointIndices.Reverse().Skip(1))
|
||||
{
|
||||
var oldCursorIndex = m_TextEditor.cursorIndex;
|
||||
var oldSelectIndex = m_TextEditor.selectIndex;
|
||||
|
||||
m_TextEditor.MoveLeft();
|
||||
|
||||
Assert.AreEqual(expectedIndex, m_TextEditor.cursorIndex, string.Format("cursorIndex {0} did not move to previous code point index", oldCursorIndex));
|
||||
Assert.AreEqual(expectedIndex, m_TextEditor.selectIndex, string.Format("selectIndex {0} did not move to previous code point index", oldSelectIndex));
|
||||
}
|
||||
|
||||
Assert.AreEqual(0, m_TextEditor.cursorIndex, "cursorIndex did not reach start");
|
||||
Assert.AreEqual(0, m_TextEditor.selectIndex, "selectIndex did not reach start");
|
||||
|
||||
m_TextEditor.MoveLeft();
|
||||
|
||||
Assert.AreEqual(0, m_TextEditor.cursorIndex, "cursorIndex at start should not change");
|
||||
Assert.AreEqual(0, m_TextEditor.selectIndex, "selectIndex at start should not change");
|
||||
}
|
||||
|
||||
[Test, TestCaseSource("textWithLineStartIndices")]
|
||||
public void MoveLineStart_MovesCursorAfterPreviousLineFeed(string text, int[] lineStartIndices)
|
||||
{
|
||||
m_TextEditor.text = text;
|
||||
|
||||
for (var index = 0; index <= text.Length; index++)
|
||||
{
|
||||
m_TextEditor.cursorIndex = m_TextEditor.selectIndex = index;
|
||||
var oldCursorIndex = m_TextEditor.cursorIndex;
|
||||
var oldSelectIndex = m_TextEditor.selectIndex;
|
||||
|
||||
m_TextEditor.MoveLineStart();
|
||||
|
||||
var lineStart = lineStartIndices.Reverse().FirstOrDefault(i => i <= oldCursorIndex);
|
||||
Assert.AreEqual(lineStart, m_TextEditor.cursorIndex, string.Format("cursorIndex {0} did not move to line start", oldCursorIndex));
|
||||
Assert.AreEqual(lineStart, m_TextEditor.selectIndex, string.Format("selectIndex {0} did not move to line start", oldSelectIndex));
|
||||
}
|
||||
}
|
||||
|
||||
[Test, TestCaseSource("textWithLineEndIndices")]
|
||||
public void MoveLineEnd_MovesCursorBeforeNextLineFeed(string text, int[] lineEndIndices)
|
||||
{
|
||||
m_TextEditor.text = text;
|
||||
|
||||
for (var index = 0; index <= text.Length; index++)
|
||||
{
|
||||
m_TextEditor.cursorIndex = m_TextEditor.selectIndex = index;
|
||||
var oldCursorIndex = m_TextEditor.cursorIndex;
|
||||
var oldSelectIndex = m_TextEditor.selectIndex;
|
||||
|
||||
m_TextEditor.MoveLineEnd();
|
||||
|
||||
var lineEnd = lineEndIndices.First(i => i >= oldCursorIndex);
|
||||
Assert.AreEqual(lineEnd, m_TextEditor.cursorIndex, string.Format("cursorIndex {0} did not move to line end", oldCursorIndex));
|
||||
Assert.AreEqual(lineEnd, m_TextEditor.selectIndex, string.Format("selectIndex {0} did not move to line end", oldSelectIndex));
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void MoveTextStart_MovesCursorToStartOfText()
|
||||
{
|
||||
m_TextEditor.text = "Hello World";
|
||||
m_TextEditor.cursorIndex = m_TextEditor.selectIndex = 5;
|
||||
|
||||
m_TextEditor.MoveTextStart();
|
||||
|
||||
Assert.AreEqual(0, m_TextEditor.cursorIndex, "cursorIndex did not move to start of text");
|
||||
Assert.AreEqual(0, m_TextEditor.selectIndex, "selectIndex did not move to start of text");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void MoveTextEnd_MovesCursorToEndOfText()
|
||||
{
|
||||
m_TextEditor.text = "Hello World";
|
||||
m_TextEditor.cursorIndex = m_TextEditor.selectIndex = 5;
|
||||
|
||||
m_TextEditor.MoveTextEnd();
|
||||
|
||||
Assert.AreEqual(m_TextEditor.text.Length, m_TextEditor.cursorIndex, "cursorIndex did not move to end of text");
|
||||
Assert.AreEqual(m_TextEditor.text.Length, m_TextEditor.selectIndex, "selectIndex did not move to end of text");
|
||||
}
|
||||
|
||||
[Test, TestCaseSource("textWithCodePointBoundaryIndices")]
|
||||
public void SelectLeft_ExpandSelectionToPreviousCodePoint(string text, int[] codePointIndices)
|
||||
{
|
||||
m_TextEditor.text = text;
|
||||
m_TextEditor.cursorIndex = m_TextEditor.selectIndex = text.Length;
|
||||
|
||||
foreach (var expectedCursorIndex in codePointIndices.Reverse().Skip(1))
|
||||
{
|
||||
var oldCursorIndex = m_TextEditor.cursorIndex;
|
||||
var oldSelectIndex = m_TextEditor.selectIndex;
|
||||
|
||||
m_TextEditor.SelectLeft();
|
||||
|
||||
Assert.AreEqual(expectedCursorIndex, m_TextEditor.cursorIndex, string.Format("cursorIndex {0} did not move to previous code point index", oldCursorIndex));
|
||||
Assert.AreEqual(oldSelectIndex, m_TextEditor.selectIndex, "selectIndex should not change");
|
||||
}
|
||||
|
||||
Assert.AreEqual(0, m_TextEditor.cursorIndex, "cursorIndex did not reach start");
|
||||
|
||||
m_TextEditor.SelectLeft();
|
||||
|
||||
Assert.AreEqual(0, m_TextEditor.cursorIndex, "cursorIndex at start should not change");
|
||||
}
|
||||
|
||||
[Test, TestCaseSource("textWithCodePointBoundaryIndices")]
|
||||
public void SelectRight_ExpandSelectionToNextCodePoint(string text, int[] codePointIndices)
|
||||
{
|
||||
m_TextEditor.text = text;
|
||||
m_TextEditor.cursorIndex = m_TextEditor.selectIndex = 0;
|
||||
|
||||
foreach (var expectedCursorIndex in codePointIndices.Skip(1))
|
||||
{
|
||||
var oldCursorIndex = m_TextEditor.cursorIndex;
|
||||
var oldSelectIndex = m_TextEditor.selectIndex;
|
||||
|
||||
m_TextEditor.SelectRight();
|
||||
|
||||
Assert.AreEqual(expectedCursorIndex, m_TextEditor.cursorIndex, string.Format("cursorIndex {0} did not move to next code point index", oldCursorIndex));
|
||||
Assert.AreEqual(oldSelectIndex, m_TextEditor.selectIndex, "selectIndex should not change");
|
||||
}
|
||||
|
||||
Assert.AreEqual(text.Length, m_TextEditor.cursorIndex, "cursorIndex did not reach end");
|
||||
|
||||
m_TextEditor.SelectRight();
|
||||
|
||||
Assert.AreEqual(text.Length, m_TextEditor.cursorIndex, "cursorIndex at end should not change");
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCaseSource("textWithWordStartAndEndIndices")]
|
||||
[TestCaseSource("textWithWordStartAndEndIndicesWherePunctuationIsNotAWord")]
|
||||
public void MoveWordRight_MovesCursorToNextWordEnd(string text, int[] wordStartIndices, int[] wordEndIndices)
|
||||
{
|
||||
if (text.Any(char.IsSurrogate))
|
||||
Assert.Ignore("char.IsLetterOrDigit(string, int) does not currently work correctly with surrogates");
|
||||
|
||||
m_TextEditor.text = text;
|
||||
|
||||
for (var index = 0; index <= text.Length; index++)
|
||||
{
|
||||
m_TextEditor.cursorIndex = m_TextEditor.selectIndex = index;
|
||||
var oldCursorIndex = m_TextEditor.cursorIndex;
|
||||
var oldSelectIndex = m_TextEditor.selectIndex;
|
||||
|
||||
m_TextEditor.MoveWordRight();
|
||||
|
||||
var nextWordEnd = wordEndIndices.FirstOrDefault(i => i > oldCursorIndex);
|
||||
if (nextWordEnd == 0)
|
||||
nextWordEnd = text.Length;
|
||||
Assert.AreEqual(nextWordEnd, m_TextEditor.cursorIndex, string.Format("cursorIndex {0} did not move to next word start", oldCursorIndex));
|
||||
Assert.AreEqual(nextWordEnd, m_TextEditor.selectIndex, string.Format("selectIndex {0} did not move to next word start", oldSelectIndex));
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCaseSource("textWithWordStartAndEndIndices")]
|
||||
[TestCaseSource("textWithWordStartAndEndIndicesWherePunctuationIsAWord")]
|
||||
public void MoveToStartOfNextWord_MovesCursorToNextWordStart(string text, int[] wordStartIndices, int[] wordEndIndices)
|
||||
{
|
||||
m_TextEditor.text = text;
|
||||
|
||||
for (var index = 0; index <= text.Length; index++)
|
||||
{
|
||||
m_TextEditor.cursorIndex = m_TextEditor.selectIndex = index;
|
||||
var oldCursorIndex = m_TextEditor.cursorIndex;
|
||||
var oldSelectIndex = m_TextEditor.selectIndex;
|
||||
|
||||
m_TextEditor.MoveToStartOfNextWord();
|
||||
|
||||
var nextWordStart = oldCursorIndex == text.Length ? text.Length : wordStartIndices.Concat(new[] { text.Length }).First(i => i > oldCursorIndex);
|
||||
Assert.AreEqual(nextWordStart, m_TextEditor.cursorIndex, string.Format("cursorIndex {0} did not move to start of next word", oldCursorIndex));
|
||||
Assert.AreEqual(nextWordStart, m_TextEditor.selectIndex, string.Format("selectIndex {0} did not move to start of next word", oldSelectIndex));
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCaseSource("textWithWordStartAndEndIndices")]
|
||||
[TestCaseSource("textWithWordStartAndEndIndicesWherePunctuationIsAWord")]
|
||||
public void MoveToEndOfPreviousWord_MovesCursorToPreviousWordStart(string text, int[] wordStartIndices, int[] wordEndIndices)
|
||||
{
|
||||
m_TextEditor.text = text;
|
||||
|
||||
for (var index = 0; index <= text.Length; index++)
|
||||
{
|
||||
m_TextEditor.cursorIndex = m_TextEditor.selectIndex = index;
|
||||
var oldCursorIndex = m_TextEditor.cursorIndex;
|
||||
var oldSelectIndex = m_TextEditor.selectIndex;
|
||||
|
||||
m_TextEditor.MoveToEndOfPreviousWord();
|
||||
|
||||
var previousWordStart = wordStartIndices.Reverse().FirstOrDefault(i => i < oldCursorIndex);
|
||||
Assert.AreEqual(previousWordStart, m_TextEditor.cursorIndex, string.Format("cursorIndex {0} did not move to previous word start", oldCursorIndex));
|
||||
Assert.AreEqual(previousWordStart, m_TextEditor.selectIndex, string.Format("selectIndex {0} did not move to previous word start", oldSelectIndex));
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCaseSource("textWithWordStartAndEndIndices")]
|
||||
[TestCaseSource("textWithWordStartAndEndIndicesWherePunctuationIsAWord")]
|
||||
public void FindStartOfNextWord_ReturnsIndexOfNextWordStart(string text, int[] wordStartIndices, int[] wordEndIndices)
|
||||
{
|
||||
if (text.Any(char.IsSurrogate))
|
||||
Assert.Ignore("char.IsLetterOrDigit(string, int) does not currently work correctly with surrogates");
|
||||
|
||||
m_TextEditor.text = text;
|
||||
|
||||
for (var index = 0; index <= text.Length; index++)
|
||||
{
|
||||
var nextWordStart = index == text.Length ? text.Length : wordStartIndices.Concat(new[] {text.Length}).First(i => i > index);
|
||||
Assert.AreEqual(nextWordStart, m_TextEditor.FindStartOfNextWord(index));
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCaseSource("textWithWordStartAndEndIndices")]
|
||||
[TestCaseSource("textWithWordStartAndEndIndicesWherePunctuationIsNotAWord")]
|
||||
public void MoveWordLeft_MovesCursorToPreviousWordStart(string text, int[] wordStartIndices, int[] wordEndIndices)
|
||||
{
|
||||
if (text.Any(char.IsSurrogate))
|
||||
Assert.Ignore("char.IsLetterOrDigit(string, int) does not currently work correctly with surrogates");
|
||||
|
||||
m_TextEditor.text = text;
|
||||
|
||||
for (var index = 0; index <= text.Length; index++)
|
||||
{
|
||||
m_TextEditor.cursorIndex = m_TextEditor.selectIndex = index;
|
||||
var oldCursorIndex = m_TextEditor.cursorIndex;
|
||||
var oldSelectIndex = m_TextEditor.selectIndex;
|
||||
|
||||
m_TextEditor.MoveWordLeft();
|
||||
|
||||
var previousWordStart = wordStartIndices.Reverse().FirstOrDefault(i => i < oldCursorIndex);
|
||||
Assert.AreEqual(previousWordStart, m_TextEditor.cursorIndex, string.Format("cursorIndex {0} did not move to previous word start", oldCursorIndex));
|
||||
Assert.AreEqual(previousWordStart, m_TextEditor.selectIndex, string.Format("selectIndex {0} did not move to previous word start", oldSelectIndex));
|
||||
}
|
||||
}
|
||||
|
||||
[Test, TestCaseSource("textWithExpectedCursorAndSelectIndicesWhenSelectingCurrentWordAtIndex")]
|
||||
public void SelectCurrentWord(string text, int[] expectedCursorIndices, int[] expectedSelectIndices)
|
||||
{
|
||||
m_TextEditor.text = text;
|
||||
|
||||
for (var index = 0; index <= text.Length; index++)
|
||||
{
|
||||
m_TextEditor.cursorIndex = m_TextEditor.selectIndex = index;
|
||||
var oldCursorIndex = m_TextEditor.cursorIndex;
|
||||
|
||||
m_TextEditor.SelectCurrentWord();
|
||||
|
||||
Assert.AreEqual(expectedCursorIndices[index], m_TextEditor.cursorIndex, string.Format("wrong cursorIndex for initial cursorIndex {0}", oldCursorIndex));
|
||||
Assert.AreEqual(expectedSelectIndices[index], m_TextEditor.selectIndex, string.Format("wrong selectIndex for initial cursorIndex {0}", oldCursorIndex));
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void HandleKeyEvent_WithControlAKeyDownEvent_MovesCursorToStartOfLineOnMacOS_SelectsAllElsewhere()
|
||||
{
|
||||
const string text = "foo";
|
||||
m_TextEditor.text = text;
|
||||
m_TextEditor.MoveLineEnd();
|
||||
var controlAKeyDownEvent = new Event { type = EventType.KeyDown, keyCode = KeyCode.A, modifiers = EventModifiers.Control };
|
||||
|
||||
m_TextEditor.HandleKeyEvent(controlAKeyDownEvent);
|
||||
|
||||
if (SystemInfo.operatingSystemFamily == OperatingSystemFamily.MacOSX)
|
||||
{
|
||||
Assert.That(m_TextEditor.SelectedText, Is.Empty, "Selected text was not empty");
|
||||
Assert.That(m_TextEditor.cursorIndex, Is.EqualTo(0), "Cursor did not move to start of line");
|
||||
}
|
||||
else
|
||||
Assert.That(m_TextEditor.SelectedText, Is.EqualTo(text), "Text was not selected");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void HandleKeyEvent_WithCommandAKeyDownEvent_SelectsAllOnMacOS()
|
||||
{
|
||||
if (SystemInfo.operatingSystemFamily != OperatingSystemFamily.MacOSX)
|
||||
Assert.Ignore("Test is only applicable on macOS");
|
||||
|
||||
const string text = "foo";
|
||||
m_TextEditor.text = text;
|
||||
var commandAKeyDownEvent = new Event { type = EventType.KeyDown, keyCode = KeyCode.A, modifiers = EventModifiers.Command };
|
||||
|
||||
m_TextEditor.HandleKeyEvent(commandAKeyDownEvent);
|
||||
|
||||
Assert.That(m_TextEditor.SelectedText, Is.EqualTo(text), "Text was not selected");
|
||||
}
|
||||
}
|
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
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;
|
||||
using UnityEngine.UI.Tests;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace ToggleTest
|
||||
{
|
||||
class TestableToggleGroup : ToggleGroup
|
||||
{
|
||||
public bool ToggleListContains(Toggle toggle)
|
||||
{
|
||||
return m_Toggles.Contains(toggle);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,160 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.TestTools;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.UI.Tests;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace ToggleTest
|
||||
{
|
||||
class ToggleGroupTests : IPrebuildSetup
|
||||
{
|
||||
const string kPrefabToggleGroupPath = "Assets/Resources/TestToggleGroup.prefab";
|
||||
|
||||
protected GameObject m_PrefabRoot;
|
||||
protected List<Toggle> m_toggle = new List<Toggle>();
|
||||
protected static int nbToggleInGroup = 2;
|
||||
private TestableToggleGroup m_toggleGroup;
|
||||
|
||||
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 toggleGroupGO = new GameObject("ToggleGroup", typeof(RectTransform), typeof(TestableToggleGroup));
|
||||
toggleGroupGO.transform.SetParent(canvasGO.transform);
|
||||
toggleGroupGO.AddComponent(typeof(TestableToggleGroup));
|
||||
|
||||
var toggle0GO = new GameObject("TestToggle0", typeof(RectTransform), typeof(Toggle), typeof(Image));
|
||||
toggle0GO.transform.SetParent(toggleGroupGO.transform);
|
||||
|
||||
var toggle1GO = new GameObject("TestToggle1", typeof(RectTransform), typeof(Toggle), typeof(Image));
|
||||
toggle1GO.transform.SetParent(toggleGroupGO.transform);
|
||||
|
||||
var toggle = toggle0GO.GetComponent<Toggle>();
|
||||
toggle.graphic = toggle0GO.GetComponent<Image>();
|
||||
toggle.graphic.canvasRenderer.SetColor(Color.white);
|
||||
|
||||
var toggle1 = toggle1GO.GetComponent<Toggle>();
|
||||
toggle1.graphic = toggle1GO.GetComponent<Image>();
|
||||
toggle1.graphic.canvasRenderer.SetColor(Color.white);
|
||||
|
||||
|
||||
if (!Directory.Exists("Assets/Resources/"))
|
||||
Directory.CreateDirectory("Assets/Resources/");
|
||||
|
||||
PrefabUtility.SaveAsPrefabAsset(rootGO, kPrefabToggleGroupPath);
|
||||
|
||||
GameObject.DestroyImmediate(rootGO);
|
||||
#endif
|
||||
}
|
||||
|
||||
[SetUp]
|
||||
public void TestSetup()
|
||||
{
|
||||
m_PrefabRoot = Object.Instantiate(Resources.Load("TestToggleGroup")) as GameObject;
|
||||
|
||||
m_toggleGroup = m_PrefabRoot.GetComponentInChildren<TestableToggleGroup>();
|
||||
m_toggle.AddRange(m_PrefabRoot.GetComponentsInChildren<Toggle>());
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
m_toggle.Clear();
|
||||
m_toggleGroup = null;
|
||||
Object.DestroyImmediate(m_PrefabRoot);
|
||||
}
|
||||
|
||||
[OneTimeTearDown]
|
||||
public void OneTimeTearDown()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
AssetDatabase.DeleteAsset(kPrefabToggleGroupPath);
|
||||
#endif
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TogglingOneShouldDisableOthersInGroup()
|
||||
{
|
||||
m_toggle[0].group = m_toggleGroup;
|
||||
m_toggle[1].group = m_toggleGroup;
|
||||
m_toggle[0].isOn = true;
|
||||
m_toggle[1].isOn = true;
|
||||
Assert.IsFalse(m_toggle[0].isOn);
|
||||
Assert.IsTrue(m_toggle[1].isOn);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DisallowSwitchOffShouldKeepToggleOnWhenClicking()
|
||||
{
|
||||
m_toggle[0].group = m_toggleGroup;
|
||||
m_toggle[1].group = m_toggleGroup;
|
||||
m_toggle[0].isOn = true;
|
||||
Assert.IsTrue(m_toggle[0].isOn);
|
||||
m_toggle[0].OnPointerClick(new PointerEventData(EventSystem.current) { button = PointerEventData.InputButton.Left });
|
||||
Assert.IsTrue(m_toggle[0].isOn);
|
||||
Assert.IsFalse(m_toggle[1].isOn);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DisallowSwitchOffShouldDisableToggleWhenClicking()
|
||||
{
|
||||
m_toggleGroup.allowSwitchOff = true;
|
||||
m_toggle[0].group = m_toggleGroup;
|
||||
m_toggle[1].group = m_toggleGroup;
|
||||
m_toggle[0].isOn = true;
|
||||
Assert.IsTrue(m_toggle[0].isOn);
|
||||
m_toggle[0].OnPointerClick(new PointerEventData(EventSystem.current) { button = PointerEventData.InputButton.Left });
|
||||
Assert.IsFalse(m_toggle[0].isOn);
|
||||
Assert.IsFalse(m_toggle[1].isOn);
|
||||
}
|
||||
|
||||
[TestCase(0)]
|
||||
[TestCase(1)]
|
||||
public void ReEnablingGameObjectWithToggleGroupRetainsPreviouslySelectedToggle(int toggleIndex)
|
||||
{
|
||||
m_toggle[0].group = m_toggleGroup;
|
||||
m_toggle[1].group = m_toggleGroup;
|
||||
|
||||
m_toggle[toggleIndex].isOn = true;
|
||||
m_PrefabRoot.SetActive(false);
|
||||
m_PrefabRoot.SetActive(true);
|
||||
Assert.IsTrue(m_toggle[toggleIndex].isOn);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ChangingToggleGroupUnregistersFromOriginalGroup()
|
||||
{
|
||||
m_toggle[0].group = m_toggleGroup;
|
||||
Assert.IsTrue(m_toggleGroup.ToggleListContains(m_toggle[0]));
|
||||
m_toggle[0].group = null;
|
||||
Assert.IsFalse(m_toggleGroup.ToggleListContains(m_toggle[0]));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DisabledToggleGroupDoesntControlChildren()
|
||||
{
|
||||
m_toggleGroup.enabled = false;
|
||||
m_toggle[0].group = m_toggleGroup;
|
||||
m_toggle[1].group = m_toggleGroup;
|
||||
m_toggle[0].isOn = true;
|
||||
m_toggle[1].isOn = true;
|
||||
Assert.IsTrue(m_toggle[0].isOn);
|
||||
Assert.IsTrue(m_toggle[1].isOn);
|
||||
|
||||
m_toggleGroup.enabled = true;
|
||||
IEnumerable<Toggle> activeToggles = m_toggleGroup.ActiveToggles();
|
||||
Assert.IsTrue(activeToggles.Count() == 1);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,105 @@
|
||||
using System;
|
||||
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;
|
||||
using UnityEngine.UI.Tests;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace ToggleTest
|
||||
{
|
||||
class ToggleTests : IPrebuildSetup
|
||||
{
|
||||
const string kPrefabTogglePath = "Assets/Resources/TestToggle.prefab";
|
||||
|
||||
protected GameObject m_PrefabRoot;
|
||||
protected List<Toggle> m_toggle = new List<Toggle>();
|
||||
protected static int nbToggleInGroup = 2;
|
||||
|
||||
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 toggleGO = new GameObject("TestToggle", typeof(RectTransform), typeof(Toggle), typeof(Image));
|
||||
toggleGO.transform.SetParent(canvasGO.transform);
|
||||
|
||||
var toggle = toggleGO.GetComponent<Toggle>();
|
||||
toggle.enabled = true;
|
||||
toggle.graphic = toggleGO.GetComponent<Image>();
|
||||
toggle.graphic.canvasRenderer.SetColor(Color.white);
|
||||
|
||||
if (!Directory.Exists("Assets/Resources/"))
|
||||
Directory.CreateDirectory("Assets/Resources/");
|
||||
|
||||
PrefabUtility.SaveAsPrefabAsset(rootGO, kPrefabTogglePath);
|
||||
|
||||
GameObject.DestroyImmediate(rootGO);
|
||||
#endif
|
||||
}
|
||||
|
||||
[SetUp]
|
||||
public virtual void TestSetup()
|
||||
{
|
||||
m_PrefabRoot = Object.Instantiate(Resources.Load("TestToggle")) as GameObject;
|
||||
m_toggle.Add(m_PrefabRoot.GetComponentInChildren<Toggle>());
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public virtual void TearDown()
|
||||
{
|
||||
m_toggle.Clear();
|
||||
Object.DestroyImmediate(m_PrefabRoot);
|
||||
}
|
||||
|
||||
[OneTimeTearDown]
|
||||
public void OneTimeTearDown()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
AssetDatabase.DeleteAsset(kPrefabTogglePath);
|
||||
#endif
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SetIsOnWithoutNotifyWillNotNotify()
|
||||
{
|
||||
m_toggle[0].isOn = false;
|
||||
bool calledOnValueChanged = false;
|
||||
m_toggle[0].onValueChanged.AddListener(b => { calledOnValueChanged = true; });
|
||||
m_toggle[0].SetIsOnWithoutNotify(true);
|
||||
Assert.IsTrue(m_toggle[0].isOn);
|
||||
Assert.IsFalse(calledOnValueChanged);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void NonInteractableCantBeToggled()
|
||||
{
|
||||
m_toggle[0].isOn = true;
|
||||
Assert.IsTrue(m_toggle[0].isOn);
|
||||
m_toggle[0].interactable = false;
|
||||
m_toggle[0].OnSubmit(null);
|
||||
Assert.IsTrue(m_toggle[0].isOn);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void InactiveCantBeToggled()
|
||||
{
|
||||
m_toggle[0].isOn = true;
|
||||
Assert.IsTrue(m_toggle[0].isOn);
|
||||
m_toggle[0].enabled = false;
|
||||
m_toggle[0].OnSubmit(null);
|
||||
Assert.IsTrue(m_toggle[0].isOn);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"name": "UnityEngine.UI.Tests",
|
||||
"references": [
|
||||
"UnityEngine.UI",
|
||||
"UnityEngine.TestRunner",
|
||||
"UnityEditor.TestRunner"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": true,
|
||||
"precompiledReferences": [
|
||||
"nunit.framework.dll"
|
||||
],
|
||||
"autoReferenced": false,
|
||||
"defineConstraints": [
|
||||
"UNITY_INCLUDE_TESTS"
|
||||
],
|
||||
"versionDefines": [
|
||||
{
|
||||
"name": "com.unity.modules.physics",
|
||||
"expression": "1.0.0",
|
||||
"define": "PACKAGE_PHYSICS"
|
||||
},
|
||||
{
|
||||
"name": "com.unity.modules.physics2d",
|
||||
"expression": "1.0.0",
|
||||
"define": "PACKAGE_PHYSICS2D"
|
||||
},
|
||||
{
|
||||
"name": "com.unity.modules.animation",
|
||||
"expression": "1.0.0",
|
||||
"define": "PACKAGE_ANIMATION"
|
||||
}
|
||||
],
|
||||
"noEngineReferences": false
|
||||
}
|
@@ -0,0 +1,13 @@
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace UnityEngine.UI.Tests
|
||||
{
|
||||
// Make a non-abstract Graphic.
|
||||
public class ConcreteGraphic : Graphic
|
||||
{
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("{0} '{1}'", GetType().Name, this.gameObject.name);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace UnityEngine.UI.Tests.Utils
|
||||
{
|
||||
class ExceptionUtils
|
||||
{
|
||||
public static void PreserveStackTrace(Exception e)
|
||||
{
|
||||
var ctx = new StreamingContext(StreamingContextStates.CrossAppDomain);
|
||||
var mgr = new ObjectManager(null, ctx);
|
||||
var si = new SerializationInfo(e.GetType(), new FormatterConverter());
|
||||
|
||||
e.GetObjectData(si, ctx);
|
||||
mgr.RegisterObject(e, 1, si); // prepare for SetObjectData
|
||||
mgr.DoFixups(); // ObjectManager calls SetObjectData
|
||||
|
||||
// voila, e is unmodified save for _remoteStackTraceString
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,73 @@
|
||||
using System.Collections.Generic;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace UnityEngine.UI.Tests
|
||||
{
|
||||
static class GraphicTestHelper
|
||||
{
|
||||
public static void TestOnPopulateMeshDefaultBehavior(Graphic graphic, VertexHelper 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 = graphic.color,
|
||||
position = new Vector3(graphic.rectTransform.rect.x, graphic.rectTransform.rect.y),
|
||||
uv0 = new Vector2(0f, 0f),
|
||||
normal = new Vector3(0, 0, -1),
|
||||
tangent = new Vector4(1, 0, 0, -1)
|
||||
},
|
||||
new UIVertex
|
||||
{
|
||||
color = graphic.color,
|
||||
position = new Vector3(graphic.rectTransform.rect.x, graphic.rectTransform.rect.y + graphic.rectTransform.rect.height),
|
||||
uv0 = new Vector2(0f, 1f),
|
||||
normal = new Vector3(0, 0, -1),
|
||||
tangent = new Vector4(1, 0, 0, -1)
|
||||
},
|
||||
new UIVertex
|
||||
{
|
||||
color = graphic.color,
|
||||
position = new Vector3(graphic.rectTransform.rect.x + graphic.rectTransform.rect.width, graphic.rectTransform.rect.y + graphic.rectTransform.rect.height),
|
||||
uv0 = new Vector2(1f, 1f),
|
||||
normal = new Vector3(0, 0, -1),
|
||||
tangent = new Vector4(1, 0, 0, -1)
|
||||
},
|
||||
new UIVertex
|
||||
{
|
||||
color = graphic.color,
|
||||
position = new Vector3(graphic.rectTransform.rect.x + graphic.rectTransform.rect.width, graphic.rectTransform.rect.y + graphic.rectTransform.rect.height),
|
||||
uv0 = new Vector2(1f, 1f),
|
||||
normal = new Vector3(0, 0, -1),
|
||||
tangent = new Vector4(1, 0, 0, -1)
|
||||
},
|
||||
new UIVertex
|
||||
{
|
||||
color = graphic.color,
|
||||
position = new Vector3(graphic.rectTransform.rect.x + graphic.rectTransform.rect.width, graphic.rectTransform.rect.y),
|
||||
uv0 = new Vector2(1f, 0f),
|
||||
normal = new Vector3(0, 0, -1),
|
||||
tangent = new Vector4(1, 0, 0, -1)
|
||||
},
|
||||
new UIVertex
|
||||
{
|
||||
color = graphic.color,
|
||||
position = new Vector3(graphic.rectTransform.rect.x, graphic.rectTransform.rect.y),
|
||||
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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,50 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEngine.UI.Tests
|
||||
{
|
||||
// Hook into the graphic callback so we can do our check.
|
||||
public class ImageHook : Image
|
||||
{
|
||||
public bool isGeometryUpdated;
|
||||
public bool isLayoutRebuild;
|
||||
public bool isMaterialRebuilt;
|
||||
public Rect cachedClipRect;
|
||||
|
||||
public void ResetTest()
|
||||
{
|
||||
isGeometryUpdated = false;
|
||||
isLayoutRebuild = false;
|
||||
isMaterialRebuilt = false;
|
||||
}
|
||||
|
||||
public override void SetLayoutDirty()
|
||||
{
|
||||
base.SetLayoutDirty();
|
||||
isLayoutRebuild = true;
|
||||
}
|
||||
|
||||
public override void SetMaterialDirty()
|
||||
{
|
||||
base.SetMaterialDirty();
|
||||
isMaterialRebuilt = true;
|
||||
}
|
||||
|
||||
protected override void UpdateGeometry()
|
||||
{
|
||||
base.UpdateGeometry();
|
||||
isGeometryUpdated = true;
|
||||
}
|
||||
|
||||
public override void SetClipRect(Rect clipRect, bool validRect)
|
||||
{
|
||||
cachedClipRect = clipRect;
|
||||
if (validRect)
|
||||
canvasRenderer.EnableRectClipping(clipRect);
|
||||
else
|
||||
canvasRenderer.DisableRectClipping();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,55 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
namespace UnityEngine.UI.Tests
|
||||
{
|
||||
class PrivateFieldSetter<T> : IDisposable
|
||||
{
|
||||
private object m_Obj;
|
||||
private FieldInfo m_FieldInfo;
|
||||
private object m_OldValue;
|
||||
|
||||
public PrivateFieldSetter(object obj, string field, object value)
|
||||
{
|
||||
m_Obj = obj;
|
||||
m_FieldInfo = typeof(T).GetField(field, BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
m_OldValue = m_FieldInfo.GetValue(obj);
|
||||
m_FieldInfo.SetValue(obj, value);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
m_FieldInfo.SetValue(m_Obj, m_OldValue);
|
||||
}
|
||||
}
|
||||
|
||||
static class PrivateStaticField
|
||||
{
|
||||
public static T GetValue<T>(Type staticType, string fieldName)
|
||||
{
|
||||
var type = staticType;
|
||||
FieldInfo field = null;
|
||||
while (field == null && type != null)
|
||||
{
|
||||
field = type.GetField(fieldName, BindingFlags.Static | BindingFlags.NonPublic);
|
||||
type = type.BaseType;
|
||||
}
|
||||
return (T)field.GetValue(null);
|
||||
}
|
||||
}
|
||||
|
||||
static class PrivateField
|
||||
{
|
||||
public static T GetValue<T>(this object o, string fieldName)
|
||||
{
|
||||
var type = o.GetType();
|
||||
FieldInfo field = null;
|
||||
while (field == null && type != null)
|
||||
{
|
||||
field = type.GetField(fieldName, BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
type = type.BaseType;
|
||||
}
|
||||
return field != null ? (T)field.GetValue(o) : default(T);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,149 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using NUnit.Framework;
|
||||
using UnityEngine.EventSystems;
|
||||
|
||||
namespace UnityEngine.UI.Tests
|
||||
{
|
||||
public static class UIBehaviourExtensions
|
||||
{
|
||||
private static object InvokeMethodAndRethrow(Type type, Object obj, string methodName, params object[] args)
|
||||
{
|
||||
BindingFlags flags = BindingFlags.Default;
|
||||
flags |= BindingFlags.Public;
|
||||
flags |= BindingFlags.NonPublic;
|
||||
if (obj != null)
|
||||
flags |= BindingFlags.Instance;
|
||||
else
|
||||
flags |= BindingFlags.Static;
|
||||
MethodInfo method;
|
||||
|
||||
try
|
||||
{
|
||||
// Attempt to get the method plainly at first
|
||||
method = type.GetMethod(methodName, flags);
|
||||
}
|
||||
catch (AmbiguousMatchException)
|
||||
{
|
||||
// If it's ambiguous, then attempt to get it using its params (though nulls would mess things up).
|
||||
method = type.GetMethod(methodName, flags, null, args.Select(a => a != null ? a.GetType() : null).Where(a => a != null).ToArray(), new ParameterModifier[0]);
|
||||
}
|
||||
Assert.NotNull(method, string.Format("Not method {0} found on object {1}", methodName, obj));
|
||||
return method.Invoke(obj, args);
|
||||
}
|
||||
|
||||
public static object InvokeMethodAndRethrow<T>(Object obj, string methodName, params object[] args)
|
||||
{
|
||||
return InvokeMethodAndRethrow(typeof(T), obj, methodName, args);
|
||||
}
|
||||
|
||||
public static object InvokeMethodAndRethrow(Object obj, string methodName, params object[] args)
|
||||
{
|
||||
return InvokeMethodAndRethrow(obj.GetType(), obj, methodName, args);
|
||||
}
|
||||
|
||||
public static void InvokeOnEnable(this UIBehaviour behaviour)
|
||||
{
|
||||
InvokeMethodAndRethrow(behaviour, "OnEnable");
|
||||
}
|
||||
|
||||
public static void InvokeOnDisable(this UIBehaviour behaviour)
|
||||
{
|
||||
InvokeMethodAndRethrow(behaviour, "OnDisable");
|
||||
}
|
||||
|
||||
public static void InvokeAwake(this UIBehaviour behaviour)
|
||||
{
|
||||
InvokeMethodAndRethrow(behaviour, "Awake");
|
||||
}
|
||||
|
||||
public static void InvokeRebuild(this UIBehaviour behaviour, CanvasUpdate type)
|
||||
{
|
||||
InvokeMethodAndRethrow(behaviour, "Rebuild", type);
|
||||
}
|
||||
|
||||
public static void InvokeLateUpdate(this UIBehaviour behaviour)
|
||||
{
|
||||
InvokeMethodAndRethrow(behaviour, "LateUpdate");
|
||||
}
|
||||
|
||||
public static void InvokeUpdate(this UIBehaviour behaviour)
|
||||
{
|
||||
InvokeMethodAndRethrow(behaviour, "Update");
|
||||
}
|
||||
|
||||
public static void InvokeOnRectTransformDimensionsChange(this UIBehaviour behaviour)
|
||||
{
|
||||
InvokeMethodAndRethrow(behaviour, "OnRectTransformDimensionsChange");
|
||||
}
|
||||
|
||||
public static void InvokeOnCanvasGroupChanged(this UIBehaviour behaviour)
|
||||
{
|
||||
InvokeMethodAndRethrow(behaviour, "OnCanvasGroupChanged");
|
||||
}
|
||||
|
||||
public static void InvokeOnDidApplyAnimationProperties(this UIBehaviour behaviour)
|
||||
{
|
||||
InvokeMethodAndRethrow(behaviour, "OnDidApplyAnimationProperties");
|
||||
}
|
||||
}
|
||||
|
||||
public static class SelectableExtensions
|
||||
{
|
||||
public static void InvokeOnPointerDown(this Selectable selectable, PointerEventData data)
|
||||
{
|
||||
UIBehaviourExtensions.InvokeMethodAndRethrow<Selectable>(selectable, "OnPointerDown", data);
|
||||
}
|
||||
|
||||
public static void InvokeOnPointerUp(this Selectable selectable, PointerEventData data)
|
||||
{
|
||||
UIBehaviourExtensions.InvokeMethodAndRethrow<Selectable>(selectable, "OnPointerUp", data);
|
||||
}
|
||||
|
||||
public static void InvokeOnPointerEnter(this Selectable selectable, PointerEventData data)
|
||||
{
|
||||
UIBehaviourExtensions.InvokeMethodAndRethrow<Selectable>(selectable, "OnPointerEnter", data);
|
||||
}
|
||||
|
||||
public static void InvokeOnPointerExit(this Selectable selectable, PointerEventData data)
|
||||
{
|
||||
UIBehaviourExtensions.InvokeMethodAndRethrow<Selectable>(selectable, "OnPointerExit", data);
|
||||
}
|
||||
|
||||
public static void InvokeTriggerAnimation(this Selectable selectable, string triggerName)
|
||||
{
|
||||
UIBehaviourExtensions.InvokeMethodAndRethrow<Selectable>(selectable, "TriggerAnimation", triggerName);
|
||||
}
|
||||
|
||||
public static void InvokeOnSelect(this Selectable selectable, string triggerName)
|
||||
{
|
||||
UIBehaviourExtensions.InvokeMethodAndRethrow<Selectable>(selectable, "OnSelect", triggerName);
|
||||
}
|
||||
}
|
||||
|
||||
public static class GraphicExtension
|
||||
{
|
||||
public static void InvokeOnPopulateMesh(this Graphic graphic, VertexHelper vh)
|
||||
{
|
||||
UIBehaviourExtensions.InvokeMethodAndRethrow(graphic, "OnPopulateMesh", vh);
|
||||
}
|
||||
}
|
||||
|
||||
public static class GraphicRaycasterExtension
|
||||
{
|
||||
public static void InvokeRaycast(Canvas canvas, Camera eventCamera, Vector2 pointerPosition, List<Graphic> results)
|
||||
{
|
||||
UIBehaviourExtensions.InvokeMethodAndRethrow<GraphicRaycaster>(null, "Raycast", canvas, eventCamera, pointerPosition, results);
|
||||
}
|
||||
}
|
||||
|
||||
public static class ToggleGroupExtension
|
||||
{
|
||||
public static void InvokeValidateToggleIsInGroup(this ToggleGroup tgroup, Toggle toggle)
|
||||
{
|
||||
UIBehaviourExtensions.InvokeMethodAndRethrow<ToggleGroup>(tgroup, "ValidateToggleIsInGroup", toggle);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user