| OLD | NEW | 
|---|
| 1 /* | 1 /* | 
| 2  * This file is part of Adblock Plus <http://adblockplus.org/>, | 2  * This file is part of Adblock Plus <http://adblockplus.org/>, | 
| 3  * Copyright (C) 2006-2014 Eyeo GmbH | 3  * Copyright (C) 2006-2014 Eyeo GmbH | 
| 4  * | 4  * | 
| 5  * Adblock Plus is free software: you can redistribute it and/or modify | 5  * Adblock Plus is free software: you can redistribute it and/or modify | 
| 6  * it under the terms of the GNU General Public License version 3 as | 6  * it under the terms of the GNU General Public License version 3 as | 
| 7  * published by the Free Software Foundation. | 7  * published by the Free Software Foundation. | 
| 8  * | 8  * | 
| 9  * Adblock Plus is distributed in the hope that it will be useful, | 9  * Adblock Plus is distributed in the hope that it will be useful, | 
| 10  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
| (...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 390     let type5 = type1.extend({}, { | 390     let type5 = type1.extend({}, { | 
| 391       destructor: function(super_) | 391       destructor: function(super_) | 
| 392       { | 392       { | 
| 393         this.retain(); | 393         this.retain(); | 
| 394         this.release(); | 394         this.release(); | 
| 395       } | 395       } | 
| 396     }); | 396     }); | 
| 397     type5(0).release(); | 397     type5(0).release(); | 
| 398     ok(true, "Temporarily retaining reference in destructor is allowed"); | 398     ok(true, "Temporarily retaining reference in destructor is allowed"); | 
| 399   }); | 399   }); | 
|  | 400 | 
|  | 401   test("Property watchers", function() | 
|  | 402   { | 
|  | 403     let {ObjectType, uint8, int32} = require("typedObjects"); | 
|  | 404 | 
|  | 405     let watched  = null; | 
|  | 406     let type1 = new ObjectType({ | 
|  | 407       foo: uint8, | 
|  | 408       bar: int32 | 
|  | 409     }, { | 
|  | 410       constructor: function(foo, bar) | 
|  | 411       { | 
|  | 412         this.foo = foo; | 
|  | 413         this.bar = bar; | 
|  | 414       }, | 
|  | 415 | 
|  | 416       watch: { | 
|  | 417         foo: function(value) | 
|  | 418         { | 
|  | 419           watched = [this, "foo", this.foo, value]; | 
|  | 420           return value + 1; | 
|  | 421         }, | 
|  | 422         bar: function(value) | 
|  | 423         { | 
|  | 424           watched = [this, "bar", this.bar, value]; | 
|  | 425           return value + 2; | 
|  | 426         } | 
|  | 427       } | 
|  | 428     }); | 
|  | 429 | 
|  | 430     let obj1 = type1(1, 2); | 
|  | 431 | 
|  | 432     obj1.foo = 5; | 
|  | 433     deepEqual(watched, [obj1, "foo", 2, 5], "Watcher called for first property")
     ; | 
|  | 434     equal(obj1.foo, 6, "Value returned by the watcher applied"); | 
|  | 435 | 
|  | 436     obj1.bar += 4; | 
|  | 437     deepEqual(watched, [obj1, "bar", 4, 8], "Watcher called for second property"
     ); | 
|  | 438     equal(obj1.bar, 10, "Value returned by the watcher applied"); | 
|  | 439 | 
|  | 440     let type2 = type1.extend({}, { | 
|  | 441       watch: { | 
|  | 442         bar: function(value) | 
|  | 443         { | 
|  | 444           watched = [this, "barOverridden", this.bar, value]; | 
|  | 445           return value; | 
|  | 446         } | 
|  | 447       } | 
|  | 448     }); | 
|  | 449 | 
|  | 450     let obj2 = type2(3, 4); | 
|  | 451 | 
|  | 452     obj2.foo = 8; | 
|  | 453     deepEqual(watched, [obj2, "foo", 4, 8], "Watchers are inherited"); | 
|  | 454     equal(obj2.foo, 9, "Value returned by the watcher applied"); | 
|  | 455 | 
|  | 456     obj2.bar = 10; | 
|  | 457     deepEqual(watched, [obj2, "barOverridden", 4, 10], "Watchers can be overridd
     en"); | 
|  | 458     equal(obj2.bar, 10, "Value returned by the watcher applied"); | 
|  | 459   }); | 
|  | 460 | 
|  | 461   test("Arrays of primitive types", function() | 
|  | 462   { | 
|  | 463     let {ObjectType, uint32} = require("typedObjects"); | 
|  | 464 | 
|  | 465     let arrayDestroyed = false; | 
|  | 466     let uint32Array = uint32.Array({ | 
|  | 467       customProp: uint32, | 
|  | 468       setCustomProp: function(customProp) | 
|  | 469       { | 
|  | 470         this.customProp = customProp; | 
|  | 471       } | 
|  | 472     }, { | 
|  | 473       constructor: function(length) | 
|  | 474       { | 
|  | 475         this.length = length; | 
|  | 476       }, | 
|  | 477       destructor: function() | 
|  | 478       { | 
|  | 479         arrayDestroyed = true; | 
|  | 480       } | 
|  | 481     }); | 
|  | 482     ok(uint32Array, "Array type created"); | 
|  | 483 | 
|  | 484     let array1 = uint32Array(3); | 
|  | 485     ok(array1, "Array created"); | 
|  | 486     equal(array1.length, 3, "Constructor set length to 3"); | 
|  | 487     equal(array1.size, 4, "Array size was set accordingly"); | 
|  | 488 | 
|  | 489     // Custom properties/methods | 
|  | 490     equal(typeof array1.customProp, "number", "Custom array property created"); | 
|  | 491     equal(typeof array1.setCustomProp, "function", "Custom array method created"
     ); | 
|  | 492 | 
|  | 493     array1.setCustomProp(12); | 
|  | 494     equal(array1.customProp, 12, "Method could set custom property"); | 
|  | 495 | 
|  | 496     // Setting/reading array elements | 
|  | 497     for (var i = 0; i < 3; i++) | 
|  | 498       array1.set(i, i * 2); | 
|  | 499     for (var i = 0; i < 3; i++) | 
|  | 500       equal(array1.get(i), i * 2, "Array element value persisted"); | 
|  | 501 | 
|  | 502     // Array length changes | 
|  | 503     array1.length = 5; | 
|  | 504     equal(array1.length, 5, "Length increased to 5"); | 
|  | 505     equal(array1.size, 8, "Array size adjusted accordingly"); | 
|  | 506     for (var i = 0; i < 3; i++) | 
|  | 507       equal(array1.get(i), i * 2, "Array element value survived length increase"
     ); | 
|  | 508 | 
|  | 509     array1.length = 2; | 
|  | 510     equal(array1.length, 2, "Length reduced to 2"); | 
|  | 511     equal(array1.size, 8, "Array size unchanged after length reduction"); | 
|  | 512     for (var i = 0; i < 2; i++) | 
|  | 513       equal(array1.get(i), i * 2, "Value of remaining elements survived length d
     ecrease"); | 
|  | 514 | 
|  | 515     // Out of bounds read/writes | 
|  | 516     throws(() => array1.get(-1), "Getting with negative element index throws"); | 
|  | 517     throws(() => array1.get(2), "Getting with too large element index throws"); | 
|  | 518     throws(() => array1.set(-1, 12), "Setting with negative element index throws
     "); | 
|  | 519     throws(() => array1.set(2, 12), "Setting with too large element index throws
     "); | 
|  | 520 | 
|  | 521     // Using array as a property type | 
|  | 522     let type1 = ObjectType({ | 
|  | 523       foo: uint32Array | 
|  | 524     }); | 
|  | 525     let obj1 = type1(); | 
|  | 526     obj1.foo = array1; | 
|  | 527     ok(array1.equals(obj1.foo), "Array assigned to object property correctly"); | 
|  | 528 | 
|  | 529     ok(!arrayDestroyed, "Array not destroyed at this point"); | 
|  | 530     array1.release(); | 
|  | 531     ok(!arrayDestroyed, "Array not destroyed after releasing if referenced in an
      object"); | 
|  | 532 | 
|  | 533     obj1.release(); | 
|  | 534     ok(arrayDestroyed, "Array destroyed after releasing object holding a referen
     ce to it"); | 
|  | 535   }); | 
|  | 536 | 
|  | 537   test("Arrays of objects", function() | 
|  | 538   { | 
|  | 539     let {ObjectType, uint8} = require("typedObjects"); | 
|  | 540 | 
|  | 541     let destroyed = []; | 
|  | 542     let arrayDestroyed = false; | 
|  | 543     let type1 = ObjectType({ | 
|  | 544       foo: uint8 | 
|  | 545     }, { | 
|  | 546       constructor: function(foo) | 
|  | 547       { | 
|  | 548         this.foo = foo; | 
|  | 549       }, | 
|  | 550       destructor: function() | 
|  | 551       { | 
|  | 552         destroyed.push(this.foo); | 
|  | 553       } | 
|  | 554     }); | 
|  | 555 | 
|  | 556     let type1Array = type1.Array(null, { | 
|  | 557       destructor: function() | 
|  | 558       { | 
|  | 559         arrayDestroyed = true; | 
|  | 560       } | 
|  | 561     }); | 
|  | 562     ok(type1Array, "Array type created"); | 
|  | 563 | 
|  | 564     let array1 = type1Array(); | 
|  | 565     ok(array1, "Array created"); | 
|  | 566 | 
|  | 567     equal(array1.length, 0, "Default array length"); | 
|  | 568     equal(array1.size, 0, "Default array size"); | 
|  | 569 | 
|  | 570     throws(() => array1.get(0), "Getting element of empty array throws"); | 
|  | 571     throws(() => array1.set(0, null), "Setting element of empty array throws"); | 
|  | 572 | 
|  | 573     array1.length = 1; | 
|  | 574     equal(array1.length, 1, "Array length set to 1"); | 
|  | 575     equal(array1.size, 1, "Array size adjusted accordingly"); | 
|  | 576 | 
|  | 577     let obj1 = type1(1); | 
|  | 578     array1.set(0, obj1); | 
|  | 579     obj1.release(); | 
|  | 580 | 
|  | 581     ok(obj1.equals(array1.get(0)), "Array element persisted"); | 
|  | 582     throws(() => array1.get(-1), "Getting with negative element index throws"); | 
|  | 583     throws(() => array1.get(1), "Getting with too large element index throws"); | 
|  | 584     throws(() => array1.set(-1, null), "Setting with negative element index thro
     ws"); | 
|  | 585     throws(() => array1.set(1, null), "Setting with too large element index thro
     ws"); | 
|  | 586 | 
|  | 587     array1.length = 3; | 
|  | 588     equal(array1.length, 3, "Array length set to 3"); | 
|  | 589     equal(array1.size, 4, "Array size adjusted accordingly"); | 
|  | 590 | 
|  | 591     ok(obj1.equals(array1.get(0)), "Array element survived resizing"); | 
|  | 592     equal(array1.get(1), null, "Uninitialized array element is null"); | 
|  | 593     equal(array1.get(2), null, "Uninitialized array element is null"); | 
|  | 594 | 
|  | 595     let obj2 = type1(2); | 
|  | 596     array1.set(2, obj2); | 
|  | 597     obj2.release(); | 
|  | 598 | 
|  | 599     ok(obj1.equals(array1.get(0)), "Array element unchanged after setting anothe
     r element"); | 
|  | 600     equal(array1.get(1), null, "Uninitialized array element is null"); | 
|  | 601     ok(obj2.equals(array1.get(2)), "Array element persisted"); | 
|  | 602 | 
|  | 603     deepEqual(destroyed, [], "No objects destroyed at this point"); | 
|  | 604 | 
|  | 605     array1.set(0, null); | 
|  | 606     deepEqual(destroyed, [1], "Object destroyed after being unset in array"); | 
|  | 607 | 
|  | 608     array1.set(1, array1.get(2)); | 
|  | 609     array1.set(2, null); | 
|  | 610     deepEqual(destroyed, [1], "Object not destroyed after being unset in array i
     f still set on another element"); | 
|  | 611 | 
|  | 612     array1.length = 1; | 
|  | 613     equal(array1.length, 1, "Array length reduced"); | 
|  | 614     equal(array1.size, 4, "Array size unchanged after length reduction"); | 
|  | 615     deepEqual(destroyed, [1, 2], "Object destroyed after removed implicitly by r
     educing length"); | 
|  | 616 | 
|  | 617     ok(!arrayDestroyed, "Array not destroyed at this point"); | 
|  | 618     array1.release(); | 
|  | 619     ok(arrayDestroyed, "Array destroyed after releasing"); | 
|  | 620   }); | 
|  | 621 | 
|  | 622   test("Array memory allocation", function() | 
|  | 623   { | 
|  | 624     let {uint32} = require("typedObjects"); | 
|  | 625 | 
|  | 626     let uint32Array = uint32.Array(null, { | 
|  | 627       arrayBufferSize: 8, | 
|  | 628       constructor: function(length) | 
|  | 629       { | 
|  | 630         this.length = length; | 
|  | 631       } | 
|  | 632     }); | 
|  | 633 | 
|  | 634     let array1 = uint32Array(0); | 
|  | 635     equal(array1.arrayBufferIndex, -1, "No buffer allocated for zero-size arrays
     "); | 
|  | 636 | 
|  | 637     array1.length = 3; | 
|  | 638     equal(array1.arrayBufferIndex, 0, "First array allocated in first buffer"); | 
|  | 639     equal(array1.arrayByteOffset, 0, "First array allocated at zero byte offset"
     ); | 
|  | 640 | 
|  | 641     let array2 = uint32Array(4); | 
|  | 642     equal(array2.arrayBufferIndex, 0, "Second array allocated in first buffer"); | 
|  | 643     equal(array2.arrayByteOffset, 16, "Second array allocated at next available 
     byte offset"); | 
|  | 644 | 
|  | 645     let array3 = uint32Array(4); | 
|  | 646     equal(array3.arrayBufferIndex, 1, "Third array allocated in new buffer"); | 
|  | 647     equal(array3.arrayByteOffset, 0, "Third array allocated at zero byte offset"
     ); | 
|  | 648 | 
|  | 649     let array4 = uint32Array(2); | 
|  | 650     equal(array4.arrayBufferIndex, 2, "Array with different size allocated in ne
     w buffer"); | 
|  | 651     equal(array4.arrayByteOffset, 0, "Array with different size allocated at zer
     o offset"); | 
|  | 652 | 
|  | 653     array2.release(); | 
|  | 654     array2 = uint32Array(3); | 
|  | 655     equal(array2.arrayBufferIndex, 0, "After releasing an array new array is all
     ocated in same buffer"); | 
|  | 656     equal(array2.arrayByteOffset, 16, "After releasing an array new array is all
     ocated at same byte offset"); | 
|  | 657 | 
|  | 658     array1.length = 0; | 
|  | 659     array1.size = 0; | 
|  | 660     equal(array1.arrayBufferIndex, -1, "Setting array size to zero releases its 
     buffer"); | 
|  | 661 | 
|  | 662     array4.length = 4; | 
|  | 663     equal(array4.arrayBufferIndex, 0, "Increasing array size moves it to a diffe
     rent buffer"); | 
|  | 664     equal(array4.arrayByteOffset, 0, "Increasing array size moves makes it reuse
      the spot from a released array buffer"); | 
|  | 665 | 
|  | 666     let array5 = uint32Array(9); | 
|  | 667     equal(array5.arrayBufferIndex, 3, "Large array gets its own buffer"); | 
|  | 668     equal(array5.arrayByteOffset, 0, "Large array is allocated at zero offset"); | 
|  | 669 | 
|  | 670     let array6 = uint32Array(9); | 
|  | 671     equal(array6.arrayBufferIndex, 4, "Second large array gets its own buffer"); | 
|  | 672     equal(array6.arrayByteOffset, 0, "Second large array is allocated at zero of
     fset"); | 
|  | 673 | 
|  | 674     array5.release(); | 
|  | 675     array5 = uint32Array(9); | 
|  | 676     equal(array5.arrayBufferIndex, 5, "Buffer indexes for large arrays aren't re
     used"); | 
|  | 677     equal(array5.arrayByteOffset, 0, "Large array is allocated at zero offset"); | 
|  | 678 | 
|  | 679     for (let array of [array1, array2, array3, array4, array5]) | 
|  | 680       array.release(); | 
|  | 681   }); | 
| 400 })(); | 682 })(); | 
| OLD | NEW | 
|---|