OLD | NEW |
---|---|
(Empty) | |
1 var pinchtest = (function() { | |
2 'use strict'; | |
3 | |
4 function assertTrue(condition, message) { | |
5 if (!condition) { | |
6 message = message || "Assertion failed"; | |
7 console.trace(); | |
8 throw new Error(message); | |
9 } | |
10 } | |
11 | |
12 function assertClose(a, b, message) { | |
13 if (Math.abs(a-b) > 1e-5) { | |
14 message = message || "Assertion failed"; | |
15 console.log('"', a, '" and "', b, '" are not close.'); | |
16 console.trace(); | |
17 throw new Error(message); | |
18 } | |
19 } | |
20 | |
21 function isEquivalent(a, b) { | |
22 // Create arrays of property names | |
23 var aProps = Object.getOwnPropertyNames(a); | |
24 var bProps = Object.getOwnPropertyNames(b); | |
25 | |
26 // If number of properties is different, | |
27 // objects are not equivalent | |
28 if (aProps.length != bProps.length) { | |
29 return false; | |
30 } | |
31 | |
32 for (var i = 0; i < aProps.length; i++) { | |
33 var propName = aProps[i]; | |
34 | |
35 // If values of same property are not equal, | |
36 // objects are not equivalent | |
37 if (a[propName] !== b[propName]) { | |
38 return false; | |
39 } | |
40 } | |
41 | |
42 // If we made it this far, objects | |
43 // are considered equivalent | |
44 return true; | |
45 } | |
46 | |
47 function assertEqual(a, b, message) { | |
48 if (!isEquivalent(a, b)) { | |
49 message = message || "Assertion failed"; | |
50 console.log('"', a, '" and "', b, '" are not equal'); | |
51 console.trace(); | |
52 throw new Error(message); | |
53 } | |
54 } | |
55 | |
56 var touch = (function() { | |
tdresser
2015/04/21 12:28:45
It might be worth factoring this out into a differ
wychen
2015/04/22 04:25:17
Acknowledged.
| |
57 'use strict'; | |
58 var points = {}; | |
59 function lowestID() { | |
60 var ans = -1; | |
61 for(var key in points) { | |
62 ans = Math.max(ans, key); | |
63 } | |
64 return ans + 1; | |
65 } | |
66 function changeTouchPoint (key, x, y, offsetX, offsetY) { | |
67 var e = { | |
68 clientX: x, | |
69 clientY: y, | |
70 pageX: x, | |
71 pageY: y | |
72 }; | |
73 if (typeof(offsetX) === 'number') { | |
74 e.clientX += offsetX; | |
75 } | |
76 if (typeof(offsetY) === 'number') { | |
77 e.clientY += offsetY; | |
78 } | |
79 points[key] = e; | |
80 } | |
81 return { | |
82 addTouchPoint: function(x, y, offsetX, offsetY) { | |
83 changeTouchPoint(lowestID(), x, y, offsetX, offsetY); | |
84 }, | |
85 updateTouchPoint: changeTouchPoint, | |
86 releaseTouchPoint: function(key) { | |
87 delete points[key]; | |
88 }, | |
89 events: function() { | |
90 var arr = []; | |
91 for(var key in points) { | |
92 arr.push(points[key]); | |
93 } | |
94 return { | |
95 touches: arr, | |
96 preventDefault: function(){} | |
97 }; | |
98 } | |
99 } | |
100 }); | |
101 | |
102 function testZoomOut() { | |
103 pincher.reset(); | |
104 var t = new touch(); | |
105 | |
106 // Make sure start event doesn't change state | |
107 var oldState = pincher.status(); | |
108 t.addTouchPoint(100, 100); | |
109 pincher.handleTouchStart(t.events()); | |
110 assertEqual(oldState, pincher.status()); | |
111 t.addTouchPoint(300, 300); | |
112 pincher.handleTouchStart(t.events()); | |
113 assertEqual(oldState, pincher.status()); | |
114 | |
115 // Make sure extra move event doesn't change state | |
116 pincher.handleTouchStart(t.events()); | |
tdresser
2015/04/21 12:28:45
I'm not clear on what's going on here.
The comment
wychen
2015/04/22 04:25:17
Good catch! It was a typo. Fixed!
| |
117 assertEqual(oldState, pincher.status()); | |
118 | |
119 t.updateTouchPoint(0, 150, 150); | |
120 t.updateTouchPoint(1, 250, 250); | |
121 pincher.handleTouchMove(t.events()); | |
122 assertTrue(pincher.status().clampedScale < 0.9); | |
123 | |
124 // Make sure end event doesn't change state | |
125 oldState = pincher.status(); | |
126 t.releaseTouchPoint(1); | |
127 pincher.handleTouchEnd(t.events()); | |
128 assertEqual(oldState, pincher.status()); | |
129 t.releaseTouchPoint(0); | |
130 pincher.handleTouchEnd(t.events()); | |
131 assertEqual(oldState, pincher.status()); | |
132 } | |
133 | |
134 function testZoomIn() { | |
135 pincher.reset(); | |
136 var t = new touch(); | |
137 | |
138 var oldState = pincher.status(); | |
139 t.addTouchPoint(150, 150); | |
140 pincher.handleTouchStart(t.events()); | |
141 assertEqual(oldState, pincher.status()); | |
142 t.addTouchPoint(250, 250); | |
143 pincher.handleTouchStart(t.events()); | |
144 assertEqual(oldState, pincher.status()); | |
145 | |
146 t.updateTouchPoint(0, 100, 100); | |
147 t.updateTouchPoint(1, 300, 300); | |
148 pincher.handleTouchMove(t.events()); | |
149 assertTrue(pincher.status().clampedScale > 1.1); | |
150 | |
151 oldState = pincher.status(); | |
152 t.releaseTouchPoint(1); | |
153 pincher.handleTouchEnd(t.events()); | |
154 assertEqual(oldState, pincher.status()); | |
155 t.releaseTouchPoint(0); | |
156 pincher.handleTouchEnd(t.events()); | |
157 assertEqual(oldState, pincher.status()); | |
158 } | |
159 | |
160 function testZoomOutAndPan() { | |
161 pincher.reset(); | |
162 var t = new touch(); | |
163 t.addTouchPoint(100, 100); | |
164 pincher.handleTouchStart(t.events()); | |
165 t.addTouchPoint(300, 300); | |
166 pincher.handleTouchStart(t.events()); | |
167 t.updateTouchPoint(0, 150, 150); | |
168 t.updateTouchPoint(1, 250, 250); | |
169 pincher.handleTouchMove(t.events()); | |
170 t.updateTouchPoint(0, 150, 150, 10, -5); | |
171 t.updateTouchPoint(1, 250, 250, 10, -5); | |
172 pincher.handleTouchMove(t.events()); | |
173 t.releaseTouchPoint(1); | |
174 pincher.handleTouchEnd(t.events()); | |
175 t.releaseTouchPoint(0); | |
176 pincher.handleTouchEnd(t.events()); | |
177 | |
178 assertClose(pincher.status().shiftX, 10); | |
179 assertClose(pincher.status().shiftY, -5); | |
180 assertTrue(pincher.status().clampedScale < 0.9); | |
181 } | |
182 | |
183 function testReversible() { | |
184 pincher.reset(); | |
185 var t = new touch(); | |
186 t.addTouchPoint(100, 100); | |
187 pincher.handleTouchStart(t.events()); | |
188 t.addTouchPoint(300, 300); | |
189 pincher.handleTouchStart(t.events()); | |
190 t.updateTouchPoint(0, 0, 0); | |
191 t.updateTouchPoint(1, 400, 400); | |
192 pincher.handleTouchMove(t.events()); | |
193 t.releaseTouchPoint(1); | |
194 pincher.handleTouchEnd(t.events()); | |
195 t.releaseTouchPoint(0); | |
196 pincher.handleTouchEnd(t.events()); | |
197 t.addTouchPoint(0, 0); | |
198 pincher.handleTouchStart(t.events()); | |
199 t.addTouchPoint(400, 400); | |
200 pincher.handleTouchStart(t.events()); | |
201 t.updateTouchPoint(0, 100, 100); | |
202 t.updateTouchPoint(1, 300, 300); | |
203 pincher.handleTouchMove(t.events()); | |
204 t.releaseTouchPoint(1); | |
205 pincher.handleTouchEnd(t.events()); | |
206 t.releaseTouchPoint(0); | |
207 pincher.handleTouchEnd(t.events()); | |
208 assertClose(pincher.status().clampedScale, 1); | |
209 } | |
210 | |
211 function testMultitouchZoomOut() { | |
212 pincher.reset(); | |
213 var t = new touch(); | |
214 | |
215 var oldState = pincher.status(); | |
216 t.addTouchPoint(100, 100); | |
217 pincher.handleTouchStart(t.events()); | |
218 assertEqual(oldState, pincher.status()); | |
219 t.addTouchPoint(300, 300); | |
220 pincher.handleTouchStart(t.events()); | |
221 assertEqual(oldState, pincher.status()); | |
222 t.addTouchPoint(100, 300); | |
223 pincher.handleTouchStart(t.events()); | |
224 assertEqual(oldState, pincher.status()); | |
225 t.addTouchPoint(300, 100); | |
226 pincher.handleTouchStart(t.events()); | |
227 assertEqual(oldState, pincher.status()); | |
228 | |
229 // Multi-touch zoom out. | |
230 t.updateTouchPoint(0, 150, 150); | |
231 t.updateTouchPoint(1, 250, 250); | |
232 t.updateTouchPoint(2, 150, 250); | |
233 t.updateTouchPoint(3, 250, 150); | |
234 pincher.handleTouchMove(t.events()); | |
235 | |
236 oldState = pincher.status(); | |
237 t.releaseTouchPoint(3); | |
238 pincher.handleTouchEnd(t.events()); | |
239 assertEqual(oldState, pincher.status()); | |
240 t.releaseTouchPoint(2); | |
241 pincher.handleTouchEnd(t.events()); | |
242 assertEqual(oldState, pincher.status()); | |
243 t.releaseTouchPoint(1); | |
244 pincher.handleTouchEnd(t.events()); | |
245 assertEqual(oldState, pincher.status()); | |
246 t.releaseTouchPoint(0); | |
247 pincher.handleTouchEnd(t.events()); | |
248 assertEqual(oldState, pincher.status()); | |
249 | |
250 assertTrue(pincher.status().clampedScale < 0.9); | |
251 } | |
252 | |
253 function testZoomOutThenMulti() { | |
254 pincher.reset(); | |
255 var t = new touch(); | |
256 | |
257 var oldState = pincher.status(); | |
258 t.addTouchPoint(100, 100); | |
259 pincher.handleTouchStart(t.events()); | |
260 assertEqual(oldState, pincher.status()); | |
261 t.addTouchPoint(300, 300); | |
262 pincher.handleTouchStart(t.events()); | |
263 assertEqual(oldState, pincher.status()); | |
264 | |
265 // Zoom out. | |
266 t.updateTouchPoint(0, 150, 150); | |
267 t.updateTouchPoint(1, 250, 250); | |
268 pincher.handleTouchMove(t.events()); | |
269 assertTrue(pincher.status().clampedScale < 0.9); | |
270 | |
271 // Make sure adding and removing more point doesn't change state | |
272 oldState = pincher.status(); | |
273 t.addTouchPoint(600, 600); | |
274 pincher.handleTouchStart(t.events()); | |
275 assertEqual(oldState, pincher.status()); | |
276 t.releaseTouchPoint(2); | |
277 pincher.handleTouchEnd(t.events()); | |
278 assertEqual(oldState, pincher.status()); | |
279 | |
280 // More than two fingers. | |
281 t.addTouchPoint(150, 250); | |
282 pincher.handleTouchStart(t.events()); | |
283 t.addTouchPoint(250, 150); | |
284 pincher.handleTouchStart(t.events()); | |
285 assertEqual(oldState, pincher.status()); | |
286 | |
287 t.updateTouchPoint(0, 100, 100); | |
288 t.updateTouchPoint(1, 300, 300); | |
289 t.updateTouchPoint(2, 100, 300); | |
290 t.updateTouchPoint(3, 300, 100); | |
291 pincher.handleTouchMove(t.events()); | |
292 assertClose(pincher.status().scale, 1); | |
293 | |
294 oldState = pincher.status(); | |
295 t.releaseTouchPoint(3); | |
296 t.releaseTouchPoint(2); | |
297 t.releaseTouchPoint(1); | |
298 t.releaseTouchPoint(0); | |
299 pincher.handleTouchEnd(t.events()); | |
300 assertEqual(oldState, pincher.status()); | |
301 } | |
302 | |
303 function testCancel() { | |
304 pincher.reset(); | |
305 var t = new touch(); | |
306 | |
307 t.addTouchPoint(100, 100); | |
308 pincher.handleTouchStart(t.events()); | |
309 t.addTouchPoint(300, 300); | |
310 pincher.handleTouchStart(t.events()); | |
311 t.updateTouchPoint(0, 150, 150); | |
312 t.updateTouchPoint(1, 250, 250); | |
313 pincher.handleTouchMove(t.events()); | |
314 assertTrue(pincher.status().clampedScale < 0.9); | |
315 | |
316 var oldState = pincher.status(); | |
317 t.releaseTouchPoint(1); | |
318 t.releaseTouchPoint(0); | |
319 pincher.handleTouchCancel(t.events()); | |
320 assertEqual(oldState, pincher.status()); | |
321 | |
322 t.addTouchPoint(150, 150); | |
323 pincher.handleTouchStart(t.events()); | |
324 t.addTouchPoint(250, 250); | |
325 pincher.handleTouchStart(t.events()); | |
326 t.updateTouchPoint(0, 100, 100); | |
327 t.updateTouchPoint(1, 300, 300); | |
328 pincher.handleTouchMove(t.events()); | |
329 assertClose(pincher.status().clampedScale, 1); | |
330 } | |
331 | |
332 function testSingularity() { | |
333 pincher.reset(); | |
334 var t = new touch(); | |
335 | |
336 t.addTouchPoint(100, 100); | |
337 pincher.handleTouchStart(t.events()); | |
338 t.addTouchPoint(100, 100); | |
339 pincher.handleTouchStart(t.events()); | |
340 t.updateTouchPoint(0, 150, 150); | |
341 t.updateTouchPoint(1, 50, 50); | |
342 pincher.handleTouchMove(t.events()); | |
343 assertTrue(pincher.status().clampedScale > 1.1); | |
344 assertTrue(pincher.status().clampedScale < 100); | |
345 assertTrue(pincher.status().scale < 100); | |
346 | |
347 pincher.handleTouchCancel(); | |
348 } | |
349 | |
350 function testMinSpan() { | |
351 pincher.reset(); | |
352 var t = new touch(); | |
353 | |
354 t.addTouchPoint(50, 50); | |
355 pincher.handleTouchStart(t.events()); | |
356 t.addTouchPoint(150, 150); | |
357 pincher.handleTouchStart(t.events()); | |
358 t.updateTouchPoint(0, 100, 100); | |
359 t.updateTouchPoint(1, 100, 100); | |
360 pincher.handleTouchMove(t.events()); | |
361 assertTrue(pincher.status().clampedScale < 0.9); | |
362 assertTrue(pincher.status().clampedScale > 0); | |
363 assertTrue(pincher.status().scale > 0); | |
364 | |
365 pincher.handleTouchCancel(); | |
366 } | |
367 | |
368 return { | |
369 run: function(){ | |
370 testZoomOut(); | |
371 testZoomIn(); | |
372 testZoomOutAndPan(); | |
373 testReversible(); | |
374 testMultitouchZoomOut(); | |
375 testZoomOutThenMulti(); | |
376 testCancel(); | |
377 testSingularity(); | |
378 testMinSpan(); | |
379 pincher.reset(); | |
380 | |
381 return {success: true}; | |
382 } | |
383 }; | |
384 }()); | |
OLD | NEW |