| OLD | NEW |
| (Empty) |
| 1 // Copyright 2011 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 // We change the stack size for the ARM64 simulator because at one point this | |
| 29 // test enters an infinite recursion which goes through the runtime and we | |
| 30 // overflow the system stack before the simulator stack. | |
| 31 | |
| 32 // Flags: --harmony-proxies --sim-stack-size=500 --allow-natives-syntax | |
| 33 | |
| 34 | |
| 35 // Helper. | |
| 36 | |
| 37 function TestWithProxies(test, x, y, z) { | |
| 38 // Separate function for nicer stack traces. | |
| 39 TestWithObjectProxy(test, x, y, z); | |
| 40 TestWithFunctionProxy(test, x, y, z); | |
| 41 } | |
| 42 | |
| 43 function TestWithObjectProxy(test, x, y, z) { | |
| 44 test((handler) => { return new Proxy({}, handler) }, x, y, z) | |
| 45 | |
| 46 } | |
| 47 | |
| 48 function TestWithFunctionProxy(test, x, y, z) { | |
| 49 test((handler) => { return new Proxy(() => {}, handler) }, x, y, z) | |
| 50 } | |
| 51 | |
| 52 // --------------------------------------------------------------------------- | |
| 53 // Getting property descriptors (Object.getOwnPropertyDescriptor). | |
| 54 | |
| 55 var key | |
| 56 | |
| 57 function TestGetOwnProperty(handler) { | |
| 58 TestWithProxies(TestGetOwnProperty2, handler) | |
| 59 } | |
| 60 | |
| 61 function TestGetOwnProperty2(create, handler) { | |
| 62 var p = create(handler) | |
| 63 assertEquals(42, Object.getOwnPropertyDescriptor(p, "a").value) | |
| 64 assertEquals("a", key) | |
| 65 assertEquals(42, Object.getOwnPropertyDescriptor(p, 99).value) | |
| 66 assertEquals("99", key) | |
| 67 } | |
| 68 | |
| 69 TestGetOwnProperty({ | |
| 70 getOwnPropertyDescriptor(target, k) { | |
| 71 key = k | |
| 72 return {value: 42, configurable: true} | |
| 73 } | |
| 74 }) | |
| 75 | |
| 76 TestGetOwnProperty({ | |
| 77 getOwnPropertyDescriptor(target, k) { | |
| 78 return this.getOwnPropertyDescriptor2(k) | |
| 79 }, | |
| 80 getOwnPropertyDescriptor2(k) { | |
| 81 key = k | |
| 82 return {value: 42, configurable: true} | |
| 83 } | |
| 84 }) | |
| 85 | |
| 86 TestGetOwnProperty({ | |
| 87 getOwnPropertyDescriptor(target, k) { | |
| 88 key = k | |
| 89 return {get value() { return 42 }, get configurable() { return true }} | |
| 90 } | |
| 91 }) | |
| 92 | |
| 93 TestGetOwnProperty(new Proxy({}, { | |
| 94 get(target, pk, receiver) { | |
| 95 return function(t, k) { key = k; return {value: 42, configurable: true} } | |
| 96 } | |
| 97 })) | |
| 98 | |
| 99 | |
| 100 // --------------------------------------------------------------------------- | |
| 101 function TestGetOwnPropertyThrow(handler) { | |
| 102 TestWithProxies(TestGetOwnPropertyThrow2, handler) | |
| 103 } | |
| 104 | |
| 105 function TestGetOwnPropertyThrow2(create, handler) { | |
| 106 var p = create(handler) | |
| 107 assertThrowsEquals(() => Object.getOwnPropertyDescriptor(p, "a"), "myexn") | |
| 108 assertThrowsEquals(() => Object.getOwnPropertyDescriptor(p, 77), "myexn") | |
| 109 } | |
| 110 | |
| 111 TestGetOwnPropertyThrow({ | |
| 112 getOwnPropertyDescriptor: function(k) { throw "myexn" } | |
| 113 }) | |
| 114 | |
| 115 TestGetOwnPropertyThrow({ | |
| 116 getOwnPropertyDescriptor: function(k) { | |
| 117 return this.getOwnPropertyDescriptor2(k) | |
| 118 }, | |
| 119 getOwnPropertyDescriptor2: function(k) { throw "myexn" } | |
| 120 }) | |
| 121 | |
| 122 TestGetOwnPropertyThrow({ | |
| 123 getOwnPropertyDescriptor: function(k) { | |
| 124 return {get value() { throw "myexn" }} | |
| 125 } | |
| 126 }) | |
| 127 | |
| 128 TestGetOwnPropertyThrow(new Proxy({}, { | |
| 129 get: function(pr, pk) { | |
| 130 return function(k) { throw "myexn" } | |
| 131 } | |
| 132 })) | |
| 133 | |
| 134 | |
| 135 // --------------------------------------------------------------------------- | |
| 136 // Getters (dot, brackets). | |
| 137 | |
| 138 var key | |
| 139 | |
| 140 function TestGet(handler) { | |
| 141 TestWithProxies(TestGet2, handler) | |
| 142 } | |
| 143 | |
| 144 function TestGet2(create, handler) { | |
| 145 var p = create(handler) | |
| 146 assertEquals(42, p.a) | |
| 147 assertEquals("a", key) | |
| 148 assertEquals(42, p["b"]) | |
| 149 assertEquals("b", key) | |
| 150 assertEquals(42, p[99]) | |
| 151 assertEquals("99", key) | |
| 152 assertEquals(42, (function(n) { return p[n] })("c")) | |
| 153 assertEquals("c", key) | |
| 154 assertEquals(42, (function(n) { return p[n] })(101)) | |
| 155 assertEquals("101", key) | |
| 156 | |
| 157 var o = Object.create(p, {x: {value: 88}}) | |
| 158 assertEquals(42, o.a) | |
| 159 assertEquals("a", key) | |
| 160 assertEquals(42, o["b"]) | |
| 161 assertEquals("b", key) | |
| 162 assertEquals(42, o[99]) | |
| 163 assertEquals("99", key) | |
| 164 assertEquals(88, o.x) | |
| 165 assertEquals(88, o["x"]) | |
| 166 assertEquals(42, (function(n) { return o[n] })("c")) | |
| 167 assertEquals("c", key) | |
| 168 assertEquals(42, (function(n) { return o[n] })(101)) | |
| 169 assertEquals("101", key) | |
| 170 assertEquals(88, (function(n) { return o[n] })("x")) | |
| 171 } | |
| 172 | |
| 173 TestGet({ | |
| 174 get(t, k, r) { key = k; return 42 } | |
| 175 }) | |
| 176 | |
| 177 TestGet({ | |
| 178 get(t, k, r) { return this.get2(r, k) }, | |
| 179 get2(r, k) { key = k; return 42 } | |
| 180 }) | |
| 181 | |
| 182 TestGet(new Proxy({}, { | |
| 183 get(pt, pk, pr) { | |
| 184 return function(t, k, r) { key = k; return 42 } | |
| 185 } | |
| 186 })) | |
| 187 | |
| 188 | |
| 189 // --------------------------------------------------------------------------- | |
| 190 function TestGetCall(handler) { | |
| 191 TestWithProxies(TestGetCall2, handler) | |
| 192 } | |
| 193 | |
| 194 function TestGetCall2(create, handler) { | |
| 195 var p = create(handler) | |
| 196 assertEquals(55, p.f()) | |
| 197 assertEquals(55, p["f"]()) | |
| 198 assertEquals(55, p.f("unused", "arguments")) | |
| 199 assertEquals(55, p.f.call(p)) | |
| 200 assertEquals(55, p["f"].call(p)) | |
| 201 assertEquals(55, p[101].call(p)) | |
| 202 assertEquals(55, p.withargs(45, 5)) | |
| 203 assertEquals(55, p.withargs.call(p, 11, 22)) | |
| 204 assertEquals(55, (function(n) { return p[n]() })("f")) | |
| 205 assertEquals(55, (function(n) { return p[n].call(p) })("f")) | |
| 206 assertEquals(55, (function(n) { return p[n](15, 20) })("withargs")) | |
| 207 assertEquals(55, (function(n) { return p[n].call(p, 13, 21) })("withargs")) | |
| 208 assertEquals("6655", "66" + p) // calls p.toString | |
| 209 | |
| 210 var o = Object.create(p, {g: {value: function(x) { return x + 88 }}}) | |
| 211 assertEquals(55, o.f()) | |
| 212 assertEquals(55, o["f"]()) | |
| 213 assertEquals(55, o.f("unused", "arguments")) | |
| 214 assertEquals(55, o.f.call(o)) | |
| 215 assertEquals(55, o.f.call(p)) | |
| 216 assertEquals(55, o["f"].call(p)) | |
| 217 assertEquals(55, o[101].call(p)) | |
| 218 assertEquals(55, o.withargs(45, 5)) | |
| 219 assertEquals(55, o.withargs.call(p, 11, 22)) | |
| 220 assertEquals(90, o.g(2)) | |
| 221 assertEquals(91, o.g.call(o, 3)) | |
| 222 assertEquals(92, o.g.call(p, 4)) | |
| 223 assertEquals(55, (function(n) { return o[n]() })("f")) | |
| 224 assertEquals(55, (function(n) { return o[n].call(o) })("f")) | |
| 225 assertEquals(55, (function(n) { return o[n](15, 20) })("withargs")) | |
| 226 assertEquals(55, (function(n) { return o[n].call(o, 13, 21) })("withargs")) | |
| 227 assertEquals(93, (function(n) { return o[n](5) })("g")) | |
| 228 assertEquals(94, (function(n) { return o[n].call(o, 6) })("g")) | |
| 229 assertEquals(95, (function(n) { return o[n].call(p, 7) })("g")) | |
| 230 assertEquals("6655", "66" + o) // calls o.toString | |
| 231 } | |
| 232 | |
| 233 TestGetCall({ | |
| 234 get(t, k, r) { return () => { return 55 } } | |
| 235 }) | |
| 236 | |
| 237 TestGetCall({ | |
| 238 get(t, k, r) { return this.get2(t, k, r) }, | |
| 239 get2(t, k, r) { return () => { return 55 } } | |
| 240 }) | |
| 241 | |
| 242 TestGetCall({ | |
| 243 get(t, k, r) { | |
| 244 if (k == "gg") { | |
| 245 return () => { return 55 } | |
| 246 } else if (k == "withargs") { | |
| 247 return (n, m) => { return n + m * 2 } | |
| 248 } else { | |
| 249 return () => { return r.gg() } | |
| 250 } | |
| 251 } | |
| 252 }) | |
| 253 | |
| 254 TestGetCall(new Proxy({}, { | |
| 255 get(pt, pk, pr) { | |
| 256 return (t, k, r) => { return () => { return 55 } } | |
| 257 } | |
| 258 })) | |
| 259 | |
| 260 | |
| 261 // --------------------------------------------------------------------------- | |
| 262 function TestGetThrow(handler) { | |
| 263 TestWithProxies(TestGetThrow2, handler) | |
| 264 } | |
| 265 | |
| 266 function TestGetThrow2(create, handler) { | |
| 267 var p = create(handler) | |
| 268 assertThrowsEquals(function(){ p.a }, "myexn") | |
| 269 assertThrowsEquals(function(){ p["b"] }, "myexn") | |
| 270 assertThrowsEquals(function(){ p[3] }, "myexn") | |
| 271 assertThrowsEquals(function(){ (function(n) { p[n] })("c") }, "myexn") | |
| 272 assertThrowsEquals(function(){ (function(n) { p[n] })(99) }, "myexn") | |
| 273 | |
| 274 var o = Object.create(p, {x: {value: 88}, '4': {value: 89}}) | |
| 275 assertThrowsEquals(function(){ o.a }, "myexn") | |
| 276 assertThrowsEquals(function(){ o["b"] }, "myexn") | |
| 277 assertThrowsEquals(function(){ o[3] }, "myexn") | |
| 278 assertThrowsEquals(function(){ (function(n) { o[n] })("c") }, "myexn") | |
| 279 assertThrowsEquals(function(){ (function(n) { o[n] })(99) }, "myexn") | |
| 280 } | |
| 281 | |
| 282 TestGetThrow({ | |
| 283 get(r, k) { throw "myexn" } | |
| 284 }) | |
| 285 | |
| 286 TestGetThrow({ | |
| 287 get(r, k) { return this.get2(r, k) }, | |
| 288 get2(r, k) { throw "myexn" } | |
| 289 }) | |
| 290 | |
| 291 TestGetThrow(new Proxy({}, { | |
| 292 get(pr, pk) { throw "myexn" } | |
| 293 })) | |
| 294 | |
| 295 TestGetThrow(new Proxy({}, { | |
| 296 get(pr, pk) { | |
| 297 return function(r, k) { throw "myexn" } | |
| 298 } | |
| 299 })) | |
| 300 | |
| 301 | |
| 302 // --------------------------------------------------------------------------- | |
| 303 // Setters. | |
| 304 | |
| 305 var key | |
| 306 var val | |
| 307 | |
| 308 function TestSet(handler) { | |
| 309 TestWithProxies(TestSet2, handler) | |
| 310 } | |
| 311 | |
| 312 function TestSet2(create, handler) { | |
| 313 var p = create(handler) | |
| 314 assertEquals(42, p.a = 42) | |
| 315 assertEquals("a", key) | |
| 316 assertEquals(42, val) | |
| 317 assertEquals(43, p["b"] = 43) | |
| 318 assertEquals("b", key) | |
| 319 assertEquals(43, val) | |
| 320 assertEquals(44, p[77] = 44) | |
| 321 assertEquals("77", key) | |
| 322 assertEquals(44, val) | |
| 323 | |
| 324 assertEquals(45, (function(n) { return p[n] = 45 })("c")) | |
| 325 assertEquals("c", key) | |
| 326 assertEquals(45, val) | |
| 327 assertEquals(46, (function(n) { return p[n] = 46 })(99)) | |
| 328 assertEquals("99", key) | |
| 329 assertEquals(46, val) | |
| 330 | |
| 331 assertEquals(47, p["0"] = 47) | |
| 332 assertEquals("0", key) | |
| 333 assertEquals(47, val) | |
| 334 } | |
| 335 | |
| 336 TestSet({ | |
| 337 set: function(r, k, v) { key = k; val = v; return true } | |
| 338 }) | |
| 339 | |
| 340 TestSet({ | |
| 341 set: function(r, k, v) { return this.set2(r, k, v) }, | |
| 342 set2: function(r, k, v) { key = k; val = v; return true } | |
| 343 }) | |
| 344 | |
| 345 TestSet(new Proxy({}, { | |
| 346 get(pk, pr) { | |
| 347 return (r, k, v) => { key = k; val = v; return true } | |
| 348 } | |
| 349 })) | |
| 350 | |
| 351 | |
| 352 // --------------------------------------------------------------------------- | |
| 353 function TestSetThrow(handler) { | |
| 354 TestWithProxies(TestSetThrow2, handler) | |
| 355 } | |
| 356 | |
| 357 function TestSetThrow2(create, handler) { | |
| 358 var p = create(handler) | |
| 359 assertThrowsEquals(function(){ p.a = 42 }, "myexn") | |
| 360 assertThrowsEquals(function(){ p["b"] = 42 }, "myexn") | |
| 361 assertThrowsEquals(function(){ p[22] = 42 }, "myexn") | |
| 362 assertThrowsEquals(function(){ (function(n) { p[n] = 45 })("c") }, "myexn") | |
| 363 assertThrowsEquals(function(){ (function(n) { p[n] = 46 })(99) }, "myexn") | |
| 364 } | |
| 365 | |
| 366 TestSetThrow({ | |
| 367 set: function(r, k, v) { throw "myexn" } | |
| 368 }) | |
| 369 | |
| 370 TestSetThrow({ | |
| 371 set: function(r, k, v) { return this.set2(r, k, v) }, | |
| 372 set2: function(r, k, v) { throw "myexn" } | |
| 373 }) | |
| 374 | |
| 375 TestSetThrow({ | |
| 376 getOwnPropertyDescriptor: function(k) { throw "myexn" }, | |
| 377 defineProperty: function(k, desc) { key = k; val = desc.value } | |
| 378 }) | |
| 379 | |
| 380 TestSetThrow({ | |
| 381 getOwnPropertyDescriptor: function(k) { | |
| 382 return {configurable: true, writable: true} | |
| 383 }, | |
| 384 defineProperty: function(k, desc) { throw "myexn" } | |
| 385 }) | |
| 386 | |
| 387 TestSetThrow({ | |
| 388 getOwnPropertyDescriptor: function(k) { | |
| 389 return this.getOwnPropertyDescriptor2(k) | |
| 390 }, | |
| 391 getOwnPropertyDescriptor2: function(k) { throw "myexn" }, | |
| 392 defineProperty: function(k, desc) { this.defineProperty2(k, desc) }, | |
| 393 defineProperty2: function(k, desc) { key = k; val = desc.value } | |
| 394 }) | |
| 395 | |
| 396 TestSetThrow({ | |
| 397 getOwnPropertyDescriptor: function(k) { | |
| 398 return this.getOwnPropertyDescriptor2(k) | |
| 399 }, | |
| 400 getOwnPropertyDescriptor2: function(k) { | |
| 401 return {configurable: true, writable: true} | |
| 402 }, | |
| 403 defineProperty: function(k, desc) { this.defineProperty2(k, desc) }, | |
| 404 defineProperty2: function(k, desc) { throw "myexn" } | |
| 405 }) | |
| 406 | |
| 407 TestSetThrow({ | |
| 408 getOwnPropertyDescriptor: function(k) { throw "myexn" }, | |
| 409 defineProperty: function(k, desc) { key = k; val = desc.value } | |
| 410 }) | |
| 411 | |
| 412 TestSetThrow({ | |
| 413 getOwnPropertyDescriptor: function(k) { | |
| 414 return { | |
| 415 get configurable() { return true }, | |
| 416 get writable() { return true } | |
| 417 } | |
| 418 }, | |
| 419 defineProperty: function(k, desc) { throw "myexn" } | |
| 420 }) | |
| 421 | |
| 422 TestSetThrow({ | |
| 423 getOwnPropertyDescriptor: function(k) { throw "myexn" } | |
| 424 }) | |
| 425 | |
| 426 TestSetThrow({ | |
| 427 getOwnPropertyDescriptor: function(k) { throw "myexn" }, | |
| 428 defineProperty: function(k, desc) { key = k; val = desc.value } | |
| 429 }) | |
| 430 | |
| 431 TestSetThrow(new Proxy({}, { | |
| 432 get: function(pr, pk) { throw "myexn" } | |
| 433 })) | |
| 434 | |
| 435 TestSetThrow(new Proxy({}, { | |
| 436 get: function(pr, pk) { | |
| 437 return function(r, k, v) { throw "myexn" } | |
| 438 } | |
| 439 })) | |
| 440 | |
| 441 // --------------------------------------------------------------------------- | |
| 442 | |
| 443 // Evil proxy-induced side-effects shouldn't crash. | |
| 444 TestWithProxies(function(create) { | |
| 445 var calls = 0 | |
| 446 var handler = { | |
| 447 getPropertyDescriptor: function() { | |
| 448 ++calls | |
| 449 return (calls % 2 == 1) | |
| 450 ? {get: function() { return 5 }, configurable: true} | |
| 451 : {set: function() { return false }, configurable: true} | |
| 452 } | |
| 453 } | |
| 454 var p = create(handler) | |
| 455 var o = Object.create(p) | |
| 456 // Make proxy prototype property read-only after CanPut check. | |
| 457 try { o.x = 4 } catch (e) { assertInstanceof(e, Error) } | |
| 458 }) | |
| 459 | |
| 460 TestWithProxies(function(create) { | |
| 461 var handler = { | |
| 462 getPropertyDescriptor: function() { | |
| 463 Object.defineProperty(o, "x", {get: function() { return 5 }}); | |
| 464 return {set: function() {}} | |
| 465 } | |
| 466 } | |
| 467 var p = create(handler) | |
| 468 var o = Object.create(p) | |
| 469 // Make object property read-only after CanPut check. | |
| 470 try { o.x = 4 } catch (e) { assertInstanceof(e, Error) } | |
| 471 }) | |
| 472 | |
| 473 | |
| 474 // --------------------------------------------------------------------------- | |
| 475 // Property definition (Object.defineProperty and Object.defineProperties). | |
| 476 | |
| 477 var key | |
| 478 var desc | |
| 479 | |
| 480 function TestDefine(handler) { | |
| 481 TestWithProxies(TestDefine2, handler) | |
| 482 } | |
| 483 | |
| 484 function TestDefine2(create, handler) { | |
| 485 var p = create(handler) | |
| 486 assertEquals(p, Object.defineProperty(p, "a", {value: 44})) | |
| 487 assertEquals("a", key) | |
| 488 assertEquals(1, Object.getOwnPropertyNames(desc).length) | |
| 489 assertEquals(44, desc.value) | |
| 490 | |
| 491 assertEquals(p, Object.defineProperty(p, "b", {value: 45, writable: false})) | |
| 492 assertEquals("b", key) | |
| 493 assertEquals(2, Object.getOwnPropertyNames(desc).length) | |
| 494 assertEquals(45, desc.value) | |
| 495 assertEquals(false, desc.writable) | |
| 496 | |
| 497 assertEquals(p, Object.defineProperty(p, "c", {value: 46, enumerable: false})) | |
| 498 assertEquals("c", key) | |
| 499 assertEquals(2, Object.getOwnPropertyNames(desc).length) | |
| 500 assertEquals(46, desc.value) | |
| 501 assertEquals(false, desc.enumerable) | |
| 502 | |
| 503 assertEquals(p, Object.defineProperty(p, 101, {value: 47, enumerable: false})) | |
| 504 assertEquals("101", key) | |
| 505 assertEquals(2, Object.getOwnPropertyNames(desc).length) | |
| 506 assertEquals(47, desc.value) | |
| 507 assertEquals(false, desc.enumerable) | |
| 508 | |
| 509 var attributes = {configurable: true, mine: 66, minetoo: 23} | |
| 510 assertEquals(p, Object.defineProperty(p, "d", attributes)) | |
| 511 assertEquals("d", key); | |
| 512 // Modifying the attributes object after the fact should have no effect. | |
| 513 attributes.configurable = false | |
| 514 attributes.mine = 77 | |
| 515 delete attributes.minetoo; | |
| 516 assertEquals(1, Object.getOwnPropertyNames(desc).length) | |
| 517 assertEquals(true, desc.configurable) | |
| 518 assertEquals(undefined, desc.mine) | |
| 519 assertEquals(undefined, desc.minetoo) | |
| 520 | |
| 521 assertEquals(p, Object.defineProperty(p, "e", {get: function(){ return 5 }})) | |
| 522 assertEquals("e", key) | |
| 523 assertEquals(1, Object.getOwnPropertyNames(desc).length) | |
| 524 assertEquals(5, desc.get()) | |
| 525 | |
| 526 assertEquals(p, Object.defineProperty(p, "zzz", {})) | |
| 527 assertEquals("zzz", key) | |
| 528 assertEquals(0, Object.getOwnPropertyNames(desc).length) | |
| 529 | |
| 530 var props = { | |
| 531 '11': {}, | |
| 532 blub: {get: function() { return true }}, | |
| 533 '': {get value() { return 20 }}, | |
| 534 last: {value: 21, configurable: true, mine: "eyes"} | |
| 535 } | |
| 536 Object.defineProperty(props, "hidden", {value: "hidden", enumerable: false}) | |
| 537 assertEquals(p, Object.defineProperties(p, props)) | |
| 538 assertEquals("last", key) | |
| 539 assertEquals(2, Object.getOwnPropertyNames(desc).length) | |
| 540 assertEquals(21, desc.value) | |
| 541 assertEquals(true, desc.configurable) | |
| 542 assertEquals(undefined, desc.mine) // Arguably a bug in the spec... | |
| 543 | |
| 544 var props = {bla: {get value() { throw "myexn" }}} | |
| 545 assertThrowsEquals(function(){ Object.defineProperties(p, props) }, "myexn") | |
| 546 } | |
| 547 | |
| 548 TestDefine({ | |
| 549 defineProperty(t, k, d) { key = k; desc = d; return true } | |
| 550 }) | |
| 551 | |
| 552 TestDefine({ | |
| 553 defineProperty(t, k, d) { return this.defineProperty2(k, d) }, | |
| 554 defineProperty2(k, d) { key = k; desc = d; return true } | |
| 555 }) | |
| 556 | |
| 557 | |
| 558 // --------------------------------------------------------------------------- | |
| 559 function TestDefineThrow(handler) { | |
| 560 TestWithProxies(TestDefineThrow2, handler) | |
| 561 } | |
| 562 | |
| 563 function TestDefineThrow2(create, handler) { | |
| 564 var p = create(handler) | |
| 565 assertThrowsEquals(() => Object.defineProperty(p, "a", {value: 44}), "myexn") | |
| 566 assertThrowsEquals(() => Object.defineProperty(p, 0, {value: 44}), "myexn") | |
| 567 | |
| 568 var d1 = create({ | |
| 569 get: function(r, k) { throw "myexn" }, | |
| 570 getOwnPropertyNames: function() { return ["value"] } | |
| 571 }) | |
| 572 assertThrowsEquals(function(){ Object.defineProperty(p, "p", d1) }, "myexn") | |
| 573 var d2 = create({ | |
| 574 get: function(r, k) { return 77 }, | |
| 575 getOwnPropertyNames: function() { throw "myexn" } | |
| 576 }) | |
| 577 assertThrowsEquals(function(){ Object.defineProperty(p, "p", d2) }, "myexn") | |
| 578 | |
| 579 var props = {bla: {get value() { throw "otherexn" }}} | |
| 580 assertThrowsEquals(() => Object.defineProperties(p, props), "otherexn") | |
| 581 } | |
| 582 | |
| 583 TestDefineThrow({ | |
| 584 defineProperty: function(k, d) { throw "myexn" } | |
| 585 }) | |
| 586 | |
| 587 TestDefineThrow({ | |
| 588 defineProperty: function(k, d) { return this.defineProperty2(k, d) }, | |
| 589 defineProperty2: function(k, d) { throw "myexn" } | |
| 590 }) | |
| 591 | |
| 592 TestDefineThrow(new Proxy({}, { | |
| 593 get: function(pr, pk) { throw "myexn" } | |
| 594 })) | |
| 595 | |
| 596 TestDefineThrow(new Proxy({}, { | |
| 597 get: function(pr, pk) { | |
| 598 return function(k, d) { throw "myexn" } | |
| 599 } | |
| 600 })) | |
| 601 | |
| 602 | |
| 603 | |
| 604 // --------------------------------------------------------------------------- | |
| 605 // Property deletion (delete). | |
| 606 | |
| 607 var key | |
| 608 | |
| 609 function TestDelete(handler) { | |
| 610 TestWithProxies(TestDelete2, handler) | |
| 611 } | |
| 612 | |
| 613 function TestDelete2(create, handler) { | |
| 614 var p = create(handler) | |
| 615 assertEquals(true, delete p.a) | |
| 616 assertEquals("a", key) | |
| 617 assertEquals(true, delete p["b"]) | |
| 618 assertEquals("b", key) | |
| 619 assertEquals(true, delete p[1]) | |
| 620 assertEquals("1", key) | |
| 621 | |
| 622 assertEquals(false, delete p.z1) | |
| 623 assertEquals("z1", key) | |
| 624 assertEquals(false, delete p["z2"]) | |
| 625 assertEquals("z2", key); | |
| 626 | |
| 627 (function() { | |
| 628 "use strict" | |
| 629 assertEquals(true, delete p.c) | |
| 630 assertEquals("c", key) | |
| 631 assertEquals(true, delete p["d"]) | |
| 632 assertEquals("d", key) | |
| 633 assertEquals(true, delete p[2]) | |
| 634 assertEquals("2", key) | |
| 635 | |
| 636 assertThrows(function(){ delete p.z3 }, TypeError) | |
| 637 assertEquals("z3", key) | |
| 638 assertThrows(function(){ delete p["z4"] }, TypeError) | |
| 639 assertEquals("z4", key) | |
| 640 })() | |
| 641 } | |
| 642 | |
| 643 TestDelete({ | |
| 644 deleteProperty(target, k) { key = k; return k < "z" } | |
| 645 }) | |
| 646 | |
| 647 TestDelete({ | |
| 648 deleteProperty(target, k) { return this.delete2(k) }, | |
| 649 delete2: function(k) { key = k; return k < "z" } | |
| 650 }) | |
| 651 | |
| 652 TestDelete(new Proxy({}, { | |
| 653 get(pt, pk, pr) { | |
| 654 return (target, k) => { key = k; return k < "z" } | |
| 655 } | |
| 656 })) | |
| 657 | |
| 658 | |
| 659 // --------------------------------------------------------------------------- | |
| 660 function TestDeleteThrow(handler) { | |
| 661 TestWithProxies(TestDeleteThrow2, handler) | |
| 662 } | |
| 663 | |
| 664 function TestDeleteThrow2(create, handler) { | |
| 665 var p = create(handler) | |
| 666 assertThrowsEquals(function(){ delete p.a }, "myexn") | |
| 667 assertThrowsEquals(function(){ delete p["b"] }, "myexn"); | |
| 668 assertThrowsEquals(function(){ delete p[3] }, "myexn"); | |
| 669 | |
| 670 (function() { | |
| 671 "use strict" | |
| 672 assertThrowsEquals(function(){ delete p.c }, "myexn") | |
| 673 assertThrowsEquals(function(){ delete p["d"] }, "myexn") | |
| 674 assertThrowsEquals(function(){ delete p[4] }, "myexn"); | |
| 675 })() | |
| 676 } | |
| 677 | |
| 678 TestDeleteThrow({ | |
| 679 deleteProperty(t, k) { throw "myexn" } | |
| 680 }) | |
| 681 | |
| 682 TestDeleteThrow({ | |
| 683 deleteProperty(t, k) { return this.delete2(k) }, | |
| 684 delete2(k) { throw "myexn" } | |
| 685 }) | |
| 686 | |
| 687 TestDeleteThrow(new Proxy({}, { | |
| 688 get(pt, pk, pr) { throw "myexn" } | |
| 689 })) | |
| 690 | |
| 691 TestDeleteThrow(new Proxy({}, { | |
| 692 get(pt, pk, pr) { | |
| 693 return (k) => { throw "myexn" } | |
| 694 } | |
| 695 })) | |
| 696 | |
| 697 | |
| 698 // --------------------------------------------------------------------------- | |
| 699 // Property descriptors (Object.getOwnPropertyDescriptor). | |
| 700 | |
| 701 function TestDescriptor(handler) { | |
| 702 TestWithProxies(TestDescriptor2, handler) | |
| 703 } | |
| 704 | |
| 705 function TestDescriptor2(create, handler) { | |
| 706 var p = create(handler) | |
| 707 var descs = [ | |
| 708 {configurable: true}, | |
| 709 {value: 34, enumerable: true, configurable: true}, | |
| 710 {value: 3, writable: false, mine: "eyes", configurable: true}, | |
| 711 {get value() { return 20 }, get configurable() { return true }}, | |
| 712 {get: function() { "get" }, set: function() { "set" }, configurable: true} | |
| 713 ] | |
| 714 for (var i = 0; i < descs.length; ++i) { | |
| 715 assertEquals(p, Object.defineProperty(p, i, descs[i])) | |
| 716 var desc = Object.getOwnPropertyDescriptor(p, i) | |
| 717 for (prop in descs[i]) { | |
| 718 // TODO(rossberg): Ignore user attributes as long as the spec isn't | |
| 719 // fixed suitably. | |
| 720 if (prop != "mine") assertEquals(descs[i][prop], desc[prop]) | |
| 721 } | |
| 722 assertEquals(undefined, Object.getOwnPropertyDescriptor(p, "absent")) | |
| 723 } | |
| 724 } | |
| 725 | |
| 726 TestDescriptor({ | |
| 727 defineProperty(t, k, d) { this["__" + k] = d; return true }, | |
| 728 getOwnPropertyDescriptor(t, k) { return this["__" + k] } | |
| 729 }) | |
| 730 | |
| 731 TestDescriptor({ | |
| 732 defineProperty(t, k, d) { this["__" + k] = d; return true }, | |
| 733 getOwnPropertyDescriptor(t, k) { | |
| 734 return this.getOwnPropertyDescriptor2(k) | |
| 735 }, | |
| 736 getOwnPropertyDescriptor2: function(k) { return this["__" + k] } | |
| 737 }) | |
| 738 | |
| 739 | |
| 740 // --------------------------------------------------------------------------- | |
| 741 function TestDescriptorThrow(handler) { | |
| 742 TestWithProxies(TestDescriptorThrow2, handler) | |
| 743 } | |
| 744 | |
| 745 function TestDescriptorThrow2(create, handler) { | |
| 746 var p = create(handler) | |
| 747 assertThrowsEquals(() => Object.getOwnPropertyDescriptor(p, "a"), "myexn") | |
| 748 } | |
| 749 | |
| 750 TestDescriptorThrow({ | |
| 751 getOwnPropertyDescriptor: function(k) { throw "myexn" } | |
| 752 }) | |
| 753 | |
| 754 TestDescriptorThrow({ | |
| 755 getOwnPropertyDescriptor: function(k) { | |
| 756 return this.getOwnPropertyDescriptor2(k) | |
| 757 }, | |
| 758 getOwnPropertyDescriptor2: function(k) { throw "myexn" } | |
| 759 }) | |
| 760 | |
| 761 | |
| 762 | |
| 763 // --------------------------------------------------------------------------- | |
| 764 // Comparison. | |
| 765 | |
| 766 function TestComparison(eq) { | |
| 767 TestWithProxies(TestComparison2, eq) | |
| 768 } | |
| 769 | |
| 770 function TestComparison2(create, eq) { | |
| 771 var p1 = create({}) | |
| 772 var p2 = create({}) | |
| 773 | |
| 774 assertTrue(eq(p1, p1)) | |
| 775 assertTrue(eq(p2, p2)) | |
| 776 assertTrue(!eq(p1, p2)) | |
| 777 assertTrue(!eq(p1, {})) | |
| 778 assertTrue(!eq({}, p2)) | |
| 779 assertTrue(!eq({}, {})) | |
| 780 } | |
| 781 | |
| 782 TestComparison(function(o1, o2) { return o1 == o2 }) | |
| 783 TestComparison(function(o1, o2) { return o1 === o2 }) | |
| 784 TestComparison(function(o1, o2) { return !(o1 != o2) }) | |
| 785 TestComparison(function(o1, o2) { return !(o1 !== o2) }) | |
| 786 | |
| 787 | |
| 788 | |
| 789 // Type (typeof). | |
| 790 | |
| 791 function TestTypeof() { | |
| 792 assertEquals("object", typeof new Proxy({},{})) | |
| 793 assertTrue(typeof new Proxy({}, {}) == "object") | |
| 794 assertTrue("object" == typeof new Proxy({},{})) | |
| 795 | |
| 796 assertEquals("function", typeof new Proxy(function() {}, {})) | |
| 797 assertTrue(typeof new Proxy(function() {}, {}) == "function") | |
| 798 assertTrue("function" == typeof new Proxy(function() {},{})) | |
| 799 } | |
| 800 | |
| 801 TestTypeof() | |
| 802 | |
| 803 | |
| 804 | |
| 805 // --------------------------------------------------------------------------- | |
| 806 // Membership test (in). | |
| 807 | |
| 808 var key | |
| 809 | |
| 810 function TestIn(handler) { | |
| 811 TestWithProxies(TestIn2, handler) | |
| 812 } | |
| 813 | |
| 814 function TestIn2(create, handler) { | |
| 815 var p = create(handler) | |
| 816 assertTrue("a" in p) | |
| 817 assertEquals("a", key) | |
| 818 assertTrue(99 in p) | |
| 819 assertEquals("99", key) | |
| 820 assertFalse("z" in p) | |
| 821 assertEquals("z", key) | |
| 822 | |
| 823 assertEquals(2, ("a" in p) ? 2 : 0) | |
| 824 assertEquals(0, !("a" in p) ? 2 : 0) | |
| 825 assertEquals(0, ("zzz" in p) ? 2 : 0) | |
| 826 assertEquals(2, !("zzz" in p) ? 2 : 0) | |
| 827 | |
| 828 // Test compilation in conditionals. | |
| 829 if ("b" in p) { | |
| 830 } else { | |
| 831 assertTrue(false) | |
| 832 } | |
| 833 assertEquals("b", key) | |
| 834 | |
| 835 if ("zz" in p) { | |
| 836 assertTrue(false) | |
| 837 } | |
| 838 assertEquals("zz", key) | |
| 839 | |
| 840 if (!("c" in p)) { | |
| 841 assertTrue(false) | |
| 842 } | |
| 843 assertEquals("c", key) | |
| 844 | |
| 845 if (!("zzz" in p)) { | |
| 846 } else { | |
| 847 assertTrue(false) | |
| 848 } | |
| 849 assertEquals("zzz", key) | |
| 850 } | |
| 851 | |
| 852 TestIn({ | |
| 853 has(t, k) { key = k; return k < "z" } | |
| 854 }) | |
| 855 | |
| 856 TestIn({ | |
| 857 has(t, k) { return this.has2(k) }, | |
| 858 has2(k) { key = k; return k < "z" } | |
| 859 }) | |
| 860 | |
| 861 TestIn(new Proxy({},{ | |
| 862 get(pt, pk, pr) { | |
| 863 return (t, k) => { key = k; return k < "z" } | |
| 864 } | |
| 865 })) | |
| 866 | |
| 867 | |
| 868 // --------------------------------------------------------------------------- | |
| 869 function TestInThrow(handler) { | |
| 870 TestWithProxies(TestInThrow2, handler) | |
| 871 } | |
| 872 | |
| 873 function TestInThrow2(create, handler) { | |
| 874 var p = create(handler) | |
| 875 assertThrowsEquals(function(){ return "a" in p }, "myexn") | |
| 876 assertThrowsEquals(function(){ return 99 in p }, "myexn") | |
| 877 assertThrowsEquals(function(){ return !("a" in p) }, "myexn") | |
| 878 assertThrowsEquals(function(){ return ("a" in p) ? 2 : 3 }, "myexn") | |
| 879 assertThrowsEquals(function(){ if ("b" in p) {} }, "myexn") | |
| 880 assertThrowsEquals(function(){ if (!("b" in p)) {} }, "myexn") | |
| 881 assertThrowsEquals(function(){ if ("zzz" in p) {} }, "myexn") | |
| 882 } | |
| 883 | |
| 884 TestInThrow({ | |
| 885 has: function(k) { throw "myexn" } | |
| 886 }) | |
| 887 | |
| 888 TestInThrow({ | |
| 889 has: function(k) { return this.has2(k) }, | |
| 890 has2: function(k) { throw "myexn" } | |
| 891 }) | |
| 892 | |
| 893 TestInThrow(new Proxy({},{ | |
| 894 get: function(pr, pk) { throw "myexn" } | |
| 895 })) | |
| 896 | |
| 897 TestInThrow(new Proxy({},{ | |
| 898 get: function(pr, pk) { | |
| 899 return function(k) { throw "myexn" } | |
| 900 } | |
| 901 })) | |
| 902 | |
| 903 | |
| 904 | |
| 905 // --------------------------------------------------------------------------- | |
| 906 // Own Properties (Object.prototype.hasOwnProperty). | |
| 907 | |
| 908 var key | |
| 909 | |
| 910 function TestHasOwn(handler) { | |
| 911 TestWithProxies(TestHasOwn2, handler) | |
| 912 } | |
| 913 | |
| 914 function TestHasOwn2(create, handler) { | |
| 915 var p = create(handler) | |
| 916 assertTrue(Object.prototype.hasOwnProperty.call(p, "a")) | |
| 917 assertEquals("a", key) | |
| 918 assertTrue(Object.prototype.hasOwnProperty.call(p, 99)) | |
| 919 assertEquals("99", key) | |
| 920 assertFalse(Object.prototype.hasOwnProperty.call(p, "z")) | |
| 921 assertEquals("z", key) | |
| 922 } | |
| 923 | |
| 924 TestHasOwn({ | |
| 925 getOwnPropertyDescriptor(t, k) { | |
| 926 key = k; if (k < "z") return {configurable: true} | |
| 927 }, | |
| 928 has() { assertUnreachable() } | |
| 929 }) | |
| 930 | |
| 931 TestHasOwn({ | |
| 932 getOwnPropertyDescriptor(t, k) { return this.getOwnPropertyDescriptor2(k) }, | |
| 933 getOwnPropertyDescriptor2(k) { | |
| 934 key = k; if (k < "z") return {configurable: true} | |
| 935 } | |
| 936 }) | |
| 937 | |
| 938 | |
| 939 | |
| 940 // --------------------------------------------------------------------------- | |
| 941 function TestHasOwnThrow(handler) { | |
| 942 TestWithProxies(TestHasOwnThrow2, handler) | |
| 943 } | |
| 944 | |
| 945 function TestHasOwnThrow2(create, handler) { | |
| 946 var p = create(handler) | |
| 947 assertThrowsEquals(function(){ Object.prototype.hasOwnProperty.call(p, "a")}, | |
| 948 "myexn") | |
| 949 assertThrowsEquals(function(){ Object.prototype.hasOwnProperty.call(p, 99)}, | |
| 950 "myexn") | |
| 951 } | |
| 952 | |
| 953 TestHasOwnThrow({ | |
| 954 getOwnPropertyDescriptor(t, k) { throw "myexn" } | |
| 955 }) | |
| 956 | |
| 957 TestHasOwnThrow({ | |
| 958 getOwnPropertyDescriptor(t, k) { return this.getOwnPropertyDescriptor2(k) }, | |
| 959 getOwnPropertyDescriptor2(k) { throw "myexn" } | |
| 960 }); | |
| 961 | |
| 962 | |
| 963 // --------------------------------------------------------------------------- | |
| 964 // Instanceof (instanceof) | |
| 965 | |
| 966 (function TestProxyInstanceof() { | |
| 967 var o1 = {} | |
| 968 var p1 = new Proxy({}, {}) | |
| 969 var p2 = new Proxy(o1, {}) | |
| 970 var p3 = new Proxy(p2, {}) | |
| 971 var o2 = Object.create(p2) | |
| 972 | |
| 973 var f0 = function() {} | |
| 974 f0.prototype = o1 | |
| 975 var f1 = function() {} | |
| 976 f1.prototype = p1 | |
| 977 var f2 = function() {} | |
| 978 f2.prototype = p2 | |
| 979 var f3 = function() {} | |
| 980 f3.prototype = o2 | |
| 981 | |
| 982 assertTrue(o1 instanceof Object) | |
| 983 assertFalse(o1 instanceof f0) | |
| 984 assertFalse(o1 instanceof f1) | |
| 985 assertFalse(o1 instanceof f2) | |
| 986 assertFalse(o1 instanceof f3) | |
| 987 assertTrue(p1 instanceof Object) | |
| 988 assertFalse(p1 instanceof f0) | |
| 989 assertFalse(p1 instanceof f1) | |
| 990 assertFalse(p1 instanceof f2) | |
| 991 assertFalse(p1 instanceof f3) | |
| 992 assertTrue(p2 instanceof Object) | |
| 993 assertFalse(p2 instanceof f0) | |
| 994 assertFalse(p2 instanceof f1) | |
| 995 assertFalse(p2 instanceof f2) | |
| 996 assertFalse(p2 instanceof f3) | |
| 997 assertTrue(p3 instanceof Object) | |
| 998 assertFalse(p3 instanceof f0) | |
| 999 assertFalse(p3 instanceof f1) | |
| 1000 assertFalse(p3 instanceof f2) | |
| 1001 assertFalse(p3 instanceof f3) | |
| 1002 assertTrue(o2 instanceof Object) | |
| 1003 assertFalse(o2 instanceof f0) | |
| 1004 assertFalse(o2 instanceof f1) | |
| 1005 assertTrue(o2 instanceof f2) | |
| 1006 assertFalse(o2 instanceof f3) | |
| 1007 | |
| 1008 var f = new Proxy(function() {}, {}) | |
| 1009 assertTrue(f instanceof Function) | |
| 1010 })(); | |
| 1011 | |
| 1012 | |
| 1013 (function TestInstanceofProxy() { | |
| 1014 var o0 = Object.create(null) | |
| 1015 var o1 = {} | |
| 1016 var o2 = Object.create(o0) | |
| 1017 var o3 = Object.create(o1) | |
| 1018 var o4 = Object.create(o2) | |
| 1019 var o5 = Object.create(o3) | |
| 1020 | |
| 1021 function handler(o) { | |
| 1022 return { | |
| 1023 get: function(r, p) { | |
| 1024 // We want to test prototype lookup, so ensure the proxy | |
| 1025 // offers OrdinaryHasInstance behavior. | |
| 1026 if (p === Symbol.hasInstance) { | |
| 1027 return undefined; | |
| 1028 } | |
| 1029 return o; | |
| 1030 } | |
| 1031 } | |
| 1032 } | |
| 1033 | |
| 1034 var f0 = new Proxy(function() {}, handler(o0)) | |
| 1035 var f1 = new Proxy(function() {}, handler(o1)) | |
| 1036 var f2 = new Proxy(function() {}, handler(o2)) | |
| 1037 var f3 = new Proxy(function() {}, handler(o3)) | |
| 1038 var f4 = new Proxy(function() {}, handler(o4)) | |
| 1039 var f5 = new Proxy(function() {}, handler(o4)) | |
| 1040 | |
| 1041 assertFalse(null instanceof f0) | |
| 1042 assertFalse(o0 instanceof f0) | |
| 1043 assertFalse(o0 instanceof f1) | |
| 1044 assertFalse(o0 instanceof f2) | |
| 1045 assertFalse(o0 instanceof f3) | |
| 1046 assertFalse(o0 instanceof f4) | |
| 1047 assertFalse(o0 instanceof f5) | |
| 1048 assertFalse(o1 instanceof f0) | |
| 1049 assertFalse(o1 instanceof f1) | |
| 1050 assertFalse(o1 instanceof f2) | |
| 1051 assertFalse(o1 instanceof f3) | |
| 1052 assertFalse(o1 instanceof f4) | |
| 1053 assertFalse(o1 instanceof f5) | |
| 1054 assertTrue(o2 instanceof f0) | |
| 1055 assertFalse(o2 instanceof f1) | |
| 1056 assertFalse(o2 instanceof f2) | |
| 1057 assertFalse(o2 instanceof f3) | |
| 1058 assertFalse(o2 instanceof f4) | |
| 1059 assertFalse(o2 instanceof f5) | |
| 1060 assertFalse(o3 instanceof f0) | |
| 1061 assertTrue(o3 instanceof f1) | |
| 1062 assertFalse(o3 instanceof f2) | |
| 1063 assertFalse(o3 instanceof f3) | |
| 1064 assertFalse(o3 instanceof f4) | |
| 1065 assertFalse(o3 instanceof f5) | |
| 1066 assertTrue(o4 instanceof f0) | |
| 1067 assertFalse(o4 instanceof f1) | |
| 1068 assertTrue(o4 instanceof f2) | |
| 1069 assertFalse(o4 instanceof f3) | |
| 1070 assertFalse(o4 instanceof f4) | |
| 1071 assertFalse(o4 instanceof f5) | |
| 1072 assertFalse(o5 instanceof f0) | |
| 1073 assertTrue(o5 instanceof f1) | |
| 1074 assertFalse(o5 instanceof f2) | |
| 1075 assertTrue(o5 instanceof f3) | |
| 1076 assertFalse(o5 instanceof f4) | |
| 1077 assertFalse(o5 instanceof f5) | |
| 1078 | |
| 1079 var f = new Proxy(function() {}, {}) | |
| 1080 var ff = new Proxy(function() {}, handler(Function)) | |
| 1081 assertTrue(f instanceof Function) | |
| 1082 assertFalse(f instanceof ff) | |
| 1083 })(); | |
| 1084 | |
| 1085 | |
| 1086 // --------------------------------------------------------------------------- | |
| 1087 // Prototype (Object.getPrototypeOf, Object.prototype.isPrototypeOf). | |
| 1088 | |
| 1089 (function TestPrototype() { | |
| 1090 var o1 = {} | |
| 1091 var p1 = new Proxy({}, {}) | |
| 1092 var p2 = new Proxy(o1, {}) | |
| 1093 var p3 = new Proxy(p2, {}) | |
| 1094 var o2 = Object.create(p3) | |
| 1095 | |
| 1096 assertSame(Object.getPrototypeOf(o1), Object.prototype) | |
| 1097 assertSame(Object.getPrototypeOf(p1), Object.prototype) | |
| 1098 assertSame(Object.getPrototypeOf(p2), Object.prototype) | |
| 1099 assertSame(Object.getPrototypeOf(p3), Object.prototype) | |
| 1100 assertSame(Object.getPrototypeOf(o2), p3) | |
| 1101 | |
| 1102 assertTrue(Object.prototype.isPrototypeOf(o1)) | |
| 1103 assertTrue(Object.prototype.isPrototypeOf(p1)) | |
| 1104 assertTrue(Object.prototype.isPrototypeOf(p2)) | |
| 1105 assertTrue(Object.prototype.isPrototypeOf(p3)) | |
| 1106 assertTrue(Object.prototype.isPrototypeOf(o2)) | |
| 1107 assertTrue(Object.prototype.isPrototypeOf.call(Object.prototype, o1)) | |
| 1108 assertTrue(Object.prototype.isPrototypeOf.call(Object.prototype, p1)) | |
| 1109 assertTrue(Object.prototype.isPrototypeOf.call(Object.prototype, p2)) | |
| 1110 assertTrue(Object.prototype.isPrototypeOf.call(Object.prototype, p3)) | |
| 1111 assertTrue(Object.prototype.isPrototypeOf.call(Object.prototype, o2)) | |
| 1112 assertFalse(Object.prototype.isPrototypeOf.call(o1, o1)) | |
| 1113 assertFalse(Object.prototype.isPrototypeOf.call(o1, p1)) | |
| 1114 assertFalse(Object.prototype.isPrototypeOf.call(o1, p2)) | |
| 1115 assertFalse(Object.prototype.isPrototypeOf.call(o1, p3)) | |
| 1116 assertFalse(Object.prototype.isPrototypeOf.call(o1, o2)) | |
| 1117 assertFalse(Object.prototype.isPrototypeOf.call(p1, p1)) | |
| 1118 assertFalse(Object.prototype.isPrototypeOf.call(p1, o1)) | |
| 1119 assertFalse(Object.prototype.isPrototypeOf.call(p1, p2)) | |
| 1120 assertFalse(Object.prototype.isPrototypeOf.call(p1, p3)) | |
| 1121 assertFalse(Object.prototype.isPrototypeOf.call(p1, o2)) | |
| 1122 assertFalse(Object.prototype.isPrototypeOf.call(p2, p1)) | |
| 1123 assertFalse(Object.prototype.isPrototypeOf.call(p2, p2)) | |
| 1124 assertFalse(Object.prototype.isPrototypeOf.call(p2, p3)) | |
| 1125 assertFalse(Object.prototype.isPrototypeOf.call(p2, o2)) | |
| 1126 assertFalse(Object.prototype.isPrototypeOf.call(p3, p2)) | |
| 1127 assertTrue(Object.prototype.isPrototypeOf.call(p3, o2)) | |
| 1128 assertFalse(Object.prototype.isPrototypeOf.call(o2, o1)) | |
| 1129 assertFalse(Object.prototype.isPrototypeOf.call(o2, p1)) | |
| 1130 assertFalse(Object.prototype.isPrototypeOf.call(o2, p2)) | |
| 1131 assertFalse(Object.prototype.isPrototypeOf.call(o2, p3)) | |
| 1132 assertFalse(Object.prototype.isPrototypeOf.call(o2, o2)) | |
| 1133 | |
| 1134 var f = new Proxy(function() {}, {}) | |
| 1135 assertSame(Object.getPrototypeOf(f), Function.prototype) | |
| 1136 assertTrue(Object.prototype.isPrototypeOf(f)) | |
| 1137 assertTrue(Object.prototype.isPrototypeOf.call(Function.prototype, f)) | |
| 1138 })(); | |
| 1139 | |
| 1140 | |
| 1141 // --------------------------------------------------------------------------- | |
| 1142 function TestPropertyNamesThrow(handler) { | |
| 1143 TestWithProxies(TestPropertyNamesThrow2, handler) | |
| 1144 } | |
| 1145 | |
| 1146 function TestPropertyNamesThrow2(create, handler) { | |
| 1147 var p = create(handler) | |
| 1148 assertThrowsEquals(function(){ Object.getOwnPropertyNames(p) }, "myexn") | |
| 1149 } | |
| 1150 | |
| 1151 TestPropertyNamesThrow({ | |
| 1152 ownKeys() { throw "myexn" } | |
| 1153 }) | |
| 1154 | |
| 1155 TestPropertyNamesThrow({ | |
| 1156 ownKeys() { return this.getOwnPropertyNames2() }, | |
| 1157 getOwnPropertyNames2() { throw "myexn" } | |
| 1158 }) | |
| 1159 | |
| 1160 // --------------------------------------------------------------------------- | |
| 1161 | |
| 1162 function TestKeys(names, handler) { | |
| 1163 var p = new Proxy({}, handler); | |
| 1164 assertArrayEquals(names, Object.keys(p)) | |
| 1165 } | |
| 1166 | |
| 1167 TestKeys([], { | |
| 1168 ownKeys() { return [] } | |
| 1169 }) | |
| 1170 | |
| 1171 TestKeys([], { | |
| 1172 ownKeys() { return ["a", "zz", " ", "0", "toString"] } | |
| 1173 }) | |
| 1174 | |
| 1175 TestKeys(["a", "zz", " ", "0", "toString"], { | |
| 1176 ownKeys() { return ["a", "zz", " ", "0", "toString"] }, | |
| 1177 getOwnPropertyDescriptor(t, p) { | |
| 1178 return {configurable: true, enumerable: true} | |
| 1179 } | |
| 1180 }) | |
| 1181 | |
| 1182 TestKeys([], { | |
| 1183 ownKeys() { return this.keys2() }, | |
| 1184 keys2() { return ["throw", "function "] } | |
| 1185 }) | |
| 1186 | |
| 1187 TestKeys(["throw", "function "], { | |
| 1188 ownKeys() { return this.keys2() }, | |
| 1189 keys2() { return ["throw", "function "] }, | |
| 1190 getOwnPropertyDescriptor(t, p) { | |
| 1191 return {configurable: true, enumerable: true} | |
| 1192 } | |
| 1193 }) | |
| 1194 | |
| 1195 TestKeys(["a", "0"], { | |
| 1196 ownKeys() { return ["a", "23", "zz", "", "0"] }, | |
| 1197 getOwnPropertyDescriptor(t, k) { | |
| 1198 return k == "" ? | |
| 1199 undefined : | |
| 1200 { configurable: true, enumerable: k.length == 1} | |
| 1201 } | |
| 1202 }) | |
| 1203 | |
| 1204 TestKeys(["23", "zz", ""], { | |
| 1205 ownKeys() { return this.getOwnPropertyNames2() }, | |
| 1206 getOwnPropertyNames2() { return ["a", "23", "zz", "", "0"] }, | |
| 1207 getOwnPropertyDescriptor(t, k) { | |
| 1208 return this.getOwnPropertyDescriptor2(k) | |
| 1209 }, | |
| 1210 getOwnPropertyDescriptor2(k) { | |
| 1211 return {configurable: true, enumerable: k.length != 1 } | |
| 1212 } | |
| 1213 }) | |
| 1214 | |
| 1215 TestKeys([], { | |
| 1216 get ownKeys() { | |
| 1217 return function() { return ["a", "b", "c"] } | |
| 1218 }, | |
| 1219 getOwnPropertyDescriptor: function(k) { return {configurable: true} } | |
| 1220 }) | |
| 1221 | |
| 1222 | |
| 1223 // --------------------------------------------------------------------------- | |
| 1224 function TestKeysThrow(handler) { | |
| 1225 TestWithProxies(TestKeysThrow2, handler) | |
| 1226 } | |
| 1227 | |
| 1228 function TestKeysThrow2(create, handler) { | |
| 1229 var p = create(handler); | |
| 1230 assertThrowsEquals(function(){ Object.keys(p) }, "myexn"); | |
| 1231 } | |
| 1232 | |
| 1233 TestKeysThrow({ | |
| 1234 ownKeys() { throw "myexn" } | |
| 1235 }) | |
| 1236 | |
| 1237 TestKeysThrow({ | |
| 1238 ownKeys() { return this.keys2() }, | |
| 1239 keys2() { throw "myexn" } | |
| 1240 }) | |
| 1241 | |
| 1242 TestKeysThrow({ | |
| 1243 ownKeys() { return ['1'] }, | |
| 1244 getOwnPropertyDescriptor: function() { throw "myexn" }, | |
| 1245 }) | |
| 1246 | |
| 1247 TestKeysThrow({ | |
| 1248 ownKeys() { return this.getOwnPropertyNames2() }, | |
| 1249 getOwnPropertyNames2() { return ['1', '2'] }, | |
| 1250 getOwnPropertyDescriptor(k) { | |
| 1251 return this.getOwnPropertyDescriptor2(k) | |
| 1252 }, | |
| 1253 getOwnPropertyDescriptor2(k) { throw "myexn" } | |
| 1254 }) | |
| 1255 | |
| 1256 TestKeysThrow({ | |
| 1257 get ownKeys() { throw "myexn" } | |
| 1258 }) | |
| 1259 | |
| 1260 TestKeysThrow({ | |
| 1261 get ownKeys() { | |
| 1262 return function() { throw "myexn" } | |
| 1263 }, | |
| 1264 }) | |
| 1265 | |
| 1266 TestKeysThrow({ | |
| 1267 get ownKeys() { | |
| 1268 return function() { return ['1', '2'] } | |
| 1269 }, | |
| 1270 getOwnPropertyDescriptor(k) { throw "myexn" } | |
| 1271 }) | |
| 1272 | |
| 1273 | |
| 1274 | |
| 1275 // --------------------------------------------------------------------------- | |
| 1276 // String conversion (Object.prototype.toString, | |
| 1277 // Object.prototype.toLocaleString, | |
| 1278 // Function.prototype.toString) | |
| 1279 | |
| 1280 var key | |
| 1281 | |
| 1282 function TestToString(handler) { | |
| 1283 var p = new Proxy({}, handler) | |
| 1284 key = "" | |
| 1285 assertEquals("[object Object]", Object.prototype.toString.call(p)) | |
| 1286 assertEquals(Symbol.toStringTag, key) | |
| 1287 assertEquals("my_proxy", Object.prototype.toLocaleString.call(p)) | |
| 1288 assertEquals("toString", key) | |
| 1289 | |
| 1290 var f = new Proxy(function() {}, handler) | |
| 1291 key = "" | |
| 1292 assertEquals("[object Function]", Object.prototype.toString.call(f)) | |
| 1293 assertEquals(Symbol.toStringTag, key) | |
| 1294 assertEquals("my_proxy", Object.prototype.toLocaleString.call(f)) | |
| 1295 assertEquals("toString", key) | |
| 1296 assertThrows(function(){ Function.prototype.toString.call(f) }) | |
| 1297 | |
| 1298 var o = Object.create(p) | |
| 1299 key = "" | |
| 1300 assertEquals("[object Object]", Object.prototype.toString.call(o)) | |
| 1301 assertEquals(Symbol.toStringTag, key) | |
| 1302 assertEquals("my_proxy", Object.prototype.toLocaleString.call(o)) | |
| 1303 assertEquals("toString", key) | |
| 1304 } | |
| 1305 | |
| 1306 TestToString({ | |
| 1307 get: function(r, k) { key = k; return function() { return "my_proxy" } } | |
| 1308 }) | |
| 1309 | |
| 1310 TestToString({ | |
| 1311 get: function(r, k) { return this.get2(r, k) }, | |
| 1312 get2: function(r, k) { key = k; return function() { return "my_proxy" } } | |
| 1313 }) | |
| 1314 | |
| 1315 TestToString(new Proxy({}, { | |
| 1316 get: function(pr, pk) { | |
| 1317 return function(r, k) { key = k; return function() { return "my_proxy" } } | |
| 1318 } | |
| 1319 })) | |
| 1320 | |
| 1321 | |
| 1322 function TestToStringThrow(handler) { | |
| 1323 var p = new Proxy({}, handler) | |
| 1324 assertThrowsEquals(() => Object.prototype.toString.call(p), "myexn") | |
| 1325 assertThrowsEquals(() => Object.prototype.toLocaleString.call(p), "myexn") | |
| 1326 | |
| 1327 var f = new Proxy(function(){}, handler) | |
| 1328 assertThrowsEquals(() => Object.prototype.toString.call(f), "myexn") | |
| 1329 assertThrowsEquals(() => Object.prototype.toLocaleString.call(f), "myexn") | |
| 1330 | |
| 1331 var o = Object.create(p) | |
| 1332 assertThrowsEquals(() => Object.prototype.toString.call(o), "myexn") | |
| 1333 assertThrowsEquals(() => Object.prototype.toLocaleString.call(o), "myexn") | |
| 1334 } | |
| 1335 | |
| 1336 TestToStringThrow({ | |
| 1337 get: function(r, k) { throw "myexn" } | |
| 1338 }) | |
| 1339 | |
| 1340 TestToStringThrow({ | |
| 1341 get: function(r, k) { return this.get2(r, k) }, | |
| 1342 get2: function(r, k) { throw "myexn" } | |
| 1343 }) | |
| 1344 | |
| 1345 TestToStringThrow(new Proxy({}, { | |
| 1346 get: function(pr, pk) { throw "myexn" } | |
| 1347 })) | |
| 1348 | |
| 1349 TestToStringThrow(new Proxy({}, { | |
| 1350 get: function(pr, pk) { | |
| 1351 return function(r, k) { throw "myexn" } | |
| 1352 } | |
| 1353 })) | |
| 1354 | |
| 1355 | |
| 1356 // --------------------------------------------------------------------------- | |
| 1357 // Value conversion (Object.prototype.toValue) | |
| 1358 | |
| 1359 function TestValueOf(handler) { | |
| 1360 TestWithProxies(TestValueOf2, handler) | |
| 1361 } | |
| 1362 | |
| 1363 function TestValueOf2(create, handler) { | |
| 1364 var p = create(handler) | |
| 1365 assertSame(p, Object.prototype.valueOf.call(p)) | |
| 1366 } | |
| 1367 | |
| 1368 TestValueOf({}) | |
| 1369 | |
| 1370 | |
| 1371 | |
| 1372 // --------------------------------------------------------------------------- | |
| 1373 // Enumerability (Object.prototype.propertyIsEnumerable) | |
| 1374 | |
| 1375 var key | |
| 1376 | |
| 1377 function TestIsEnumerable(handler) { | |
| 1378 TestWithProxies(TestIsEnumerable2, handler) | |
| 1379 } | |
| 1380 | |
| 1381 function TestIsEnumerable2(create, handler) { | |
| 1382 var p = create(handler) | |
| 1383 assertTrue(Object.prototype.propertyIsEnumerable.call(p, "a")) | |
| 1384 assertEquals("a", key) | |
| 1385 assertTrue(Object.prototype.propertyIsEnumerable.call(p, 2)) | |
| 1386 assertEquals("2", key) | |
| 1387 assertFalse(Object.prototype.propertyIsEnumerable.call(p, "z")) | |
| 1388 assertEquals("z", key) | |
| 1389 | |
| 1390 var o = Object.create(p) | |
| 1391 key = "" | |
| 1392 assertFalse(Object.prototype.propertyIsEnumerable.call(o, "a")) | |
| 1393 assertEquals("", key) // trap not invoked | |
| 1394 } | |
| 1395 | |
| 1396 TestIsEnumerable({ | |
| 1397 getOwnPropertyDescriptor(t, k) { | |
| 1398 key = k; | |
| 1399 return {enumerable: k < "z", configurable: true} | |
| 1400 }, | |
| 1401 }) | |
| 1402 | |
| 1403 TestIsEnumerable({ | |
| 1404 getOwnPropertyDescriptor: function(t, k) { | |
| 1405 return this.getOwnPropertyDescriptor2(k) | |
| 1406 }, | |
| 1407 getOwnPropertyDescriptor2: function(k) { | |
| 1408 key = k; | |
| 1409 return {enumerable: k < "z", configurable: true} | |
| 1410 }, | |
| 1411 }) | |
| 1412 | |
| 1413 TestIsEnumerable({ | |
| 1414 getOwnPropertyDescriptor: function(t, k) { | |
| 1415 key = k; | |
| 1416 return {get enumerable() { return k < "z" }, configurable: true} | |
| 1417 }, | |
| 1418 }) | |
| 1419 | |
| 1420 TestIsEnumerable(new Proxy({}, { | |
| 1421 get: function(pt, pk, pr) { | |
| 1422 return function(t, k) { | |
| 1423 key = k; | |
| 1424 return {enumerable: k < "z", configurable: true} | |
| 1425 } | |
| 1426 } | |
| 1427 })) | |
| 1428 | |
| 1429 | |
| 1430 // --------------------------------------------------------------------------- | |
| 1431 function TestIsEnumerableThrow(handler) { | |
| 1432 TestWithProxies(TestIsEnumerableThrow2, handler) | |
| 1433 } | |
| 1434 | |
| 1435 function TestIsEnumerableThrow2(create, handler) { | |
| 1436 var p = create(handler) | |
| 1437 assertThrowsEquals(() => Object.prototype.propertyIsEnumerable.call(p, "a"), | |
| 1438 "myexn") | |
| 1439 assertThrowsEquals(() => Object.prototype.propertyIsEnumerable.call(p, 11), | |
| 1440 "myexn") | |
| 1441 } | |
| 1442 | |
| 1443 TestIsEnumerableThrow({ | |
| 1444 getOwnPropertyDescriptor: function(k) { throw "myexn" } | |
| 1445 }) | |
| 1446 | |
| 1447 TestIsEnumerableThrow({ | |
| 1448 getOwnPropertyDescriptor: function(k) { | |
| 1449 return this.getOwnPropertyDescriptor2(k) | |
| 1450 }, | |
| 1451 getOwnPropertyDescriptor2: function(k) { throw "myexn" } | |
| 1452 }) | |
| 1453 | |
| 1454 TestIsEnumerableThrow({ | |
| 1455 getOwnPropertyDescriptor: function(k) { | |
| 1456 return {get enumerable() { throw "myexn" }, configurable: true} | |
| 1457 }, | |
| 1458 }) | |
| 1459 | |
| 1460 TestIsEnumerableThrow(new Proxy({}, { | |
| 1461 get: function(pr, pk) { throw "myexn" } | |
| 1462 })) | |
| 1463 | |
| 1464 TestIsEnumerableThrow(new Proxy({}, { | |
| 1465 get: function(pr, pk) { | |
| 1466 return function(k) { throw "myexn" } | |
| 1467 } | |
| 1468 })); | |
| 1469 | |
| 1470 | |
| 1471 | |
| 1472 // --------------------------------------------------------------------------- | |
| 1473 // Constructor functions with proxy prototypes. | |
| 1474 | |
| 1475 (function TestConstructorWithProxyPrototype() { | |
| 1476 TestWithProxies(TestConstructorWithProxyPrototype2, {}) | |
| 1477 })(); | |
| 1478 | |
| 1479 function TestConstructorWithProxyPrototype2(create, handler) { | |
| 1480 function C() {}; | |
| 1481 C.prototype = create(handler); | |
| 1482 | |
| 1483 var o = new C; | |
| 1484 assertSame(C.prototype, Object.getPrototypeOf(o)); | |
| 1485 }; | |
| 1486 | |
| 1487 | |
| 1488 (function TestOptWithProxyPrototype() { | |
| 1489 var handler = { | |
| 1490 get(t, k) { | |
| 1491 return 10; | |
| 1492 } | |
| 1493 }; | |
| 1494 | |
| 1495 function C() {}; | |
| 1496 C.prototype = new Proxy({}, handler); | |
| 1497 var o = new C(); | |
| 1498 | |
| 1499 function f() { | |
| 1500 return o.x; | |
| 1501 } | |
| 1502 assertEquals(10, f()); | |
| 1503 assertEquals(10, f()); | |
| 1504 %OptimizeFunctionOnNextCall(f); | |
| 1505 assertEquals(10, f()); | |
| 1506 })(); | |
| OLD | NEW |