| OLD | NEW |
| (Empty) |
| 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(set, 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(map, 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 })(); | |
| OLD | NEW |