Home | History | Annotate | Download | only in es6
      1 // Copyright 2012 the V8 project authors. All rights reserved.
      2 // Redistribution and use in source and binary forms, with or without
      3 // modification, are permitted provided that the following conditions are
      4 // met:
      5 //
      6 //     * Redistributions of source code must retain the above copyright
      7 //       notice, this list of conditions and the following disclaimer.
      8 //     * Redistributions in binary form must reproduce the above
      9 //       copyright notice, this list of conditions and the following
     10 //       disclaimer in the documentation and/or other materials provided
     11 //       with the distribution.
     12 //     * Neither the name of Google Inc. nor the names of its
     13 //       contributors may be used to endorse or promote products derived
     14 //       from this software without specific prior written permission.
     15 //
     16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 
     28 // Flags: --expose-gc --allow-natives-syntax
     29 
     30 
     31 // Note: this test is superseded by harmony/collections.js.
     32 // IF YOU CHANGE THIS FILE, apply the same changes to harmony/collections.js!
     33 // TODO(rossberg): Remove once non-weak collections have caught up.
     34 
     35 // Test valid getter and setter calls on WeakSets.
     36 function TestValidSetCalls(m) {
     37   assertDoesNotThrow(function () { m.add(new Object) });
     38   assertDoesNotThrow(function () { m.has(new Object) });
     39   assertDoesNotThrow(function () { m.delete(new Object) });
     40 }
     41 TestValidSetCalls(new WeakSet);
     42 
     43 
     44 // Test valid getter and setter calls on WeakMaps
     45 function TestValidMapCalls(m) {
     46   assertDoesNotThrow(function () { m.get(new Object) });
     47   assertDoesNotThrow(function () { m.set(new Object) });
     48   assertDoesNotThrow(function () { m.has(new Object) });
     49   assertDoesNotThrow(function () { m.delete(new Object) });
     50 }
     51 TestValidMapCalls(new WeakMap);
     52 
     53 
     54 // Test invalid getter and setter calls for WeakMap
     55 function TestInvalidCalls(m) {
     56   assertThrows(function () { m.get(undefined) }, TypeError);
     57   assertThrows(function () { m.set(undefined, 0) }, TypeError);
     58   assertThrows(function () { m.get(null) }, TypeError);
     59   assertThrows(function () { m.set(null, 0) }, TypeError);
     60   assertThrows(function () { m.get(0) }, TypeError);
     61   assertThrows(function () { m.set(0, 0) }, TypeError);
     62   assertThrows(function () { m.get('a-key') }, TypeError);
     63   assertThrows(function () { m.set('a-key', 0) }, TypeError);
     64 }
     65 TestInvalidCalls(new WeakMap);
     66 
     67 
     68 // Test expected behavior for WeakSets
     69 function TestSet(set, key) {
     70   assertFalse(set.has(key));
     71   assertSame(undefined, set.add(key));
     72   assertTrue(set.has(key));
     73   assertTrue(set.delete(key));
     74   assertFalse(set.has(key));
     75   assertFalse(set.delete(key));
     76   assertFalse(set.has(key));
     77 }
     78 function TestSetBehavior(set) {
     79   for (var i = 0; i < 20; i++) {
     80     TestSet(set, new Object);
     81     TestSet(set, i);
     82     TestSet(set, i / 100);
     83     TestSet(set, 'key-' + i);
     84   }
     85   var keys = [ +0, -0, +Infinity, -Infinity, true, false, null, undefined ];
     86   for (var i = 0; i < keys.length; i++) {
     87     TestSet(set, keys[i]);
     88   }
     89 }
     90 TestSet(new WeakSet, new Object);
     91 
     92 
     93 // Test expected mapping behavior for WeakMaps
     94 function TestMapping(map, key, value) {
     95   assertSame(undefined, map.set(key, value));
     96   assertSame(value, map.get(key));
     97 }
     98 function TestMapBehavior1(m) {
     99   TestMapping(m, new Object, 23);
    100   TestMapping(m, new Object, 'the-value');
    101   TestMapping(m, new Object, new Object);
    102 }
    103 TestMapBehavior1(new WeakMap);
    104 
    105 
    106 // Test expected querying behavior of WeakMaps
    107 function TestQuery(m) {
    108   var key = new Object;
    109   var values = [ 'x', 0, +Infinity, -Infinity, true, false, null, undefined ];
    110   for (var i = 0; i < values.length; i++) {
    111     TestMapping(m, key, values[i]);
    112     assertTrue(m.has(key));
    113     assertFalse(m.has(new Object));
    114   }
    115 }
    116 TestQuery(new WeakMap);
    117 
    118 
    119 // Test expected deletion behavior of WeakMaps
    120 function TestDelete(m) {
    121   var key = new Object;
    122   TestMapping(m, key, 'to-be-deleted');
    123   assertTrue(m.delete(key));
    124   assertFalse(m.delete(key));
    125   assertFalse(m.delete(new Object));
    126   assertSame(m.get(key), undefined);
    127 }
    128 TestDelete(new WeakMap);
    129 
    130 
    131 // Test GC of WeakMaps with entry
    132 function TestGC1(m) {
    133   var key = new Object;
    134   m.set(key, 'not-collected');
    135   gc();
    136   assertSame('not-collected', m.get(key));
    137 }
    138 TestGC1(new WeakMap);
    139 
    140 
    141 // Test GC of WeakMaps with chained entries
    142 function TestGC2(m) {
    143   var head = new Object;
    144   for (key = head, i = 0; i < 10; i++, key = m.get(key)) {
    145     m.set(key, new Object);
    146   }
    147   gc();
    148   var count = 0;
    149   for (key = head; key != undefined; key = m.get(key)) {
    150     count++;
    151   }
    152   assertEquals(11, count);
    153 }
    154 TestGC2(new WeakMap);
    155 
    156 
    157 // Test property attribute [[Enumerable]]
    158 function TestEnumerable(func) {
    159   function props(x) {
    160     var array = [];
    161     for (var p in x) array.push(p);
    162     return array.sort();
    163   }
    164   assertArrayEquals([], props(func));
    165   assertArrayEquals([], props(func.prototype));
    166   assertArrayEquals([], props(new func()));
    167 }
    168 TestEnumerable(WeakMap);
    169 TestEnumerable(WeakSet);
    170 
    171 
    172 // Test arbitrary properties on WeakMaps
    173 function TestArbitrary(m) {
    174   function TestProperty(map, property, value) {
    175     map[property] = value;
    176     assertEquals(value, map[property]);
    177   }
    178   for (var i = 0; i < 20; i++) {
    179     TestProperty(m, i, 'val' + i);
    180     TestProperty(m, 'foo' + i, 'bar' + i);
    181   }
    182   TestMapping(m, new Object, 'foobar');
    183 }
    184 TestArbitrary(new WeakMap);
    185 
    186 
    187 // Test direct constructor call
    188 assertThrows(function() { WeakMap(); }, TypeError);
    189 assertThrows(function() { WeakSet(); }, TypeError);
    190 
    191 
    192 // Test some common JavaScript idioms for WeakMaps
    193 var m = new WeakMap;
    194 assertTrue(m instanceof WeakMap);
    195 assertTrue(WeakMap.prototype.set instanceof Function)
    196 assertTrue(WeakMap.prototype.get instanceof Function)
    197 assertTrue(WeakMap.prototype.has instanceof Function)
    198 assertTrue(WeakMap.prototype.delete instanceof Function)
    199 assertTrue(WeakMap.prototype.clear instanceof Function)
    200 
    201 
    202 // Test some common JavaScript idioms for WeakSets
    203 var s = new WeakSet;
    204 assertTrue(s instanceof WeakSet);
    205 assertTrue(WeakSet.prototype.add instanceof Function)
    206 assertTrue(WeakSet.prototype.has instanceof Function)
    207 assertTrue(WeakSet.prototype.delete instanceof Function)
    208 assertTrue(WeakSet.prototype.clear instanceof Function)
    209 
    210 
    211 // Test class of instance and prototype.
    212 assertEquals("WeakMap", %_ClassOf(new WeakMap))
    213 assertEquals("Object", %_ClassOf(WeakMap.prototype))
    214 assertEquals("WeakSet", %_ClassOf(new WeakSet))
    215 assertEquals("Object", %_ClassOf(WeakMap.prototype))
    216 
    217 
    218 // Test name of constructor.
    219 assertEquals("WeakMap", WeakMap.name);
    220 assertEquals("WeakSet", WeakSet.name);
    221 
    222 
    223 // Test prototype property of WeakMap and WeakSet.
    224 function TestPrototype(C) {
    225   assertTrue(C.prototype instanceof Object);
    226   assertEquals({
    227     value: {},
    228     writable: false,
    229     enumerable: false,
    230     configurable: false
    231   }, Object.getOwnPropertyDescriptor(C, "prototype"));
    232 }
    233 TestPrototype(WeakMap);
    234 TestPrototype(WeakSet);
    235 
    236 
    237 // Test constructor property of the WeakMap and WeakSet prototype.
    238 function TestConstructor(C) {
    239   assertFalse(C === Object.prototype.constructor);
    240   assertSame(C, C.prototype.constructor);
    241   assertSame(C, (new C).__proto__.constructor);
    242 }
    243 TestConstructor(WeakMap);
    244 TestConstructor(WeakSet);
    245 
    246 
    247 // Test the WeakMap and WeakSet global properties themselves.
    248 function TestDescriptor(global, C) {
    249   assertEquals({
    250     value: C,
    251     writable: true,
    252     enumerable: false,
    253     configurable: true
    254   }, Object.getOwnPropertyDescriptor(global, C.name));
    255 }
    256 TestDescriptor(this, WeakMap);
    257 TestDescriptor(this, WeakSet);
    258 
    259 
    260 // Regression test for WeakMap prototype.
    261 assertTrue(WeakMap.prototype.constructor === WeakMap)
    262 assertTrue(Object.getPrototypeOf(WeakMap.prototype) === Object.prototype)
    263 
    264 
    265 // Regression test for issue 1617: The prototype of the WeakMap constructor
    266 // needs to be unique (i.e. different from the one of the Object constructor).
    267 assertFalse(WeakMap.prototype === Object.prototype);
    268 var o = Object.create({});
    269 assertFalse("get" in o);
    270 assertFalse("set" in o);
    271 assertEquals(undefined, o.get);
    272 assertEquals(undefined, o.set);
    273 var o = Object.create({}, { myValue: {
    274   value: 10,
    275   enumerable: false,
    276   configurable: true,
    277   writable: true
    278 }});
    279 assertEquals(10, o.myValue);
    280 
    281 
    282 // Regression test for issue 1884: Invoking any of the methods for Harmony
    283 // maps, sets, or weak maps, with a wrong type of receiver should be throwing
    284 // a proper TypeError.
    285 var alwaysBogus = [ undefined, null, true, "x", 23, {} ];
    286 var bogusReceiversTestSet = [
    287   { proto: WeakMap.prototype,
    288     funcs: [ 'get', 'set', 'has', 'delete' ],
    289     receivers: alwaysBogus.concat([ new WeakSet ]),
    290   },
    291   { proto: WeakSet.prototype,
    292     funcs: [ 'add', 'has', 'delete' ],
    293     receivers: alwaysBogus.concat([ new WeakMap ]),
    294   },
    295 ];
    296 function TestBogusReceivers(testSet) {
    297   for (var i = 0; i < testSet.length; i++) {
    298     var proto = testSet[i].proto;
    299     var funcs = testSet[i].funcs;
    300     var receivers = testSet[i].receivers;
    301     for (var j = 0; j < funcs.length; j++) {
    302       var func = proto[funcs[j]];
    303       for (var k = 0; k < receivers.length; k++) {
    304         assertThrows(function () { func.call(receivers[k], {}) }, TypeError);
    305       }
    306     }
    307   }
    308 }
    309 TestBogusReceivers(bogusReceiversTestSet);
    310 
    311 
    312 // Test WeakMap clear
    313 (function() {
    314   var k = new Object();
    315   var w = new WeakMap();
    316   w.set(k, 23);
    317   assertTrue(w.has(k));
    318   assertEquals(23, w.get(k));
    319   w.clear();
    320   assertFalse(w.has(k));
    321   assertEquals(undefined, w.get(k));
    322 })();
    323 
    324 
    325 // Test WeakSet clear
    326 (function() {
    327   var k = new Object();
    328   var w = new WeakSet();
    329   w.add(k);
    330   assertTrue(w.has(k));
    331   w.clear();
    332   assertFalse(w.has(k));
    333 })();
    334