first commit
This commit is contained in:
@@ -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,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d56dbb97f857c8040beef6dd1bfc97df
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -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,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e9cac674d67385249b2805670e618c24
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -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,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7883cd788d83a71478342eef943e8150
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -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,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d925cabd9ecd5074aadab0726b96c38f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Reference in New Issue
Block a user