| OLD | NEW |
| (Empty) |
| 1 /* | |
| 2 * Copyright (C) 2011 Google Inc. All rights reserved. | |
| 3 * | |
| 4 * Redistribution and use in source and binary forms, with or without | |
| 5 * modification, are permitted provided that the following conditions | |
| 6 * are met: | |
| 7 * 1. Redistributions of source code must retain the above copyright | |
| 8 * notice, this list of conditions and the following disclaimer. | |
| 9 * 2. Redistributions in binary form must reproduce the above copyright | |
| 10 * notice, this list of conditions and the following disclaimer in the | |
| 11 * documentation and/or other materials provided with the distribution. | |
| 12 * | |
| 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' | |
| 14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | |
| 15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
| 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS | |
| 17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
| 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
| 19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
| 20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
| 21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
| 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF | |
| 23 * THE POSSIBILITY OF SUCH DAMAGE. | |
| 24 */ | |
| 25 | |
| 26 (function () { | |
| 27 | |
| 28 module("base"); | |
| 29 | |
| 30 test("bind", 3, function() { | |
| 31 function func(a, b) { | |
| 32 equals(this.prop, 5); | |
| 33 equals(a, "banana"); | |
| 34 deepEqual(b, [2, 3, 4]); | |
| 35 } | |
| 36 | |
| 37 var thisObject = { | |
| 38 "prop": 5 | |
| 39 }; | |
| 40 | |
| 41 var bound = func.bind(thisObject, "banana"); | |
| 42 bound([2, 3, 4]); | |
| 43 }); | |
| 44 | |
| 45 | |
| 46 test("joinPath", 1, function() { | |
| 47 var value = base.joinPath("path/to", "test.html"); | |
| 48 equals(value, "path/to/test.html"); | |
| 49 }); | |
| 50 | |
| 51 test("endsWith", 9, function() { | |
| 52 ok(base.endsWith("xyz", "")); | |
| 53 ok(base.endsWith("xyz", "z")); | |
| 54 ok(base.endsWith("xyz", "yz")); | |
| 55 ok(base.endsWith("xyz", "xyz")); | |
| 56 ok(!base.endsWith("xyz", "wxyz")); | |
| 57 ok(!base.endsWith("xyz", "gwxyz")); | |
| 58 ok(base.endsWith("", "")); | |
| 59 ok(!base.endsWith("", "z")); | |
| 60 ok(!base.endsWith("xyxy", "yx")); | |
| 61 }); | |
| 62 | |
| 63 test("trimExtension", 6, function() { | |
| 64 equals(base.trimExtension("xyz"), "xyz"); | |
| 65 equals(base.trimExtension("xy.z"), "xy"); | |
| 66 equals(base.trimExtension("x.yz"), "x"); | |
| 67 equals(base.trimExtension("x.y.z"), "x.y"); | |
| 68 equals(base.trimExtension(".xyz"), ""); | |
| 69 equals(base.trimExtension(""), ""); | |
| 70 }); | |
| 71 | |
| 72 test("joinPath with empty parent", 1, function() { | |
| 73 var value = base.joinPath("", "test.html"); | |
| 74 equals(value, "test.html"); | |
| 75 }); | |
| 76 | |
| 77 test("dirName", 3, function() { | |
| 78 equals(base.dirName("foo.html"), "foo.html"); | |
| 79 equals(base.dirName("foo/bar.html"), "foo"); | |
| 80 equals(base.dirName("foo/bar/baz.html"), "foo/bar"); | |
| 81 }); | |
| 82 | |
| 83 test("uniquifyArray", 5, function() { | |
| 84 deepEqual(base.uniquifyArray([]), []); | |
| 85 deepEqual(base.uniquifyArray(["a"]), ["a"]); | |
| 86 deepEqual(base.uniquifyArray(["a", "b"]), ["a", "b"]); | |
| 87 deepEqual(base.uniquifyArray(["a", "b", "b"]), ["a", "b"]); | |
| 88 deepEqual(base.uniquifyArray(["a", "b", "b", "a"]), ["a", "b"]); | |
| 89 }); | |
| 90 | |
| 91 test("flattenArray", 5, function() { | |
| 92 deepEqual(base.flattenArray([]), []); | |
| 93 deepEqual(base.flattenArray([["a"]]), ["a"]); | |
| 94 deepEqual(base.flattenArray([["a"], ["b"]]), ["a", "b"]); | |
| 95 deepEqual(base.flattenArray([["a"], ["b", "c"]]), ["a", "b", "c"]); | |
| 96 deepEqual(base.flattenArray([["a"], [], ["b"]]), ["a", "b"]); | |
| 97 }); | |
| 98 | |
| 99 test("callInParallel", 4, function() { | |
| 100 var expectedCall = [true, true, true]; | |
| 101 var expectCompletionCallback = true; | |
| 102 | |
| 103 base.callInParallel([ | |
| 104 function(callback) { | |
| 105 ok(expectedCall[0]); | |
| 106 expectedCall[0] = false; | |
| 107 callback(); | |
| 108 }, | |
| 109 function(callback) { | |
| 110 ok(expectedCall[1]); | |
| 111 expectedCall[1] = false; | |
| 112 callback(); | |
| 113 }, | |
| 114 function(callback) { | |
| 115 ok(expectedCall[2]); | |
| 116 expectedCall[2] = false; | |
| 117 callback(); | |
| 118 }, | |
| 119 ], function() { | |
| 120 ok(expectCompletionCallback); | |
| 121 expectCompletionCallback = false; | |
| 122 }) | |
| 123 }); | |
| 124 | |
| 125 test("callInSequence", 7, function() { | |
| 126 var expectedArg = 42; | |
| 127 var expectCompletionCallback = true; | |
| 128 | |
| 129 base.callInSequence(function(arg, callback) { | |
| 130 ok(arg < 45); | |
| 131 equals(arg, expectedArg++); | |
| 132 callback(); | |
| 133 }, [42, 43, 44], function() { | |
| 134 ok(expectCompletionCallback); | |
| 135 expectCompletionCallback = false; | |
| 136 }) | |
| 137 }); | |
| 138 | |
| 139 test("RequestTracker", 5, function() { | |
| 140 var ready = false; | |
| 141 var tracker = new base.RequestTracker(1, function() { | |
| 142 ok(ready); | |
| 143 }); | |
| 144 ready = true; | |
| 145 tracker.requestComplete(); | |
| 146 ready = false; | |
| 147 | |
| 148 tracker = new base.RequestTracker(2, function(parameter) { | |
| 149 ok(ready); | |
| 150 equals(parameter, 'argument'); | |
| 151 }, ['argument']); | |
| 152 tracker.requestComplete(); | |
| 153 ready = true; | |
| 154 tracker.requestComplete(); | |
| 155 ready = false; | |
| 156 | |
| 157 tracker = new base.RequestTracker(0, function() { | |
| 158 ok(true); | |
| 159 }); | |
| 160 tracker.requestComplete(); | |
| 161 | |
| 162 tracker = new base.RequestTracker(0); | |
| 163 tracker.requestComplete(); | |
| 164 // Should not barf. | |
| 165 ok(true); | |
| 166 }); | |
| 167 | |
| 168 test("CallbackIterator", 22, function() { | |
| 169 var expected = 0; | |
| 170 var iterator = new base.CallbackIterator(function(a, b) { | |
| 171 equals(a, 'ArgA' + expected); | |
| 172 equals(b, 'ArgB' + expected); | |
| 173 ++expected; | |
| 174 }, [ | |
| 175 ['ArgA0', 'ArgB0'], | |
| 176 ['ArgA1', 'ArgB1'], | |
| 177 ['ArgA2', 'ArgB2'], | |
| 178 ]); | |
| 179 ok(iterator.hasNext()) | |
| 180 ok(!iterator.hasPrevious()) | |
| 181 iterator.callNext(); | |
| 182 ok(iterator.hasNext()) | |
| 183 ok(!iterator.hasPrevious()) | |
| 184 iterator.callNext(); | |
| 185 ok(iterator.hasNext()) | |
| 186 ok(iterator.hasPrevious()) | |
| 187 iterator.callNext(); | |
| 188 ok(!iterator.hasNext()) | |
| 189 ok(iterator.hasPrevious()) | |
| 190 expected = 1; | |
| 191 iterator.callPrevious(); | |
| 192 ok(iterator.hasNext()) | |
| 193 ok(iterator.hasPrevious()) | |
| 194 expected = 0; | |
| 195 iterator.callPrevious(); | |
| 196 ok(iterator.hasNext()) | |
| 197 ok(!iterator.hasPrevious()) | |
| 198 }); | |
| 199 | |
| 200 test("filterDictionary", 3, function() { | |
| 201 var dictionary = { | |
| 202 'foo': 43, | |
| 203 'bar': 11 | |
| 204 }; | |
| 205 deepEqual(base.filterDictionary(dictionary, function() { return true; }), { | |
| 206 "foo": 43, | |
| 207 "bar": 11 | |
| 208 }); | |
| 209 deepEqual(base.filterDictionary(dictionary, function() { return false; }), {
}); | |
| 210 deepEqual(base.filterDictionary(dictionary, function(key) { return key == 'f
oo'; }), { | |
| 211 "foo": 43 | |
| 212 }); | |
| 213 }); | |
| 214 | |
| 215 test("mapDictionary", 3, function() { | |
| 216 deepEqual(base.mapDictionary({}, function(value) { return value - 10; }), {}
); | |
| 217 var dictionary = { | |
| 218 'foo': 43, | |
| 219 'bar': 11 | |
| 220 }; | |
| 221 deepEqual(base.mapDictionary(dictionary, function(value) { return value - 10
; }), { | |
| 222 "foo": 33, | |
| 223 "bar": 1 | |
| 224 }); | |
| 225 deepEqual(base.mapDictionary(dictionary, function(value) { | |
| 226 if (value > 20) | |
| 227 return value - 20; | |
| 228 }), { | |
| 229 "foo": 23, | |
| 230 }); | |
| 231 }); | |
| 232 | |
| 233 test("filterTree", 2, function() { | |
| 234 var tree = { | |
| 235 'path': { | |
| 236 'to': { | |
| 237 'test.html': { | |
| 238 'actual': 'PASS', | |
| 239 'expected': 'FAIL' | |
| 240 } | |
| 241 }, | |
| 242 'another.html': { | |
| 243 'actual': 'TEXT', | |
| 244 'expected': 'PASS' | |
| 245 } | |
| 246 } | |
| 247 } | |
| 248 | |
| 249 function isLeaf(node) | |
| 250 { | |
| 251 return !!node.actual; | |
| 252 } | |
| 253 | |
| 254 function actualIsText(node) | |
| 255 { | |
| 256 return node.actual == 'TEXT'; | |
| 257 } | |
| 258 | |
| 259 var all = base.filterTree(tree, isLeaf, function() { return true }); | |
| 260 deepEqual(all, { | |
| 261 'path/to/test.html': { | |
| 262 'actual': 'PASS', | |
| 263 'expected': 'FAIL' | |
| 264 }, | |
| 265 'path/another.html': { | |
| 266 'actual': 'TEXT', | |
| 267 'expected': 'PASS' | |
| 268 } | |
| 269 }); | |
| 270 | |
| 271 var text = base.filterTree(tree, isLeaf, actualIsText); | |
| 272 deepEqual(text, { | |
| 273 'path/another.html': { | |
| 274 'actual': 'TEXT', | |
| 275 'expected': 'PASS' | |
| 276 } | |
| 277 }); | |
| 278 }); | |
| 279 | |
| 280 test("UpdateTracker", 20, function() { | |
| 281 var dict; | |
| 282 | |
| 283 function dumpKeys() | |
| 284 { | |
| 285 var updates = [] | |
| 286 dict.forEach(function(item, key, updated) { | |
| 287 updates.push(key); | |
| 288 }); | |
| 289 return updates; | |
| 290 } | |
| 291 | |
| 292 function dumpUpdatedKeys() | |
| 293 { | |
| 294 var updates = [] | |
| 295 dict.forEach(function(item, key, updated) { | |
| 296 updated && updates.push(key); | |
| 297 }); | |
| 298 return updates; | |
| 299 } | |
| 300 | |
| 301 | |
| 302 dict = new base.UpdateTracker(); | |
| 303 dict.update("5", {}); | |
| 304 deepEqual(dumpUpdatedKeys(), ["5"]); | |
| 305 dict.update("6", {}); | |
| 306 dict.update("7", {}); | |
| 307 deepEqual(dumpUpdatedKeys(), ["5", "6", "7"]); | |
| 308 deepEqual(dict.get("6"), {}); | |
| 309 ok(dict.exists("7")); | |
| 310 dict.purge(); | |
| 311 deepEqual(dumpUpdatedKeys(), []); | |
| 312 deepEqual(dumpKeys(), ["5", "6", "7"]); | |
| 313 dict.update("5", {}); | |
| 314 deepEqual(dumpUpdatedKeys(), ["5"]); | |
| 315 dict.update("4", {}); | |
| 316 deepEqual(dumpUpdatedKeys(), ["4", "5"]); | |
| 317 deepEqual(dumpKeys(), ["4", "5", "6", "7"]); | |
| 318 dict.purge(); | |
| 319 deepEqual(dumpKeys(), ["4", "5"]); | |
| 320 deepEqual(dumpUpdatedKeys(), []); | |
| 321 dict.purge(); | |
| 322 deepEqual(dumpKeys(), []); | |
| 323 | |
| 324 var removeCount = 0; | |
| 325 dict.update("one"); | |
| 326 deepEqual(dumpUpdatedKeys(), ["one"]); | |
| 327 dict.update("two"); | |
| 328 deepEqual(dumpUpdatedKeys(), ["one", "two"]); | |
| 329 dict.update("three"); | |
| 330 dict.purge(); | |
| 331 deepEqual(dumpKeys(), ["one", "three", "two"]); | |
| 332 dict.update("two"); | |
| 333 dict.purge(function() { | |
| 334 removeCount++; | |
| 335 }); | |
| 336 deepEqual(dumpKeys(), ["two"]); | |
| 337 equal(removeCount, 2); | |
| 338 dict.update("four"); | |
| 339 var removeCounter = { count: 0 }; | |
| 340 dict.purge(function() { | |
| 341 this.count++; | |
| 342 }, removeCounter); | |
| 343 equal(removeCounter.count, 1); | |
| 344 dict.purge(function() { | |
| 345 equal(String(this), "four"); | |
| 346 }); | |
| 347 | |
| 348 dict = new base.UpdateTracker(); | |
| 349 dict.update("one"); | |
| 350 var thisObject = {} | |
| 351 dict.forEach(function(item) { | |
| 352 equal(this, thisObject); | |
| 353 }, thisObject); | |
| 354 | |
| 355 }); | |
| 356 | |
| 357 test("extends", 14, function() { | |
| 358 | |
| 359 var LikeDiv = base.extends("div", { | |
| 360 init: function() { | |
| 361 this.textContent = "awesome"; | |
| 362 }, | |
| 363 method: function(msg) { | |
| 364 return 42; | |
| 365 } | |
| 366 }); | |
| 367 | |
| 368 var LikeLikeDiv = base.extends(LikeDiv, { | |
| 369 init: function() { | |
| 370 this.className = "like"; | |
| 371 } | |
| 372 }); | |
| 373 | |
| 374 var LikeP = base.extends("p", { | |
| 375 init: function(content) { | |
| 376 this.textContent = content | |
| 377 } | |
| 378 }); | |
| 379 | |
| 380 var LikeProgress = base.extends("progress", { | |
| 381 init: function() { | |
| 382 this.max = 100; | |
| 383 this.value = 10; | |
| 384 } | |
| 385 }); | |
| 386 | |
| 387 var LikeLikeProgress = base.extends(LikeProgress, { | |
| 388 completed: function() { | |
| 389 this.value = 100; | |
| 390 } | |
| 391 }); | |
| 392 | |
| 393 document.body.appendChild(new LikeDiv()); | |
| 394 equals(document.body.lastChild.tagName, "DIV"); | |
| 395 equals(document.body.lastChild.innerHTML, "awesome"); | |
| 396 equals(document.body.lastChild.method(), 42); | |
| 397 document.body.removeChild(document.body.lastChild); | |
| 398 | |
| 399 document.body.appendChild(new LikeLikeDiv()); | |
| 400 equals(document.body.lastChild.tagName, "DIV"); | |
| 401 equals(document.body.lastChild.innerHTML, "awesome"); | |
| 402 equals(document.body.lastChild.method(), 42); | |
| 403 equals(document.body.lastChild.className, "like"); | |
| 404 document.body.removeChild(document.body.lastChild); | |
| 405 | |
| 406 document.body.appendChild(new LikeP("super")); | |
| 407 equals(document.body.lastChild.tagName, "P"); | |
| 408 equals(document.body.lastChild.innerHTML, "super"); | |
| 409 raises(function() { | |
| 410 document.body.lastChild.method(); | |
| 411 }); | |
| 412 document.body.removeChild(document.body.lastChild); | |
| 413 | |
| 414 document.body.appendChild(new LikeProgress()); | |
| 415 equals(document.body.lastChild.tagName, "PROGRESS"); | |
| 416 // Safari 5.1 lacks the <progress> element. | |
| 417 // equals(document.body.lastChild.position, 0.1); | |
| 418 equals(document.body.lastChild.innerHTML, ""); | |
| 419 raises(function() { | |
| 420 document.body.lastChild.method(); | |
| 421 }); | |
| 422 document.body.removeChild(document.body.lastChild); | |
| 423 | |
| 424 document.body.appendChild(new LikeLikeProgress()); | |
| 425 equals(document.body.lastChild.tagName, "PROGRESS"); | |
| 426 // Safari 5.1 lacks the <progress> element. | |
| 427 // equals(document.body.lastChild.position, 0.1); | |
| 428 document.body.lastChild.completed(); | |
| 429 // Safari 5.1 lacks the <progress> element. | |
| 430 // equals(document.body.lastChild.position, 1); | |
| 431 document.body.removeChild(document.body.lastChild); | |
| 432 }); | |
| 433 | |
| 434 test("relativizeTime", 14, function() { | |
| 435 var time = new Date(); | |
| 436 equals(base.relativizeTime(time), "Just now"); | |
| 437 time.setMinutes(time.getMinutes() - 1); | |
| 438 equals(base.relativizeTime(time), "1 minute ago"); | |
| 439 time.setMinutes(time.getMinutes() - 1); | |
| 440 equals(base.relativizeTime(time), "2 minutes ago"); | |
| 441 time.setMinutes(time.getMinutes() - 1); | |
| 442 equals(base.relativizeTime(time), "3 minutes ago"); | |
| 443 time.setMinutes(time.getMinutes() - 56); | |
| 444 equals(base.relativizeTime(time), "59 minutes ago"); | |
| 445 time.setMinutes(time.getMinutes() - 1); | |
| 446 equals(base.relativizeTime(time), "1 hour ago"); | |
| 447 time.setMinutes(time.getMinutes() - 29); | |
| 448 equals(base.relativizeTime(time), "1 hour ago"); | |
| 449 time.setMinutes(time.getMinutes() - 2); | |
| 450 equals(base.relativizeTime(time), "2 hours ago"); | |
| 451 time.setMinutes(time.getMinutes() - 29); | |
| 452 equals(base.relativizeTime(time), "2 hours ago"); | |
| 453 time.setHours(time.getHours() - 1); | |
| 454 equals(base.relativizeTime(time), "3 hours ago"); | |
| 455 time.setHours(time.getHours() - 20); | |
| 456 equals(base.relativizeTime(time), "23 hours ago"); | |
| 457 time.setHours(time.getHours() - 1); | |
| 458 equals(base.relativizeTime(time), "1 day ago"); | |
| 459 time.setDate(time.getDate() - 1); | |
| 460 equals(base.relativizeTime(time), "2 days ago"); | |
| 461 time.setDate(time.getDate() - 998); | |
| 462 equals(base.relativizeTime(time), "1000 days ago"); | |
| 463 }); | |
| 464 | |
| 465 test("getURLParameter", 1, function() { | |
| 466 ok(!base.getURLParameter('non-existant')); | |
| 467 }); | |
| 468 | |
| 469 test("parseJSONP", 2, function() { | |
| 470 deepEqual(base.parseJSONP(""), {}); | |
| 471 deepEqual(base.parseJSONP('p({"key": "value"})'), {"key": "value"}); | |
| 472 }); | |
| 473 | |
| 474 })(); | |
| OLD | NEW |