A game about forced loneliness, made by TACStudios
at master 498 lines 20 kB view raw
1using System.Reflection; 2using System.Collections; 3using NUnit.Framework; 4using UnityEngine.EventSystems; 5using UnityEngine.TestTools; 6 7namespace UnityEngine.UI.Tests 8{ 9 [TestFixture] 10 class SelectableTests 11 { 12 private class SelectableTest : Selectable 13 { 14 public bool isStateNormal { get { return currentSelectionState == SelectionState.Normal; } } 15 public bool isStateHighlighted { get { return currentSelectionState == SelectionState.Highlighted; } } 16 public bool isStateSelected { get { return currentSelectionState == SelectionState.Selected; } } 17 public bool isStatePressed { get { return currentSelectionState == SelectionState.Pressed; } } 18 public bool isStateDisabled { get { return currentSelectionState == SelectionState.Disabled; } } 19 20 public Selectable GetSelectableAtIndex(int index) 21 { 22 return s_Selectables[index]; 23 } 24 25 public int GetSelectableCurrentIndex() 26 { 27 return m_CurrentIndex; 28 } 29 } 30 31 private SelectableTest selectable; 32 private GameObject m_CanvasRoot; 33 private GameObject m_EventSystemGO; 34 35 private CanvasGroup CreateAndParentGroupTo(string name, GameObject child) 36 { 37 GameObject canvasRoot = new GameObject("Canvas", typeof(RectTransform), typeof(Canvas)); 38 GameObject groupGO = new GameObject(name, typeof(RectTransform), typeof(CanvasGroup)); 39 groupGO.transform.SetParent(canvasRoot.transform); 40 child.transform.SetParent(groupGO.transform); 41 return groupGO.GetComponent<CanvasGroup>(); 42 } 43 44 [SetUp] 45 public void TestSetup() 46 { 47 m_EventSystemGO = new GameObject("EventSystem", typeof(EventSystem)); 48 EventSystem.current = m_EventSystemGO.GetComponent<EventSystem>(); 49 m_CanvasRoot = new GameObject("Canvas", typeof(RectTransform), typeof(Canvas)); 50 GameObject SelectableGO = new GameObject("Selectable", typeof(RectTransform), typeof(CanvasRenderer)); 51 52 SelectableGO.transform.SetParent(m_CanvasRoot.transform); 53 selectable = SelectableGO.AddComponent<SelectableTest>(); 54 selectable.targetGraphic = selectable.gameObject.AddComponent<ConcreteGraphic>(); 55 } 56 57 [TearDown] 58 public void TearDown() 59 { 60 GameObject.DestroyImmediate(m_CanvasRoot); 61 GameObject.DestroyImmediate(m_EventSystemGO); 62 } 63 64 [Test] // regression test 1160054 65 public void SelectableArrayRemovesReferenceUponDisable() 66 { 67 int originalSelectableCount = Selectable.allSelectableCount; 68 69 selectable.enabled = false; 70 71 Assert.AreEqual(originalSelectableCount - 1, Selectable.allSelectableCount, "We have more then originalSelectableCount - 1 selectable objects."); 72 //ensure the item as the last index is nulled out as it replaced the item that was disabled. 73 Assert.IsNull(selectable.GetSelectableAtIndex(Selectable.allSelectableCount)); 74 75 selectable.enabled = true; 76 } 77 78 #region Selected object 79 80 [Test] 81 public void SettingCurrentSelectedSelectableNonInteractableShouldNullifyCurrentSelected() 82 { 83 EventSystem.current.SetSelectedGameObject(selectable.gameObject); 84 selectable.interactable = false; 85 86 // it should be unselected now that it is not interactable anymore 87 Assert.IsNull(EventSystem.current.currentSelectedGameObject); 88 } 89 90 [Test] 91 public void PointerEnterDownShouldMakeItSelectedGameObject() 92 { 93 Assert.IsNull(EventSystem.current.currentSelectedGameObject); 94 selectable.InvokeOnPointerEnter(new PointerEventData(EventSystem.current)); 95 selectable.InvokeOnPointerDown(new PointerEventData(EventSystem.current)); 96 Assert.AreEqual(selectable.gameObject, EventSystem.current.currentSelectedGameObject); 97 } 98 99 [Test] 100 public void OnSelectShouldSetSelectedState() 101 { 102 Assert.True(selectable.isStateNormal); 103 selectable.OnSelect(new BaseEventData(EventSystem.current)); 104 Assert.True(selectable.isStateSelected); 105 } 106 107 [Test] 108 public void OnDeselectShouldUnsetSelectedState() 109 { 110 Assert.True(selectable.isStateNormal); 111 selectable.OnSelect(new BaseEventData(EventSystem.current)); 112 Assert.True(selectable.isStateSelected); 113 selectable.OnDeselect(new BaseEventData(EventSystem.current)); 114 Assert.True(selectable.isStateNormal); 115 } 116 117 #endregion 118 119 #region Interactable 120 121 [Test] 122 public void SettingCanvasGroupNotInteractableShouldMakeSelectableNotInteractable() 123 { 124 // Canvas Group on same object 125 var group = selectable.gameObject.AddComponent<CanvasGroup>(); 126 Assert.IsTrue(selectable.IsInteractable()); 127 128 group.interactable = false; 129 // actual call happens on the native side, cause by interactable = false 130 selectable.InvokeOnCanvasGroupChanged(); 131 132 Assert.IsFalse(selectable.IsInteractable()); 133 } 134 135 [Test] 136 public void DisablingCanvasGroupShouldMakeSelectableAsInteractable() 137 { 138 var group = selectable.gameObject.AddComponent<CanvasGroup>(); 139 Assert.IsTrue(selectable.IsInteractable()); 140 141 group.enabled = false; 142 group.interactable = false; 143 144 selectable.InvokeOnCanvasGroupChanged(); 145 Assert.IsTrue(selectable.IsInteractable()); 146 } 147 148 [Test] 149 public void SettingParentCanvasGroupNotInteractableShouldMakeSelectableNotInteractable() 150 { 151 var canvasGroup = CreateAndParentGroupTo("CanvasGroup", selectable.gameObject); 152 Assert.IsTrue(selectable.IsInteractable()); 153 154 canvasGroup.interactable = false; 155 // actual call happens on the native side, cause by interactable = false 156 selectable.InvokeOnCanvasGroupChanged(); 157 158 Assert.IsFalse(selectable.IsInteractable()); 159 } 160 161 [Test] 162 public void SettingParentParentCanvasGroupNotInteractableShouldMakeSelectableNotInteractable() 163 { 164 var canvasGroup1 = CreateAndParentGroupTo("CanvasGroup1", selectable.gameObject); 165 var canvasGroup2 = CreateAndParentGroupTo("CanvasGroup2", canvasGroup1.gameObject); 166 Assert.IsTrue(selectable.IsInteractable()); 167 168 canvasGroup2.interactable = false; 169 // actual call happens on the native side, cause by interactable = false 170 selectable.InvokeOnCanvasGroupChanged(); 171 172 Assert.IsFalse(selectable.IsInteractable()); 173 } 174 175 [Test] 176 public void SettingParentParentCanvasGroupInteractableShouldMakeSelectableInteractable() 177 { 178 var canvasGroup1 = CreateAndParentGroupTo("CanvasGroup1", selectable.gameObject); 179 CreateAndParentGroupTo("CanvasGroup2", canvasGroup1.gameObject); 180 Assert.IsTrue(selectable.IsInteractable()); 181 182 // actual call happens on the native side, cause by interactable 183 selectable.InvokeOnCanvasGroupChanged(); 184 185 Assert.IsTrue(selectable.IsInteractable()); 186 } 187 188 [Test] 189 public void SettingParentParentCanvasGroupNotInteractableShouldNotMakeSelectableNotInteractableIfIgnoreParentGroups() 190 { 191 var canvasGroup1 = CreateAndParentGroupTo("CanvasGroup1", selectable.gameObject); 192 canvasGroup1.ignoreParentGroups = true; 193 var canvasGroup2 = CreateAndParentGroupTo("CanvasGroup2", canvasGroup1.gameObject); 194 Assert.IsTrue(selectable.IsInteractable()); 195 196 canvasGroup2.interactable = false; 197 // actual call happens on the native side, cause by interactable = false 198 selectable.InvokeOnCanvasGroupChanged(); 199 200 Assert.IsTrue(selectable.IsInteractable()); 201 } 202 203 [Test]// regression test 861736 204 public void PointerEnterThenSetNotInteractableThenExitThenSetInteractableShouldSetStateToDefault() 205 { 206 Assert.True(selectable.isStateNormal); 207 selectable.InvokeOnPointerEnter(new PointerEventData(EventSystem.current) 208 { 209 pointerEnter = selectable.gameObject 210 }); 211 Assert.True(selectable.isStateHighlighted); 212 selectable.interactable = false; 213 selectable.InvokeOnPointerExit(new PointerEventData(EventSystem.current) 214 { 215 pointerEnter = selectable.gameObject 216 }); 217 selectable.interactable = true; 218 Assert.False(selectable.isStateHighlighted); 219 Assert.True(selectable.isStateNormal); 220 } 221 222 [Test]// regression test 861736 223 public void PointerEnterThenSetNotInteractableThenSetInteractableShouldStayHighlighted() 224 { 225 Assert.True(selectable.isStateNormal); 226 selectable.InvokeOnPointerEnter(new PointerEventData(EventSystem.current) 227 { 228 pointerEnter = selectable.gameObject 229 }); 230 Assert.True(selectable.isStateHighlighted); 231 selectable.interactable = false; 232 selectable.interactable = true; 233 Assert.True(selectable.isStateHighlighted); 234 } 235 236 [Test] 237 public void InstantiatingSelectableUnderNotInteractableCanvasGroupShouldAlsoNotBeInteractable() 238 { 239 var canvasGroup = CreateAndParentGroupTo("ParentGroup", selectable.gameObject); 240 canvasGroup.interactable = false; 241 Assert.False(canvasGroup.interactable); 242 var newSelectable = Object.Instantiate(selectable.gameObject, canvasGroup.transform).GetComponent<SelectableTest>(); 243 Assert.False(newSelectable.IsInteractable()); 244 } 245 246 #endregion 247 248 #region Tweening 249 250 [UnityTest] 251 public IEnumerator SettingNotInteractableShouldTweenToDisabledColor() 252 { 253 var canvasRenderer = selectable.gameObject.GetComponent<CanvasRenderer>(); 254 selectable.InvokeOnEnable(); 255 canvasRenderer.SetColor(selectable.colors.normalColor); 256 257 selectable.interactable = false; 258 259 yield return new WaitForSeconds(1); 260 261 Assert.AreEqual(selectable.colors.disabledColor, canvasRenderer.GetColor()); 262 263 selectable.interactable = true; 264 265 yield return new WaitForSeconds(1); 266 267 Assert.AreEqual(selectable.colors.normalColor, canvasRenderer.GetColor()); 268 } 269 270 [UnityTest][Ignore("Fails")] // regression test 742140 271 public IEnumerator SettingNotInteractableThenInteractableShouldNotTweenToDisabledColor() 272 { 273 var canvasRenderer = selectable.gameObject.GetComponent<CanvasRenderer>(); 274 selectable.enabled = false; 275 selectable.enabled = true; 276 canvasRenderer.SetColor(selectable.colors.normalColor); 277 278 selectable.interactable = false; 279 selectable.interactable = true; 280 Color c = canvasRenderer.GetColor(); 281 282 for (int i = 0; i < 30; i++) 283 { 284 yield return null; 285 Color c2 = canvasRenderer.GetColor(); 286 Assert.AreNotEqual(c2, c); 287 } 288 Assert.AreEqual(selectable.colors.normalColor, canvasRenderer.GetColor()); 289 } 290 291 [UnityTest] 292 public IEnumerator SettingInteractableToFalseTrueFalseShouldTweenToDisabledColor() 293 { 294 var canvasRenderer = selectable.gameObject.GetComponent<CanvasRenderer>(); 295 selectable.InvokeOnEnable(); 296 canvasRenderer.SetColor(selectable.colors.normalColor); 297 298 selectable.interactable = false; 299 selectable.interactable = true; 300 selectable.interactable = false; 301 302 yield return new WaitForSeconds(1); 303 304 Assert.AreEqual(selectable.colors.disabledColor, canvasRenderer.GetColor()); 305 } 306 307#if PACKAGE_ANIMATION 308 [Test] 309 public void TriggerAnimationWithNoAnimator() 310 { 311 Assert.Null(selectable.animator); 312 Assert.DoesNotThrow(() => selectable.InvokeTriggerAnimation("asdasd")); 313 } 314 315 [Test] 316 public void TriggerAnimationWithDisabledAnimator() 317 { 318 var an = selectable.gameObject.AddComponent<Animator>(); 319 an.enabled = false; 320 Assert.NotNull(selectable.animator); 321 Assert.DoesNotThrow(() => selectable.InvokeTriggerAnimation("asdasd")); 322 } 323 324 [Test] 325 public void TriggerAnimationAnimatorWithNoRuntimeController() 326 { 327 var an = selectable.gameObject.AddComponent<Animator>(); 328 an.runtimeAnimatorController = null; 329 Assert.NotNull(selectable.animator); 330 Assert.DoesNotThrow(() => selectable.InvokeTriggerAnimation("asdasd")); 331 } 332 333#endif 334 #endregion 335 336 #region Selection state and pointer 337 338 [Test] 339 public void SelectShouldSetSelectedObject() 340 { 341 Assert.Null(EventSystem.current.currentSelectedGameObject); 342 selectable.Select(); 343 Assert.AreEqual(selectable.gameObject, EventSystem.current.currentSelectedGameObject); 344 } 345 346 [Test] 347 public void SelectWhenAlreadySelectingShouldNotSetSelectedObject() 348 { 349 Assert.Null(EventSystem.current.currentSelectedGameObject); 350 var fieldInfo = typeof(EventSystem).GetField("m_SelectionGuard", BindingFlags.NonPublic | BindingFlags.Instance); 351 fieldInfo 352 .SetValue(EventSystem.current, true); 353 selectable.Select(); 354 Assert.Null(EventSystem.current.currentSelectedGameObject); 355 } 356 357 [Test] 358 public void PointerEnterShouldHighlight() 359 { 360 Assert.True(selectable.isStateNormal); 361 selectable.InvokeOnPointerEnter(new PointerEventData(EventSystem.current) 362 { 363 pointerEnter = selectable.gameObject 364 }); 365 Assert.True(selectable.isStateHighlighted); 366 } 367 368 [Test] 369 public void PointerEnterOnSelectedObjectShouldStaySelected() 370 { 371 selectable.InvokeOnSelect(null); 372 Assert.True(selectable.isStateSelected); 373 selectable.InvokeOnPointerEnter(new PointerEventData(EventSystem.current) 374 { 375 pointerEnter = selectable.gameObject 376 }); 377 Assert.True(selectable.isStateSelected); 378 } 379 380 [Test] 381 public void PointerEnterAndRightClickShouldHighlightNotPress() 382 { 383 Assert.True(selectable.isStateNormal); 384 selectable.InvokeOnPointerEnter(new PointerEventData(EventSystem.current) 385 { 386 pointerEnter = selectable.gameObject 387 }); 388 selectable.InvokeOnPointerDown(new PointerEventData(EventSystem.current) 389 { 390 button = PointerEventData.InputButton.Right 391 }); 392 Assert.True(selectable.isStateHighlighted); 393 } 394 395 [Test] 396 public void PointerEnterAndRightClickShouldPress() 397 { 398 Assert.True(selectable.isStateNormal); 399 selectable.InvokeOnPointerEnter(new PointerEventData(EventSystem.current) 400 { 401 pointerEnter = selectable.gameObject 402 }); 403 selectable.InvokeOnPointerDown(new PointerEventData(EventSystem.current)); 404 Assert.True(selectable.isStatePressed); 405 } 406 407 [Test] 408 public void PointerEnterLeftClickExitShouldPress() 409 { 410 Assert.True(selectable.isStateNormal); 411 selectable.InvokeOnPointerEnter(new PointerEventData(EventSystem.current) 412 { 413 pointerEnter = selectable.gameObject 414 }); 415 selectable.InvokeOnPointerDown(new PointerEventData(EventSystem.current)); 416 selectable.InvokeOnPointerExit(new PointerEventData(EventSystem.current) 417 { 418 pointerEnter = selectable.gameObject 419 }); 420 Assert.True(selectable.isStatePressed); 421 } 422 423 [Test] 424 public void PointerEnterLeftClickExitReleaseShouldSelect() 425 { 426 Assert.True(selectable.isStateNormal); 427 selectable.InvokeOnPointerEnter(new PointerEventData(EventSystem.current) 428 { 429 pointerEnter = selectable.gameObject 430 }); 431 selectable.InvokeOnPointerDown(new PointerEventData(EventSystem.current)); 432 selectable.InvokeOnPointerExit(new PointerEventData(EventSystem.current) 433 { 434 pointerEnter = selectable.gameObject 435 }); 436 selectable.InvokeOnPointerUp(new PointerEventData(EventSystem.current)); 437 Assert.True(selectable.isStateSelected); 438 } 439 440 [Test] 441 public void PointerDownShouldSetSelectedObject() 442 { 443 Assert.Null(EventSystem.current.currentSelectedGameObject); 444 selectable.InvokeOnPointerDown(new PointerEventData(EventSystem.current)); 445 Assert.AreEqual(selectable.gameObject, EventSystem.current.currentSelectedGameObject); 446 } 447 448 [Test] 449 public void PointerLeftDownRightDownRightUpShouldNotChangeState() 450 { 451 Assert.True(selectable.isStateNormal); 452 selectable.InvokeOnPointerEnter(new PointerEventData(EventSystem.current) 453 { 454 pointerEnter = selectable.gameObject 455 }); 456 selectable.InvokeOnPointerDown(new PointerEventData(EventSystem.current) { button = PointerEventData.InputButton.Left }); 457 selectable.InvokeOnPointerDown(new PointerEventData(EventSystem.current) { button = PointerEventData.InputButton.Right }); 458 selectable.InvokeOnPointerUp(new PointerEventData(EventSystem.current) { button = PointerEventData.InputButton.Right }); 459 Assert.True(selectable.isStatePressed); 460 } 461 462 [Test, Ignore("No disabled state assigned ? Investigate")] 463 public void SettingNotInteractableShouldDisable() 464 { 465 Assert.True(selectable.isStateNormal); 466 selectable.interactable = false; 467 selectable.InvokeOnCanvasGroupChanged(); 468 Assert.True(selectable.isStateDisabled); 469 } 470 471 #endregion 472 473 #region No event system 474 475 [Test] // regression test 787563 476 public void SettingInteractableWithNoEventSystemShouldNotCrash() 477 { 478 EventSystem.current.enabled = false; 479 selectable.interactable = false; 480 } 481 482 [Test] // regression test 787563 483 public void OnPointerDownWithNoEventSystemShouldNotCrash() 484 { 485 EventSystem.current.enabled = false; 486 selectable.OnPointerDown(new PointerEventData(EventSystem.current) {button = PointerEventData.InputButton.Left}); 487 } 488 489 [Test] // regression test 787563 490 public void SelectWithNoEventSystemShouldNotCrash() 491 { 492 EventSystem.current.enabled = false; 493 selectable.Select(); 494 } 495 496 #endregion 497 } 498}