A game about forced loneliness, made by TACStudios
1using System.Collections;
2using NUnit.Framework;
3using UnityEngine;
4using UnityEngine.EventSystems;
5using UnityEngine.TestTools;
6using UnityEngine.UI;
7
8[UnityPlatform()]
9public class InputModuleTests
10{
11 EventSystem m_EventSystem;
12 FakeBaseInput m_FakeBaseInput;
13 StandaloneInputModule m_StandaloneInputModule;
14 Canvas m_Canvas;
15 Image m_Image;
16 Image m_NestedImage;
17
18 [SetUp]
19 public void TestSetup()
20 {
21 // Camera | Canvas (Image) | Event System
22
23 m_Canvas = new GameObject("Canvas").AddComponent<Canvas>();
24 m_Canvas.renderMode = RenderMode.ScreenSpaceOverlay;
25 m_Canvas.gameObject.AddComponent<GraphicRaycaster>();
26
27 m_Image = new GameObject("Image").AddComponent<Image>();
28 m_Image.gameObject.transform.SetParent(m_Canvas.transform);
29 RectTransform imageRectTransform = m_Image.GetComponent<RectTransform>();
30 imageRectTransform.sizeDelta = new Vector2(400f, 400f);
31 imageRectTransform.localPosition = Vector3.zero;
32
33 m_NestedImage = new GameObject("NestedImage").AddComponent<Image>();
34 m_NestedImage.gameObject.transform.SetParent(m_Image.transform);
35 RectTransform nestedImageRectTransform = m_NestedImage.GetComponent<RectTransform>();
36 nestedImageRectTransform.sizeDelta = new Vector2(200f, 200f);
37 nestedImageRectTransform.localPosition = Vector3.zero;
38
39 GameObject go = new GameObject("Event System");
40 m_EventSystem = go.AddComponent<EventSystem>();
41 m_EventSystem.pixelDragThreshold = 1;
42
43 m_StandaloneInputModule = go.AddComponent<StandaloneInputModule>();
44 m_FakeBaseInput = go.AddComponent<FakeBaseInput>();
45
46 // Override input with FakeBaseInput so we can send fake mouse/keyboards button presses and touches
47 m_StandaloneInputModule.inputOverride = m_FakeBaseInput;
48
49 Cursor.lockState = CursorLockMode.None;
50 }
51
52 [UnityTest]
53 public IEnumerator DragCallbacksDoGetCalled()
54 {
55 // While left mouse button is pressed and the mouse is moving, OnBeginDrag and OnDrag callbacks should be called
56 // Then when the left mouse button is released, OnEndDrag callback should be called
57
58 // Add script to EventSystem to update the mouse position
59 m_EventSystem.gameObject.AddComponent<MouseUpdate>();
60
61 // Add script to Image which implements OnBeginDrag, OnDrag & OnEndDrag callbacks
62 DragCallbackCheck callbackCheck = m_Image.gameObject.AddComponent<DragCallbackCheck>();
63
64 // Setting required input.mousePresent to fake mouse presence
65 m_FakeBaseInput.MousePresent = true;
66
67 var canvasRT = m_Canvas.gameObject.transform as RectTransform;
68 m_FakeBaseInput.MousePosition = new Vector2(Screen.width / 2, Screen.height / 2);
69
70 yield return null;
71
72 // Left mouse button down simulation
73 m_FakeBaseInput.MouseButtonDown[0] = true;
74
75 yield return null;
76
77 // Left mouse button down flag needs to reset in the next frame
78 m_FakeBaseInput.MouseButtonDown[0] = false;
79
80 yield return null;
81
82 // Left mouse button up simulation
83 m_FakeBaseInput.MouseButtonUp[0] = true;
84
85 yield return null;
86
87 // Left mouse button up flag needs to reset in the next frame
88 m_FakeBaseInput.MouseButtonUp[0] = false;
89
90 yield return null;
91
92 Assert.IsTrue(callbackCheck.onBeginDragCalled, "OnBeginDrag not called");
93 Assert.IsTrue(callbackCheck.onDragCalled, "OnDragCalled not called");
94 Assert.IsTrue(callbackCheck.onEndDragCalled, "OnEndDragCalled not called");
95 Assert.IsTrue(callbackCheck.onDropCalled, "OnDrop not called");
96 }
97
98 [UnityTest]
99 public IEnumerator MouseOutsideMaskRectTransform_WhileInsidePaddedArea_PerformsClick()
100 {
101 var mask = new GameObject("Panel").AddComponent<RectMask2D>();
102 mask.gameObject.transform.SetParent(m_Canvas.transform);
103 RectTransform panelRectTransform = mask.GetComponent<RectTransform>();
104 panelRectTransform.sizeDelta = new Vector2(100, 100f);
105 panelRectTransform.localPosition = Vector3.zero;
106
107 m_Image.gameObject.transform.SetParent(mask.transform, true);
108 mask.padding = new Vector4(-30, -30, -30, -30);
109
110
111 PointerClickCallbackCheck callbackCheck = m_Image.gameObject.AddComponent<PointerClickCallbackCheck>();
112
113 var canvasRT = m_Canvas.gameObject.transform as RectTransform;
114 var screenMiddle = new Vector2(Screen.width / 2, Screen.height / 2);
115 m_FakeBaseInput.MousePresent = true;
116 m_FakeBaseInput.MousePosition = screenMiddle;
117
118 yield return null;
119 // Click the center of the screen should hit the middle of the image.
120 m_FakeBaseInput.MouseButtonDown[0] = true;
121 yield return null;
122 m_FakeBaseInput.MouseButtonDown[0] = false;
123 yield return null;
124 m_FakeBaseInput.MouseButtonUp[0] = true;
125 yield return null;
126 m_FakeBaseInput.MouseButtonUp[0] = false;
127 yield return null;
128 Assert.IsTrue(callbackCheck.pointerDown);
129
130 //Reset the callbackcheck and click outside the mask but still in the image.
131 callbackCheck.pointerDown = false;
132 m_FakeBaseInput.MousePosition = new Vector2(screenMiddle.x - 60, screenMiddle.y);
133 yield return null;
134 m_FakeBaseInput.MouseButtonDown[0] = true;
135 yield return null;
136 m_FakeBaseInput.MouseButtonDown[0] = false;
137 yield return null;
138 m_FakeBaseInput.MouseButtonUp[0] = true;
139 yield return null;
140 m_FakeBaseInput.MouseButtonUp[0] = false;
141 yield return null;
142 Assert.IsTrue(callbackCheck.pointerDown);
143
144 //Reset the callbackcheck and click outside the mask and outside in the image.
145 callbackCheck.pointerDown = false;
146 m_FakeBaseInput.MousePosition = new Vector2(screenMiddle.x - 100, screenMiddle.y);
147 yield return null;
148 m_FakeBaseInput.MouseButtonDown[0] = true;
149 yield return null;
150 m_FakeBaseInput.MouseButtonDown[0] = false;
151 yield return null;
152 m_FakeBaseInput.MouseButtonUp[0] = true;
153 yield return null;
154 m_FakeBaseInput.MouseButtonUp[0] = false;
155 yield return null;
156 Assert.IsFalse(callbackCheck.pointerDown);
157 }
158
159 [UnityTest]
160 public IEnumerator PointerEnterChildShouldNotFullyExit_NotSendPointerEventToParent()
161 {
162 m_StandaloneInputModule.sendPointerHoverToParent = false;
163 PointerExitCallbackCheck callbackCheck = m_Image.gameObject.AddComponent<PointerExitCallbackCheck>();
164 m_NestedImage.gameObject.AddComponent<PointerExitCallbackCheck>();
165 var screenMiddle = new Vector2(Screen.width / 2, Screen.height / 2);
166
167 m_FakeBaseInput.MousePresent = true;
168 m_FakeBaseInput.MousePosition = screenMiddle - new Vector2(150, 150);
169 yield return null;
170 m_FakeBaseInput.MousePosition = screenMiddle;
171 yield return null;
172 Assert.IsTrue(callbackCheck.pointerData.fullyExited == false);
173 }
174
175 [UnityTest]
176 public IEnumerator PointerEnterChildShouldNotExit_SendPointerEventToParent()
177 {
178 m_StandaloneInputModule.sendPointerHoverToParent = true;
179 PointerExitCallbackCheck callbackCheck = m_Image.gameObject.AddComponent<PointerExitCallbackCheck>();
180 m_NestedImage.gameObject.AddComponent<PointerExitCallbackCheck>();
181 var screenMiddle = new Vector2(Screen.width / 2, Screen.height / 2);
182
183 m_FakeBaseInput.MousePresent = true;
184 m_FakeBaseInput.MousePosition = screenMiddle - new Vector2(150, 150);
185 yield return null;
186 m_FakeBaseInput.MousePosition = screenMiddle;
187 yield return null;
188 Assert.IsTrue(callbackCheck.pointerData == null);
189 }
190
191 [UnityTest]
192 public IEnumerator PointerEnterChildShouldNotReenter()
193 {
194 PointerEnterCallbackCheck callbackCheck = m_NestedImage.gameObject.AddComponent<PointerEnterCallbackCheck>();
195 var screenMiddle = new Vector2(Screen.width / 2, Screen.height / 2);
196
197 m_FakeBaseInput.MousePresent = true;
198 m_FakeBaseInput.MousePosition = screenMiddle - new Vector2(150, 150);
199 yield return null;
200 m_FakeBaseInput.MousePosition = screenMiddle;
201 yield return null;
202 Assert.IsTrue(callbackCheck.pointerData.reentered == false);
203 }
204
205 [UnityTest]
206 public IEnumerator PointerExitChildShouldReenter_NotSendPointerEventToParent()
207 {
208 m_StandaloneInputModule.sendPointerHoverToParent = false;
209 PointerEnterCallbackCheck callbackCheck = m_Image.gameObject.AddComponent<PointerEnterCallbackCheck>();
210 var screenMiddle = new Vector2(Screen.width / 2, Screen.height / 2);
211
212 m_FakeBaseInput.MousePresent = true;
213 m_FakeBaseInput.MousePosition = screenMiddle - new Vector2(150, 150);
214 yield return null;
215 m_FakeBaseInput.MousePosition = screenMiddle;
216 yield return null;
217 m_FakeBaseInput.MousePosition = screenMiddle - new Vector2(150, 150);
218 yield return null;
219 Assert.IsTrue(callbackCheck.pointerData.reentered == true);
220 }
221
222 [UnityTest]
223 public IEnumerator PointerExitChildShouldNotSendEnter_SendPointerEventToParent()
224 {
225 m_StandaloneInputModule.sendPointerHoverToParent = true;
226 m_NestedImage.gameObject.AddComponent<PointerEnterCallbackCheck>();
227 var screenMiddle = new Vector2(Screen.width / 2, Screen.height / 2);
228
229 m_FakeBaseInput.MousePresent = true;
230 m_FakeBaseInput.MousePosition = screenMiddle;
231 yield return null;
232 PointerEnterCallbackCheck callbackCheck = m_Image.gameObject.AddComponent<PointerEnterCallbackCheck>();
233 m_FakeBaseInput.MousePosition = screenMiddle - new Vector2(150, 150);
234 yield return null;
235 Assert.IsTrue(callbackCheck.pointerData == null);
236 }
237
238 [UnityTest]
239 public IEnumerator PointerExitChildShouldFullyExit()
240 {
241 PointerExitCallbackCheck callbackCheck = m_NestedImage.gameObject.AddComponent<PointerExitCallbackCheck>();
242 var screenMiddle = new Vector2(Screen.width / 2, Screen.height / 2);
243
244 m_FakeBaseInput.MousePresent = true;
245 m_FakeBaseInput.MousePosition = screenMiddle - new Vector2(150, 150);
246 yield return null;
247 m_FakeBaseInput.MousePosition = screenMiddle;
248 yield return null;
249 m_FakeBaseInput.MousePosition = screenMiddle - new Vector2(150, 150);
250 yield return null;
251 Assert.IsTrue(callbackCheck.pointerData.fullyExited == true);
252 }
253
254 [TearDown]
255 public void TearDown()
256 {
257 GameObject.DestroyImmediate(m_EventSystem.gameObject);
258 GameObject.DestroyImmediate(m_Canvas.gameObject);
259 }
260}