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