diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /js/src/tests/test262/built-ins/Proxy | |
parent | Initial commit. (diff) | |
download | firefox-esr-upstream.tar.xz firefox-esr-upstream.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
343 files changed, 10256 insertions, 0 deletions
diff --git a/js/src/tests/test262/built-ins/Proxy/apply/arguments-realm.js b/js/src/tests/test262/built-ins/Proxy/apply/arguments-realm.js new file mode 100644 index 0000000000..41359d9e69 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/apply/arguments-realm.js @@ -0,0 +1,20 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-call-thisargument-argumentslist +description: > + Arguments array is created in the Realm of the current execution context +info: | + [...] + 7. Let argArray be CreateArrayFromList(argumentsList). + 8. Return ? Call(trap, handler, « target, thisArgument, argArray »). +features: [cross-realm] +---*/ + +var f = $262.createRealm().global.eval( + 'new Proxy(function() {}, { apply: function(_, __, args) { return args; } })' +); + +assert.sameValue(f().constructor, Array); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/apply/browser.js b/js/src/tests/test262/built-ins/Proxy/apply/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/apply/browser.js diff --git a/js/src/tests/test262/built-ins/Proxy/apply/call-parameters.js b/js/src/tests/test262/built-ins/Proxy/apply/call-parameters.js new file mode 100644 index 0000000000..35e641e1c0 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/apply/call-parameters.js @@ -0,0 +1,40 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-call-thisargument-argumentslist +description: > + trap is called with handler object as its context, and parameters are: + target, the call context and and an array list with the called arguments +info: | + [[Call]] (thisArgument, argumentsList) + + 9. Return Call(trap, handler, «target, thisArgument, argArray»). +features: [Proxy] +---*/ + +var _target, _args, _handler, _context; +var target = function() { + throw new Test262Error('target should not be called'); +}; +var handler = { + apply: function(t, c, args) { + _handler = this; + _target = t; + _context = c; + _args = args; + } +}; +var p = new Proxy(target, handler); + +var context = {}; + +p.call(context, 1, 2); + +assert.sameValue(_handler, handler, "trap context is the handler object"); +assert.sameValue(_target, target, "first parameter is the target object"); +assert.sameValue(_context, context, "second parameter is the call context"); +assert.sameValue(_args.length, 2, "arguments list contains all call arguments"); +assert.sameValue(_args[0], 1, "arguments list has first call argument"); +assert.sameValue(_args[1], 2, "arguments list has second call argument"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/apply/call-result.js b/js/src/tests/test262/built-ins/Proxy/apply/call-result.js new file mode 100644 index 0000000000..23175ea80b --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/apply/call-result.js @@ -0,0 +1,25 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-call-thisargument-argumentslist +description: > + Return the result from the trap method. +info: | + [[Call]] (thisArgument, argumentsList) + + 9. Return Call(trap, handler, «target, thisArgument, argArray»). +features: [Proxy] +---*/ + +var result = {}; +var p = new Proxy(function() { + throw new Test262Error('target should not be called'); +}, { + apply: function(t, c, args) { + return result; + }, +}); + +assert.sameValue(p.call(), result); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/apply/null-handler-realm.js b/js/src/tests/test262/built-ins/Proxy/apply/null-handler-realm.js new file mode 100644 index 0000000000..1b4af39513 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/apply/null-handler-realm.js @@ -0,0 +1,25 @@ +// Copyright (C) 2019 Aleksey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-call-thisargument-argumentslist +description: > + Throws a TypeError exception if handler is null (honoring the realm of the + current execution context). +info: | + [[Call]] (thisArgument, argumentsList) + + 1. Let handler be O.[[ProxyHandler]]. + 2. If handler is null, throw a TypeError exception. +features: [cross-realm, Proxy] +---*/ + +var OProxy = $262.createRealm().global.Proxy; +var p = OProxy.revocable(function() {}, {}); + +p.revoke(); + +assert.throws(TypeError, function() { + p.proxy(); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/apply/null-handler.js b/js/src/tests/test262/built-ins/Proxy/apply/null-handler.js new file mode 100644 index 0000000000..c94729ba1d --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/apply/null-handler.js @@ -0,0 +1,21 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-call-thisargument-argumentslist +description: > + [[Call]] (thisArgument, argumentsList) + + 2. If handler is null, throw a TypeError exception. +features: [Proxy] +---*/ + + +var p = Proxy.revocable(function() {}, {}); + +p.revoke(); + +assert.throws(TypeError, function() { + p.proxy(); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/apply/return-abrupt.js b/js/src/tests/test262/built-ins/Proxy/apply/return-abrupt.js new file mode 100644 index 0000000000..d8641fa809 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/apply/return-abrupt.js @@ -0,0 +1,22 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-call-thisargument-argumentslist +description: > + Return is an abrupt completion +features: [Proxy] +---*/ + +var p = new Proxy(function() { + throw 'not the Test262Error you are looking for'; +}, { + apply: function(t, c, args) { + throw new Test262Error(); + } +}); + +assert.throws(Test262Error, function() { + p.call(); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/apply/shell.js b/js/src/tests/test262/built-ins/Proxy/apply/shell.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/apply/shell.js diff --git a/js/src/tests/test262/built-ins/Proxy/apply/trap-is-missing-target-is-proxy.js b/js/src/tests/test262/built-ins/Proxy/apply/trap-is-missing-target-is-proxy.js new file mode 100644 index 0000000000..35e72dbb8c --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/apply/trap-is-missing-target-is-proxy.js @@ -0,0 +1,28 @@ +// Copyright (C) 2020 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-call-thisargument-argumentslist +description: > + If "apply" trap is null or undefined, [[Call]] is properly + forwarded to [[ProxyTarget]] (which is also a Proxy object). +info: | + [[Call]] ( thisArgument, argumentsList ) + + [...] + 4. Let target be O.[[ProxyTarget]]. + 5. Let trap be ? GetMethod(handler, "apply"). + 6. If trap is undefined, then + a. Return ? Call(target, thisArgument, argumentsList). +features: [Proxy, Reflect] +---*/ + +var hasOwn = Object.prototype.hasOwnProperty; +var hasOwnTarget = new Proxy(hasOwn, {}); +var hasOwnProxy = new Proxy(hasOwnTarget, {}); + +var obj = {foo: 1}; +assert(hasOwnProxy.call(obj, "foo")); +assert(!Reflect.apply(hasOwnProxy, obj, ["bar"])); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/apply/trap-is-not-callable-realm.js b/js/src/tests/test262/built-ins/Proxy/apply/trap-is-not-callable-realm.js new file mode 100644 index 0000000000..4daf79f976 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/apply/trap-is-not-callable-realm.js @@ -0,0 +1,20 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-call-thisargument-argumentslist +description: > + Throws if trap is not callable (honoring the Realm of the current execution + context) +features: [cross-realm, Proxy] +---*/ + +var OProxy = $262.createRealm().global.Proxy; +var p = new OProxy(function() {}, { + apply: {} +}); + +assert.throws(TypeError, function() { + p(); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/apply/trap-is-not-callable.js b/js/src/tests/test262/built-ins/Proxy/apply/trap-is-not-callable.js new file mode 100644 index 0000000000..fd5a57c646 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/apply/trap-is-not-callable.js @@ -0,0 +1,18 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-call-thisargument-argumentslist +description: > + Throws if trap is not callable. +features: [Proxy] +---*/ + +var p = new Proxy(function() {}, { + apply: {} +}); + +assert.throws(TypeError, function() { + p(); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/apply/trap-is-null-target-is-proxy.js b/js/src/tests/test262/built-ins/Proxy/apply/trap-is-null-target-is-proxy.js new file mode 100644 index 0000000000..246fa7f57b --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/apply/trap-is-null-target-is-proxy.js @@ -0,0 +1,33 @@ +// Copyright (C) 2020 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-call-thisargument-argumentslist +description: > + If "apply" trap is null or undefined, [[Call]] is properly + forwarded to [[ProxyTarget]] (which is also a Proxy object). +info: | + [[Call]] ( thisArgument, argumentsList ) + + [...] + 4. Let target be O.[[ProxyTarget]]. + 5. Let trap be ? GetMethod(handler, "apply"). + 6. If trap is undefined, then + a. Return ? Call(target, thisArgument, argumentsList). +features: [Proxy] +---*/ + +var sum = function(a, b) { + return this.foo + a + b; +}; + +var sumBound = sum.bind({foo: 10}, 1); +var sumTarget = new Proxy(sumBound, {}); +var sumProxy = new Proxy(sumTarget, { + apply: null, +}); + +assert.sameValue(sumProxy(2), 13); +assert.sameValue(sumProxy.call({foo: 20}, 3), 14); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/apply/trap-is-null.js b/js/src/tests/test262/built-ins/Proxy/apply/trap-is-null.js new file mode 100644 index 0000000000..b843e97831 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/apply/trap-is-null.js @@ -0,0 +1,47 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-call-thisargument-argumentslist +description: > + If the apply trap value is null, propagate the call to the target object. +info: | + [[Call]] (thisArgument, argumentsList) + + ... + 5. Let trap be ? GetMethod(handler, "apply"). + 6. If trap is undefined, then + a. Return ? Call(target, thisArgument, argumentsList). + ... + + GetMethod ( V, P ) + + ... + 3. If func is either undefined or null, return undefined. + ... +features: [Proxy] +---*/ + +var calls = 0; +var _context; + +var target = new Proxy(function() {}, { + apply: function(_target, context, args) { + calls++; + _context = context; + return args[0] + args[1]; + } +}) + +var p = new Proxy(target, { + apply: null +}); + +var context = {}; +var res = p.call(context, 1, 2); + +assert.sameValue(calls, 1, "apply is null: [[Call]] is invoked once"); +assert.sameValue(_context, context, "apply is null: context is passed to [[Call]]"); +assert.sameValue(res, 3, "apply is null: result of [[Call]] is returned"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/apply/trap-is-undefined-no-property.js b/js/src/tests/test262/built-ins/Proxy/apply/trap-is-undefined-no-property.js new file mode 100644 index 0000000000..bac61d38e8 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/apply/trap-is-undefined-no-property.js @@ -0,0 +1,44 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-call-thisargument-argumentslist +description: > + If trap is not set, propagate the call to the target object. +info: | + [[Call]] (thisArgument, argumentsList) + + ... + 5. Let trap be ? GetMethod(handler, "apply"). + 6. If trap is undefined, then + a. Return ? Call(target, thisArgument, argumentsList). + ... + + GetMethod ( V, P ) + + ... + 3. If func is either undefined or null, return undefined. + ... +features: [Proxy] +---*/ + +var calls = 0; +var _context; + +var target = new Proxy(function() {}, { + apply: function(_target, context, args) { + calls++; + _context = context; + return args[0] + args[1]; + } +}) + +var p = new Proxy(target, {}); +var context = {}; +var res = p.call(context, 1, 2); + +assert.sameValue(calls, 1, "apply is missing: [[Call]] is invoked once"); +assert.sameValue(_context, context, "apply is missing: context is passed to [[Call]]"); +assert.sameValue(res, 3, "apply is missing: result of [[Call]] is returned"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/apply/trap-is-undefined-target-is-proxy.js b/js/src/tests/test262/built-ins/Proxy/apply/trap-is-undefined-target-is-proxy.js new file mode 100644 index 0000000000..bd34cb9a8d --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/apply/trap-is-undefined-target-is-proxy.js @@ -0,0 +1,35 @@ +// Copyright (C) 2020 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-call-thisargument-argumentslist +description: > + If "apply" trap is null or undefined, [[Call]] is properly + forwarded to [[ProxyTarget]] (which is also a Proxy object). +info: | + [[Call]] ( thisArgument, argumentsList ) + + [...] + 4. Let target be O.[[ProxyTarget]]. + 5. Let trap be ? GetMethod(handler, "apply"). + 6. If trap is undefined, then + a. Return ? Call(target, thisArgument, argumentsList). +features: [generators, Proxy, Reflect] +includes: [compareArray.js] +---*/ + +var sum = function* (arg) { + yield this.foo; + yield arg; +}; + +var sumTarget = new Proxy(sum, {}); +var sumProxy = new Proxy(sumTarget, { + apply: undefined, +}); + +var gen = Reflect.apply(sumProxy, {foo: 10}, [1]); + +assert.compareArray(Array.from(gen), [10, 1]); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/apply/trap-is-undefined.js b/js/src/tests/test262/built-ins/Proxy/apply/trap-is-undefined.js new file mode 100644 index 0000000000..7c8b6dae6b --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/apply/trap-is-undefined.js @@ -0,0 +1,47 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-call-thisargument-argumentslist +description: > + If the apply trap value is undefined, propagate the call to the target object. +info: | + [[Call]] (thisArgument, argumentsList) + + ... + 5. Let trap be ? GetMethod(handler, "apply"). + 6. If trap is undefined, then + a. Return ? Call(target, thisArgument, argumentsList). + ... + + GetMethod ( V, P ) + + ... + 3. If func is either undefined or null, return undefined. + ... +features: [Proxy] +---*/ + +var calls = 0; +var _context; + +var target = new Proxy(function() {}, { + apply: function(_target, context, args) { + calls++; + _context = context; + return args[0] + args[1]; + } +}) + +var p = new Proxy(target, { + apply: undefined +}); + +var context = {}; +var res = p.call(context, 1, 2); + +assert.sameValue(calls, 1, "apply is undefined: [[Call]] is invoked once"); +assert.sameValue(_context, context, "apply is undefined: context is passed to [[Call]]"); +assert.sameValue(res, 3, "apply is undefined: result of [[Call]] is returned"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/browser.js b/js/src/tests/test262/built-ins/Proxy/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/browser.js diff --git a/js/src/tests/test262/built-ins/Proxy/construct/arguments-realm.js b/js/src/tests/test262/built-ins/Proxy/construct/arguments-realm.js new file mode 100644 index 0000000000..feb7ec55a0 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/construct/arguments-realm.js @@ -0,0 +1,21 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-construct-argumentslist-newtarget +description: > + Arguments array is created in the Realm of the current execution context +info: | + [...] + 7. Let argArray be CreateArrayFromList(argumentsList). + 8. Let newObj be ? Call(trap, handler, « target, argArray, newTarget »). + [...] +features: [cross-realm] +---*/ + +var C = $262.createRealm().global.eval( + 'new Proxy(function() {}, { construct: function(_, args) { return args; } })' +); + +assert.sameValue(new C().constructor, Array); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/construct/browser.js b/js/src/tests/test262/built-ins/Proxy/construct/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/construct/browser.js diff --git a/js/src/tests/test262/built-ins/Proxy/construct/call-parameters-new-target.js b/js/src/tests/test262/built-ins/Proxy/construct/call-parameters-new-target.js new file mode 100644 index 0000000000..353c4f4092 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/construct/call-parameters-new-target.js @@ -0,0 +1,42 @@ +// Copyright (C) 2017 Aleksey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-construct-argumentslist-newtarget +description: > + trap is called with handler object as its context, and parameters are: + target, an array list with the called arguments and the NewTarget +info: | + [[Construct]] (argumentsList, newTarget) + + 9. Let newObj be Call(trap, handler, «target, argArray, newTarget»). +features: [Proxy, Reflect, Reflect.construct] +---*/ + +function Target() {} + +function NewTarget() {} + +var handler = { + construct: function(target, args, newTarget) { + assert.sameValue(this, handler, "trap context is the handler object"); + assert.sameValue(target, Target, "first parameter is the target object"); + assert.sameValue(args.length, 2, "arguments list contains all construct arguments"); + + var a = args[0]; + var b = args[1]; + assert.sameValue(a, 1, "arguments list has first construct argument"); + assert.sameValue(b, 2, "arguments list has second construct argument"); + assert.sameValue(newTarget, NewTarget, "newTarget is passed as the third parameter"); + + return { + sum: a + b + }; + }, +}; + +var P = new Proxy(Target, handler); +var res = Reflect.construct(P, [1, 2], NewTarget); +assert.sameValue(res.sum, 3); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/construct/call-parameters.js b/js/src/tests/test262/built-ins/Proxy/construct/call-parameters.js new file mode 100644 index 0000000000..cb771c9fb4 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/construct/call-parameters.js @@ -0,0 +1,41 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-construct-argumentslist-newtarget +description: > + trap is called with handler object as its context, and parameters are: + target, an array list with the called arguments and the new target, and the + constructor new.target. +info: | + [[Construct]] ( argumentsList, newTarget) + + 9. Let newObj be Call(trap, handler, «target, argArray, newTarget »). +features: [Proxy] +---*/ + +var _target, _handler, _args, _P; + +function Target() {} + +var handler = { + construct: function(t, args, newTarget) { + _handler = this; + _target = t; + _args = args; + _P = newTarget; + + return new t(args[0], args[1]); + } +}; +var P = new Proxy(Target, handler); + +new P(1, 2); + +assert.sameValue(_handler, handler, "trap context is the handler object"); +assert.sameValue(_target, Target, "first parameter is the target object"); +assert.sameValue(_args.length, 2, "arguments list contains all call arguments"); +assert.sameValue(_args[0], 1, "arguments list has first call argument"); +assert.sameValue(_args[1], 2, "arguments list has second call argument"); +assert.sameValue(_P, P, "constructor is sent as the third parameter"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/construct/call-result.js b/js/src/tests/test262/built-ins/Proxy/construct/call-result.js new file mode 100644 index 0000000000..709016ff62 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/construct/call-result.js @@ -0,0 +1,26 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-construct-argumentslist-newtarget +description: > + Return the result from the trap method. +info: | + [[Construct]] ( argumentsList, newTarget) + + 12. Return newObj +features: [Proxy] +---*/ + +var P = new Proxy(function() { + throw new Test262Error('target should not be called'); +}, { + construct: function(t, c, args) { + return { + sum: 42 + }; + } +}); + +assert.sameValue((new P(1, 2)).sum, 42); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/construct/null-handler-realm.js b/js/src/tests/test262/built-ins/Proxy/construct/null-handler-realm.js new file mode 100644 index 0000000000..a17fb95e33 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/construct/null-handler-realm.js @@ -0,0 +1,22 @@ +// Copyright (C) 2019 Aleksey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-construct-argumentslist-newtarget +description: > + [[Construct]] (argumentsList, newTarget) + + 1. Let handler be O.[[ProxyHandler]]. + 2. If handler is null, throw a TypeError exception. +features: [cross-realm, Proxy] +---*/ + +var OProxy = $262.createRealm().global.Proxy; +var p = OProxy.revocable(function() {}, {}); + +p.revoke(); + +assert.throws(TypeError, function() { + new p.proxy(); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/construct/null-handler.js b/js/src/tests/test262/built-ins/Proxy/construct/null-handler.js new file mode 100644 index 0000000000..90a310e4fd --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/construct/null-handler.js @@ -0,0 +1,21 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-construct-argumentslist-newtarget +description: > + [[Construct]] ( argumentsList, newTarget) + + 2. If handler is null, throw a TypeError exception. +features: [Proxy] +---*/ + + +var p = Proxy.revocable(function() {}, {}); + +p.revoke(); + +assert.throws(TypeError, function() { + new p.proxy(); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/construct/return-is-abrupt.js b/js/src/tests/test262/built-ins/Proxy/construct/return-is-abrupt.js new file mode 100644 index 0000000000..d1b2381407 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/construct/return-is-abrupt.js @@ -0,0 +1,26 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-construct-argumentslist-newtarget +description: > + Return abrupt from constructor call. +info: | + [[Construct]] ( argumentsList, newTarget) + + 9. Let newObj be Call(trap, handler, «target, argArray, newTarget »). + 10. ReturnIfAbrupt(newObj). +features: [Proxy] +---*/ + +function Target() {} +var P = new Proxy(Target, { + construct: function() { + throw new Test262Error(); + } +}); + +assert.throws(Test262Error, function() { + new P(); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/construct/return-not-object-throws-boolean-realm.js b/js/src/tests/test262/built-ins/Proxy/construct/return-not-object-throws-boolean-realm.js new file mode 100644 index 0000000000..fa19b3df39 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/construct/return-not-object-throws-boolean-realm.js @@ -0,0 +1,29 @@ +// Copyright (C) 2019 Aleksey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-construct-argumentslist-newtarget +description: > + Throws a TypeError if trap result is not an Object: Boolean + (honoring the Realm of the current execution context) +info: | + [[Construct]] (argumentsList, newTarget) + + [...] + 11. If Type(newObj) is not Object, throw a TypeError exception. +features: [cross-realm, Proxy] +---*/ + +var OProxy = $262.createRealm().global.Proxy; +var P = new OProxy(function() { + throw new Test262Error('target should not be called'); +}, { + construct: function() { + return true; + }, +}); + +assert.throws(TypeError, function() { + new P(); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/construct/return-not-object-throws-boolean.js b/js/src/tests/test262/built-ins/Proxy/construct/return-not-object-throws-boolean.js new file mode 100644 index 0000000000..f3c6857513 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/construct/return-not-object-throws-boolean.js @@ -0,0 +1,26 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-construct-argumentslist-newtarget +description: > + Throws a TypeError if trap result is not an Object: Boolean +info: | + [[Construct]] ( argumentsList, newTarget) + + 11. If Type(newObj) is not Object, throw a TypeError exception. +features: [Proxy] +---*/ + +var P = new Proxy(function() { + throw new Test262Error('target should not be called'); +}, { + construct: function() { + return true; + } +}); + +assert.throws(TypeError, function() { + new P(); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/construct/return-not-object-throws-null-realm.js b/js/src/tests/test262/built-ins/Proxy/construct/return-not-object-throws-null-realm.js new file mode 100644 index 0000000000..2342dd07b1 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/construct/return-not-object-throws-null-realm.js @@ -0,0 +1,29 @@ +// Copyright (C) 2019 Aleksey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-construct-argumentslist-newtarget +description: > + Throws a TypeError if trap result is not an Object: null + (honoring the Realm of the current execution context) +info: | + [[Construct]] (argumentsList, newTarget) + + [...] + 11. If Type(newObj) is not Object, throw a TypeError exception. +features: [cross-realm, Proxy] +---*/ + +var OProxy = $262.createRealm().global.Proxy; +var P = new OProxy(function() { + throw new Test262Error('target should not be called'); +}, { + construct: function() { + return null; + }, +}); + +assert.throws(TypeError, function() { + new P(); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/construct/return-not-object-throws-null.js b/js/src/tests/test262/built-ins/Proxy/construct/return-not-object-throws-null.js new file mode 100644 index 0000000000..f14da08eba --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/construct/return-not-object-throws-null.js @@ -0,0 +1,27 @@ +// Copyright (C) 2019 Aleksey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-construct-argumentslist-newtarget +description: > + Throws a TypeError if trap result is not an Object: null +info: | + [[Construct]] (argumentsList, newTarget) + + [...] + 11. If Type(newObj) is not Object, throw a TypeError exception. +features: [Proxy] +---*/ + +var P = new Proxy(function() { + throw new Test262Error('target should not be called'); +}, { + construct: function() { + return null; + }, +}); + +assert.throws(TypeError, function() { + new P(); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/construct/return-not-object-throws-number-realm.js b/js/src/tests/test262/built-ins/Proxy/construct/return-not-object-throws-number-realm.js new file mode 100644 index 0000000000..999159287c --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/construct/return-not-object-throws-number-realm.js @@ -0,0 +1,29 @@ +// Copyright (C) 2019 Aleksey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-construct-argumentslist-newtarget +description: > + Throws a TypeError if trap result is not an Object: Number + (honoring the Realm of the current execution context) +info: | + [[Construct]] (argumentsList, newTarget) + + [...] + 11. If Type(newObj) is not Object, throw a TypeError exception. +features: [cross-realm, Proxy] +---*/ + +var OProxy = $262.createRealm().global.Proxy; +var P = new OProxy(function() { + throw new Test262Error('target should not be called'); +}, { + construct: function() { + return 1; + }, +}); + +assert.throws(TypeError, function() { + new P(); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/construct/return-not-object-throws-number.js b/js/src/tests/test262/built-ins/Proxy/construct/return-not-object-throws-number.js new file mode 100644 index 0000000000..bc1c591b28 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/construct/return-not-object-throws-number.js @@ -0,0 +1,26 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-construct-argumentslist-newtarget +description: > + Throws a TypeError if trap result is not an Object: Number +info: | + [[Construct]] ( argumentsList, newTarget) + + 11. If Type(newObj) is not Object, throw a TypeError exception. +features: [Proxy] +---*/ + +var P = new Proxy(function() { + throw new Test262Error('target should not be called'); +}, { + construct: function() { + return 0; + } +}); + +assert.throws(TypeError, function() { + new P(); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/construct/return-not-object-throws-string-realm.js b/js/src/tests/test262/built-ins/Proxy/construct/return-not-object-throws-string-realm.js new file mode 100644 index 0000000000..6d607d7ffb --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/construct/return-not-object-throws-string-realm.js @@ -0,0 +1,29 @@ +// Copyright (C) 2019 Aleksey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-construct-argumentslist-newtarget +description: > + Throws a TypeError if trap result is not an Object: String + (honoring the Realm of the current execution context) +info: | + [[Construct]] (argumentsList, newTarget) + + [...] + 11. If Type(newObj) is not Object, throw a TypeError exception. +features: [cross-realm, Proxy] +---*/ + +var OProxy = $262.createRealm().global.Proxy; +var P = new OProxy(function() { + throw new Test262Error('target should not be called'); +}, { + construct: function() { + return ''; + }, +}); + +assert.throws(TypeError, function() { + new P(); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/construct/return-not-object-throws-string.js b/js/src/tests/test262/built-ins/Proxy/construct/return-not-object-throws-string.js new file mode 100644 index 0000000000..32bb69bfa5 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/construct/return-not-object-throws-string.js @@ -0,0 +1,26 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-construct-argumentslist-newtarget +description: > + Throws a TypeError if trap result is not an Object: String +info: | + [[Construct]] ( argumentsList, newTarget) + + 11. If Type(newObj) is not Object, throw a TypeError exception. +features: [Proxy] +---*/ + +var P = new Proxy(function() { + throw new Test262Error('target should not be called'); +}, { + construct: function() { + return ""; + } +}); + +assert.throws(TypeError, function() { + new P(); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/construct/return-not-object-throws-symbol-realm.js b/js/src/tests/test262/built-ins/Proxy/construct/return-not-object-throws-symbol-realm.js new file mode 100644 index 0000000000..90640df61f --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/construct/return-not-object-throws-symbol-realm.js @@ -0,0 +1,29 @@ +// Copyright (C) 2019 Aleksey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-construct-argumentslist-newtarget +description: > + Throws a TypeError if trap result is not an Object: Symbol + (honoring the Realm of the current execution context) +info: | + [[Construct]] (argumentsList, newTarget) + + [...] + 11. If Type(newObj) is not Object, throw a TypeError exception. +features: [cross-realm, Proxy] +---*/ + +var OProxy = $262.createRealm().global.Proxy; +var P = new OProxy(function() { + throw new Test262Error('target should not be called'); +}, { + construct: function() { + return Symbol(); + }, +}); + +assert.throws(TypeError, function() { + new P(); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/construct/return-not-object-throws-symbol.js b/js/src/tests/test262/built-ins/Proxy/construct/return-not-object-throws-symbol.js new file mode 100644 index 0000000000..857e0b6ae7 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/construct/return-not-object-throws-symbol.js @@ -0,0 +1,26 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-construct-argumentslist-newtarget +description: > + Throws a TypeError if trap result is not an Object: Symbol +info: | + [[Construct]] ( argumentsList, newTarget) + + 11. If Type(newObj) is not Object, throw a TypeError exception. +features: [Proxy, Symbol] +---*/ + +var P = new Proxy(function() { + throw new Test262Error('target should not be called'); +}, { + construct: function() { + return Symbol(); + } +}); + +assert.throws(TypeError, function() { + new P(); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/construct/return-not-object-throws-undefined-realm.js b/js/src/tests/test262/built-ins/Proxy/construct/return-not-object-throws-undefined-realm.js new file mode 100644 index 0000000000..300f9010f6 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/construct/return-not-object-throws-undefined-realm.js @@ -0,0 +1,27 @@ +// Copyright (C) 2019 Aleksey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-construct-argumentslist-newtarget +description: > + Throws a TypeError if trap result is not an Object: undefined + (honoring the Realm of the current execution context) +info: | + [[Construct]] (argumentsList, newTarget) + + [...] + 11. If Type(newObj) is not Object, throw a TypeError exception. +features: [cross-realm, Proxy] +---*/ + +var OProxy = $262.createRealm().global.Proxy; +var P = new OProxy(function() { + throw new Test262Error('target should not be called'); +}, { + construct: function() {}, +}); + +assert.throws(TypeError, function() { + new P(); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/construct/return-not-object-throws-undefined.js b/js/src/tests/test262/built-ins/Proxy/construct/return-not-object-throws-undefined.js new file mode 100644 index 0000000000..dab78c14d6 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/construct/return-not-object-throws-undefined.js @@ -0,0 +1,24 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-construct-argumentslist-newtarget +description: > + Throws a TypeError if trap result is not an Object: undefined +info: | + [[Construct]] ( argumentsList, newTarget) + + 11. If Type(newObj) is not Object, throw a TypeError exception. +features: [Proxy] +---*/ + +var P = new Proxy(function() { + throw new Test262Error('target should not be called'); +}, { + construct: function() {} +}); + +assert.throws(TypeError, function() { + new P(); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/construct/shell.js b/js/src/tests/test262/built-ins/Proxy/construct/shell.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/construct/shell.js diff --git a/js/src/tests/test262/built-ins/Proxy/construct/trap-is-missing-target-is-proxy.js b/js/src/tests/test262/built-ins/Proxy/construct/trap-is-missing-target-is-proxy.js new file mode 100644 index 0000000000..08b9fc06a9 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/construct/trap-is-missing-target-is-proxy.js @@ -0,0 +1,40 @@ +// Copyright (C) 2020 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-construct-argumentslist-newtarget +description: > + If "construct" trap is null or undefined, [[Construct]] call is + properly forwarded to [[ProxyTarget]] (which is also a Proxy object). +info: | + [[Construct]] ( argumentsList, newTarget ) + + [...] + 4. Let target be O.[[ProxyTarget]]. + 5. Assert: IsConstructor(target) is true. + 6. Let trap be ? GetMethod(handler, "construct"). + 7. If trap is undefined, then + a. Return ? Construct(target, argumentsList, newTarget). +features: [class, Proxy, Reflect, Reflect.construct] +includes: [compareArray.js] +---*/ + +var ArrayTarget = new Proxy(Array, {}); +var ArrayProxy = new Proxy(ArrayTarget, {}); + +var array = new ArrayProxy(1, 2, 3); +assert(Array.isArray(array)); +assert.compareArray(array, [1, 2, 3]); + +class MyArray extends Array { + get isMyArray() { + return true; + } +} + +var myArray = Reflect.construct(ArrayProxy, [], MyArray); +assert(Array.isArray(myArray)); +assert(myArray instanceof MyArray); +assert(myArray.isMyArray); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/construct/trap-is-not-callable-realm.js b/js/src/tests/test262/built-ins/Proxy/construct/trap-is-not-callable-realm.js new file mode 100644 index 0000000000..c93e0b0bbb --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/construct/trap-is-not-callable-realm.js @@ -0,0 +1,20 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-construct-argumentslist-newtarget +description: > + Throws if trap is not callable (honoring the Realm of the current execution + context) +features: [cross-realm, Proxy] +---*/ + +var OProxy = $262.createRealm().global.Proxy; +var p = new OProxy(function() {}, { + construct: {} +}); + +assert.throws(TypeError, function() { + new p(); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/construct/trap-is-not-callable.js b/js/src/tests/test262/built-ins/Proxy/construct/trap-is-not-callable.js new file mode 100644 index 0000000000..acb58e6dd1 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/construct/trap-is-not-callable.js @@ -0,0 +1,19 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-construct-argumentslist-newtarget +description: > + Throws if trap is not callable. +features: [Proxy] +---*/ + +function Target() {} +var p = new Proxy(Target, { + construct: {} +}); + +assert.throws(TypeError, function() { + new p(); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/construct/trap-is-null-target-is-proxy.js b/js/src/tests/test262/built-ins/Proxy/construct/trap-is-null-target-is-proxy.js new file mode 100644 index 0000000000..7cdaa8c741 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/construct/trap-is-null-target-is-proxy.js @@ -0,0 +1,47 @@ +// Copyright (C) 2020 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-construct-argumentslist-newtarget +description: > + If "construct" trap is null or undefined, [[Construct]] call is + properly forwarded to [[ProxyTarget]] (which is also a Proxy object). +info: | + [[Construct]] ( argumentsList, newTarget ) + + [...] + 4. Let target be O.[[ProxyTarget]]. + 5. Assert: IsConstructor(target) is true. + 6. Let trap be ? GetMethod(handler, "construct"). + 7. If trap is undefined, then + a. Return ? Construct(target, argumentsList, newTarget). +features: [class, Proxy, Reflect, Reflect.construct] +---*/ + +class Foo { + constructor(arg) { + this.arg = arg; + } +} + +var FooTarget = new Proxy(Foo, {}); +var FooProxy = new Proxy(FooTarget, { + construct: null, +}); + +var foo = new FooProxy(1); +assert(foo instanceof Foo); +assert.sameValue(foo.arg, 1); + +class Bar extends Foo { + get isBar() { + return true; + } +} + +var bar = Reflect.construct(FooProxy, [2], Bar); +assert(bar instanceof Bar); +assert.sameValue(bar.arg, 2); +assert(bar.isBar); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/construct/trap-is-null.js b/js/src/tests/test262/built-ins/Proxy/construct/trap-is-null.js new file mode 100644 index 0000000000..962e97c0f0 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/construct/trap-is-null.js @@ -0,0 +1,52 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-construct-argumentslist-newtarget +description: > + If the construct trap value is null, propagate the construct to the target object. +info: | + [[Construct]] (argumentsList, newTarget) + + ... + 5. Let trap be ? GetMethod(handler, "construct"). + 6. If trap is undefined, then + a. Assert: target has a [[Construct]] internal method. + b. Return ? Construct(target, argumentsList, newTarget). + ... + + GetMethod ( V, P ) + + ... + 3. If func is either undefined or null, return undefined. + ... +features: [Proxy, Reflect, Reflect.construct] +---*/ + +var calls = 0; +var _NewTarget; + +var Target = new Proxy(function() { + throw new Test262Error('target should not be called'); +}, { + construct: function(_Target, args, NewTarget) { + calls += 1; + _NewTarget = NewTarget; + return { + sum: args[0] + args[1] + }; + } +}) + +var P = new Proxy(Target, { + construct: null +}); + +var NewTarget = function() {}; +var obj = Reflect.construct(P, [3, 4], NewTarget); + +assert.sameValue(calls, 1, "construct is null: [[Construct]] is invoked once"); +assert.sameValue(_NewTarget, NewTarget, "construct is null: NewTarget is passed to [[Construct]]"); +assert.sameValue(obj.sum, 7, "construct is null: result of [[Construct]] is returned"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/construct/trap-is-undefined-no-property.js b/js/src/tests/test262/built-ins/Proxy/construct/trap-is-undefined-no-property.js new file mode 100644 index 0000000000..5a5204cd6a --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/construct/trap-is-undefined-no-property.js @@ -0,0 +1,48 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-construct-argumentslist-newtarget +description: > + If the construct trap is not set, propagate the construct to the target object. +info: | + [[Construct]] (argumentsList, newTarget) + + ... + 5. Let trap be ? GetMethod(handler, "construct"). + 6. If trap is undefined, then + a. Assert: target has a [[Construct]] internal method. + b. Return ? Construct(target, argumentsList, newTarget). + ... + + GetMethod ( V, P ) + + ... + 3. If func is either undefined or null, return undefined. + ... +features: [Proxy, Reflect, Reflect.construct] +---*/ + +var calls = 0; +var _NewTarget; + +var Target = new Proxy(function() { + throw new Test262Error('target should not be called'); +}, { + construct: function(_Target, args, NewTarget) { + calls += 1; + _NewTarget = NewTarget; + return { + sum: args[0] + args[1] + }; + } +}) + +var P = new Proxy(Target, {}); +var NewTarget = function() {}; +var obj = Reflect.construct(P, [3, 4], NewTarget); + +assert.sameValue(calls, 1, "construct is missing: [[Construct]] is invoked once"); +assert.sameValue(_NewTarget, NewTarget, "construct is missing: NewTarget is passed to [[Construct]]"); +assert.sameValue(obj.sum, 7, "construct is missing: result of [[Construct]] is returned"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/construct/trap-is-undefined-proto-from-cross-realm-newtarget.js b/js/src/tests/test262/built-ins/Proxy/construct/trap-is-undefined-proto-from-cross-realm-newtarget.js new file mode 100644 index 0000000000..04834fdb5f --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/construct/trap-is-undefined-proto-from-cross-realm-newtarget.js @@ -0,0 +1,49 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-construct-argumentslist-newtarget +description: > + If trap is undefined, propagate [[Construct]] to target, + passing correct newTarget parameter +info: | + [[Construct]] ( argumentsList, newTarget ) + + [...] + 7. If trap is undefined, then + b. Return ? Construct(target, argumentsList, newTarget). + + Construct ( F [ , argumentsList [ , newTarget ] ] ) + + [...] + 5. Return ? F.[[Construct]](argumentsList, newTarget). + + [[Construct]] ( argumentsList, newTarget ) + + [...] + 5. If kind is "base", then + a. Let thisArgument be ? OrdinaryCreateFromConstructor(newTarget, "%ObjectPrototype%"). + + OrdinaryCreateFromConstructor ( constructor, intrinsicDefaultProto [ , internalSlotsList ] ) + + [...] + 2. Let proto be ? GetPrototypeFromConstructor(constructor, intrinsicDefaultProto). + 3. Return ObjectCreate(proto, internalSlotsList). + + GetPrototypeFromConstructor ( constructor, intrinsicDefaultProto ) + + [...] + 3. Let proto be ? Get(constructor, "prototype"). + [...] + 5. Return proto. +features: [cross-realm, Proxy, Reflect, Reflect.construct] +---*/ + +var other = $262.createRealm().global; +var C = new other.Function(); + +var P = new Proxy(function() {}, {}); +var p = Reflect.construct(P, [], C); + +assert.sameValue(Object.getPrototypeOf(p), C.prototype); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/construct/trap-is-undefined-proto-from-newtarget-realm.js b/js/src/tests/test262/built-ins/Proxy/construct/trap-is-undefined-proto-from-newtarget-realm.js new file mode 100644 index 0000000000..dd96640ce5 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/construct/trap-is-undefined-proto-from-newtarget-realm.js @@ -0,0 +1,58 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-construct-argumentslist-newtarget +description: > + If trap is undefined, propagate [[Construct]] to target, + passing correct newTarget parameter +info: | + [[Construct]] ( argumentsList, newTarget ) + + [...] + 7. If trap is undefined, then + b. Return ? Construct(target, argumentsList, newTarget). + + Construct ( F [ , argumentsList [ , newTarget ] ] ) + + [...] + 5. Return ? F.[[Construct]](argumentsList, newTarget). + + [[Construct]] ( argumentsList, newTarget ) + + [...] + 5. If kind is "base", then + a. Let thisArgument be ? OrdinaryCreateFromConstructor(newTarget, "%ObjectPrototype%"). + + OrdinaryCreateFromConstructor ( constructor, intrinsicDefaultProto [ , internalSlotsList ] ) + + [...] + 2. Let proto be ? GetPrototypeFromConstructor(constructor, intrinsicDefaultProto). + 3. Return ObjectCreate(proto, internalSlotsList). + + GetPrototypeFromConstructor ( constructor, intrinsicDefaultProto ) + + [...] + 3. Let proto be ? Get(constructor, "prototype"). + 4. If Type(proto) is not Object, then + a. Let realm be ? GetFunctionRealm(constructor). + b. Set proto to realm's intrinsic object named intrinsicDefaultProto. + 5. Return proto. + + GetFunctionRealm ( obj ) + + [...] + 2. If obj has a [[Realm]] internal slot, then + a. Return obj.[[Realm]]. +features: [cross-realm, Proxy, Reflect, Reflect.construct] +---*/ + +var other = $262.createRealm().global; +var C = new other.Function(); +C.prototype = null; + +var P = new Proxy(function() {}, {}); +var p = Reflect.construct(P, [], C); + +assert.sameValue(Object.getPrototypeOf(p), other.Object.prototype); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/construct/trap-is-undefined-target-is-proxy.js b/js/src/tests/test262/built-ins/Proxy/construct/trap-is-undefined-target-is-proxy.js new file mode 100644 index 0000000000..068159253c --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/construct/trap-is-undefined-target-is-proxy.js @@ -0,0 +1,48 @@ +// Copyright (C) 2020 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-construct-argumentslist-newtarget +description: > + If "construct" trap is null or undefined, [[Construct]] call is + properly forwarded to [[ProxyTarget]] (which is also a Proxy object). +info: | + [[Construct]] ( argumentsList, newTarget ) + + [...] + 4. Let target be O.[[ProxyTarget]]. + 5. Assert: IsConstructor(target) is true. + 6. Let trap be ? GetMethod(handler, "construct"). + 7. If trap is undefined, then + a. Return ? Construct(target, argumentsList, newTarget). +features: [class, Proxy, Reflect, Reflect.construct] +---*/ + +class Foo { + constructor(a, b) { + this.sum = a + b; + } +} + +var FooBound = Foo.bind(null, 1); +var FooTarget = new Proxy(FooBound, {}); +var FooProxy = new Proxy(FooTarget, { + construct: undefined, +}); + +var foo = new FooBound(2); +assert(foo instanceof Foo); +assert.sameValue(foo.sum, 3); + +class Bar extends Foo { + get isBar() { + return true; + } +} + +var bar = Reflect.construct(FooProxy, [3], Bar); +assert(bar instanceof Bar); +assert.sameValue(bar.sum, 4); +assert(bar.isBar); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/construct/trap-is-undefined.js b/js/src/tests/test262/built-ins/Proxy/construct/trap-is-undefined.js new file mode 100644 index 0000000000..5682638564 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/construct/trap-is-undefined.js @@ -0,0 +1,52 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-construct-argumentslist-newtarget +description: > + If the construct trap value is undefined, propagate the construct to the target object. +info: | + [[Construct]] (argumentsList, newTarget) + + ... + 5. Let trap be ? GetMethod(handler, "construct"). + 6. If trap is undefined, then + a. Assert: target has a [[Construct]] internal method. + b. Return ? Construct(target, argumentsList, newTarget). + ... + + GetMethod ( V, P ) + + ... + 3. If func is either undefined or null, return undefined. + ... +features: [Proxy, Reflect, Reflect.construct] +---*/ + +var calls = 0; +var _NewTarget; + +var Target = new Proxy(function() { + throw new Test262Error('target should not be called'); +}, { + construct: function(_Target, args, NewTarget) { + calls += 1; + _NewTarget = NewTarget; + return { + sum: args[0] + args[1] + }; + }, +}); + +var P = new Proxy(Target, { + construct: undefined +}); + +var NewTarget = function() {}; +var obj = Reflect.construct(P, [3, 4], NewTarget); + +assert.sameValue(calls, 1, "construct is undefined: [[Construct]] is invoked once"); +assert.sameValue(_NewTarget, NewTarget, "construct is undefined: NewTarget is passed to [[Construct]]"); +assert.sameValue(obj.sum, 7, "construct is undefined: result of [[Construct]] is returned"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/constructor.js b/js/src/tests/test262/built-ins/Proxy/constructor.js new file mode 100644 index 0000000000..d6639ef80d --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/constructor.js @@ -0,0 +1,13 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 26.2.1 +description: > + The Proxy constructor is the %Proxy% intrinsic object and the + initial value of the Proxy property of the global object. +features: [Proxy] +---*/ + +assert.sameValue(typeof Proxy, "function", "`typeof Proxy` is `'function'`"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/create-handler-is-revoked-proxy.js b/js/src/tests/test262/built-ins/Proxy/create-handler-is-revoked-proxy.js new file mode 100644 index 0000000000..3ff7add338 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/create-handler-is-revoked-proxy.js @@ -0,0 +1,24 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxycreate +description: > + A Proxy is created with its [[ProxyHandler]] as revoked Proxy. +info: | + ProxyCreate ( target, handler ) + + [...] + 3. Let P be ! MakeBasicObject(« [[ProxyHandler]], [[ProxyTarget]] »). + [...] + 7. Set P.[[ProxyHandler]] to handler. + 8. Return P. +features: [Proxy] +---*/ + +var revocable = Proxy.revocable({}, {}); +revocable.revoke(); + +var proxy = new Proxy({}, revocable.proxy); +assert.sameValue(typeof proxy, "object"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/create-handler-not-object-throw-boolean.js b/js/src/tests/test262/built-ins/Proxy/create-handler-not-object-throw-boolean.js new file mode 100644 index 0000000000..69e05343b5 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/create-handler-not-object-throw-boolean.js @@ -0,0 +1,17 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.15 +description: > + Proxy ( target, handler ) + ... + 3. If Type(handler) is not Object, throw a TypeError exception. + ... +features: [Proxy] +---*/ + +assert.throws(TypeError, function() { + new Proxy({}, false); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/create-handler-not-object-throw-null.js b/js/src/tests/test262/built-ins/Proxy/create-handler-not-object-throw-null.js new file mode 100644 index 0000000000..99cef1747d --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/create-handler-not-object-throw-null.js @@ -0,0 +1,17 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.15 +description: > + Proxy ( target, handler ) + ... + 3. If Type(handler) is not Object, throw a TypeError exception. + ... +features: [Proxy] +---*/ + +assert.throws(TypeError, function() { + new Proxy({}, null); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/create-handler-not-object-throw-number.js b/js/src/tests/test262/built-ins/Proxy/create-handler-not-object-throw-number.js new file mode 100644 index 0000000000..ee25fb2ff0 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/create-handler-not-object-throw-number.js @@ -0,0 +1,17 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.15 +description: > + Proxy ( target, handler ) + ... + 3. If Type(handler) is not Object, throw a TypeError exception. + ... +features: [Proxy] +---*/ + +assert.throws(TypeError, function() { + new Proxy({}, 0); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/create-handler-not-object-throw-string.js b/js/src/tests/test262/built-ins/Proxy/create-handler-not-object-throw-string.js new file mode 100644 index 0000000000..83b0f88761 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/create-handler-not-object-throw-string.js @@ -0,0 +1,17 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.15 +description: > + Proxy ( target, handler ) + ... + 3. If Type(handler) is not Object, throw a TypeError exception. + ... +features: [Proxy] +---*/ + +assert.throws(TypeError, function() { + new Proxy({}, ""); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/create-handler-not-object-throw-symbol.js b/js/src/tests/test262/built-ins/Proxy/create-handler-not-object-throw-symbol.js new file mode 100644 index 0000000000..213003a555 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/create-handler-not-object-throw-symbol.js @@ -0,0 +1,17 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.15 +description: > + Proxy ( target, handler ) + ... + 3. If Type(handler) is not Object, throw a TypeError exception. + ... +features: [Proxy, Symbol] +---*/ + +assert.throws(TypeError, function() { + new Proxy({}, Symbol()); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/create-handler-not-object-throw-undefined.js b/js/src/tests/test262/built-ins/Proxy/create-handler-not-object-throw-undefined.js new file mode 100644 index 0000000000..92b6e74197 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/create-handler-not-object-throw-undefined.js @@ -0,0 +1,17 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.15 +description: > + Proxy ( target, handler ) + ... + 3. If Type(handler) is not Object, throw a TypeError exception. + ... +features: [Proxy] +---*/ + +assert.throws(TypeError, function() { + new Proxy({}, undefined); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/create-target-is-not-a-constructor.js b/js/src/tests/test262/built-ins/Proxy/create-target-is-not-a-constructor.js new file mode 100644 index 0000000000..2bd3fe46c5 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/create-target-is-not-a-constructor.js @@ -0,0 +1,33 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxycreate +description: > + A Proxy exotic object only accepts a constructor call if target is + constructor. +info: | + ProxyCreate ( target, handler ) + + If IsCallable(target) is true, then + Set P.[[Call]] as specified in 9.5.12. + If IsConstructor(target) is true, then + Set P.[[Construct]] as specified in 9.5.13. + ... + + Runtime Semantics: EvaluateNew(constructProduction, arguments) + + 8. If IsConstructor (constructor) is false, throw a TypeError exception. +includes: [isConstructor.js] +features: [Proxy, Reflect.construct, arrow-function] +---*/ + +var proxy = new Proxy(eval, {}); + +proxy(); // the Proxy object is callable + +assert.sameValue(isConstructor(proxy), false, 'isConstructor(proxy) must return false'); +assert.throws(TypeError, () => { + new proxy(); +}, '`new proxy()` throws TypeError'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/create-target-is-not-callable.js b/js/src/tests/test262/built-ins/Proxy/create-target-is-not-callable.js new file mode 100644 index 0000000000..2a6b35dc83 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/create-target-is-not-callable.js @@ -0,0 +1,28 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxycreate +description: > + A Proxy exotic object is only callable if the given target is callable. +info: | + Proxy ( target, handler ) + + 7. If IsCallable(target) is true, then + a. Set the [[Call]] internal method of P as specified in 9.5.13. + ... + + + 12.3.4.3 Runtime Semantics: EvaluateDirectCall( func, thisValue, arguments, + tailPosition ) + + 4. If IsCallable(func) is false, throw a TypeError exception. +features: [Proxy] +---*/ + +var p = new Proxy({}, {}); + +assert.throws(TypeError, function() { + p(); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/create-target-is-revoked-function-proxy.js b/js/src/tests/test262/built-ins/Proxy/create-target-is-revoked-function-proxy.js new file mode 100644 index 0000000000..52272af480 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/create-target-is-revoked-function-proxy.js @@ -0,0 +1,25 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxycreate +description: > + A Proxy is created with its [[ProxyTarget]] as revoked function Proxy. +info: | + ProxyCreate ( target, handler ) + + [...] + 3. Let P be ! MakeBasicObject(« [[ProxyHandler]], [[ProxyTarget]] »). + [...] + 6. Set P.[[ProxyTarget]] to target. + [...] + 8. Return P. +features: [Proxy] +---*/ + +var revocable = Proxy.revocable(function() {}, {}); +revocable.revoke(); + +var proxy = new Proxy(revocable.proxy, {}); +assert.sameValue(typeof proxy, "function"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/create-target-is-revoked-proxy.js b/js/src/tests/test262/built-ins/Proxy/create-target-is-revoked-proxy.js new file mode 100644 index 0000000000..4128ff4f86 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/create-target-is-revoked-proxy.js @@ -0,0 +1,25 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxycreate +description: > + A Proxy is created with its [[ProxyTarget]] as revoked Proxy. +info: | + ProxyCreate ( target, handler ) + + [...] + 3. Let P be ! MakeBasicObject(« [[ProxyHandler]], [[ProxyTarget]] »). + [...] + 6. Set P.[[ProxyTarget]] to target. + [...] + 8. Return P. +features: [Proxy] +---*/ + +var revocable = Proxy.revocable({}, {}); +revocable.revoke(); + +var proxy = new Proxy(revocable.proxy, {}); +assert.sameValue(typeof proxy, "object"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/create-target-not-object-throw-boolean.js b/js/src/tests/test262/built-ins/Proxy/create-target-not-object-throw-boolean.js new file mode 100644 index 0000000000..ccfc26a98f --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/create-target-not-object-throw-boolean.js @@ -0,0 +1,17 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.15 +description: > + Proxy ( target, handler ) + ... + 1. If Type(target) is not Object, throw a TypeError exception. + ... +features: [Proxy] +---*/ + +assert.throws(TypeError, function() { + new Proxy(false, {}); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/create-target-not-object-throw-null.js b/js/src/tests/test262/built-ins/Proxy/create-target-not-object-throw-null.js new file mode 100644 index 0000000000..2c1bb2199c --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/create-target-not-object-throw-null.js @@ -0,0 +1,17 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.15 +description: > + Proxy ( target, handler ) + ... + 1. If Type(target) is not Object, throw a TypeError exception. + ... +features: [Proxy] +---*/ + +assert.throws(TypeError, function() { + new Proxy(null, {}); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/create-target-not-object-throw-number.js b/js/src/tests/test262/built-ins/Proxy/create-target-not-object-throw-number.js new file mode 100644 index 0000000000..26d91b62eb --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/create-target-not-object-throw-number.js @@ -0,0 +1,17 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.15 +description: > + Proxy ( target, handler ) + ... + 1. If Type(target) is not Object, throw a TypeError exception. + ... +features: [Proxy] +---*/ + +assert.throws(TypeError, function() { + new Proxy(0, {}); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/create-target-not-object-throw-string.js b/js/src/tests/test262/built-ins/Proxy/create-target-not-object-throw-string.js new file mode 100644 index 0000000000..2211d96671 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/create-target-not-object-throw-string.js @@ -0,0 +1,17 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.15 +description: > + Proxy ( target, handler ) + ... + 1. If Type(target) is not Object, throw a TypeError exception. + ... +features: [Proxy] +---*/ + +assert.throws(TypeError, function() { + new Proxy("", {}); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/create-target-not-object-throw-symbol.js b/js/src/tests/test262/built-ins/Proxy/create-target-not-object-throw-symbol.js new file mode 100644 index 0000000000..9f3d686595 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/create-target-not-object-throw-symbol.js @@ -0,0 +1,17 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.15 +description: > + Proxy ( target, handler ) + ... + 1. If Type(target) is not Object, throw a TypeError exception. + ... +features: [Proxy, Symbol] +---*/ + +assert.throws(TypeError, function() { + new Proxy(Symbol(), {}); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/create-target-not-object-throw-undefined.js b/js/src/tests/test262/built-ins/Proxy/create-target-not-object-throw-undefined.js new file mode 100644 index 0000000000..3893c95fe8 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/create-target-not-object-throw-undefined.js @@ -0,0 +1,17 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.15 +description: > + Proxy ( target, handler ) + ... + 1. If Type(target) is not Object, throw a TypeError exception. + ... +features: [Proxy] +---*/ + +assert.throws(TypeError, function() { + new Proxy(undefined, {}); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/defineProperty/browser.js b/js/src/tests/test262/built-ins/Proxy/defineProperty/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/defineProperty/browser.js diff --git a/js/src/tests/test262/built-ins/Proxy/defineProperty/call-parameters.js b/js/src/tests/test262/built-ins/Proxy/defineProperty/call-parameters.js new file mode 100644 index 0000000000..2675515d04 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/defineProperty/call-parameters.js @@ -0,0 +1,55 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.6 +description: > + Trap is called with handler as context and parameters are target, P, and the + descriptor object. +info: | + [[DefineOwnProperty]] (P, Desc) + + ... + 9. Let descObj be FromPropertyDescriptor(Desc). + 10. Let booleanTrapResult be ToBoolean(Call(trap, handler, «target, P, + descObj»)). + ... +features: [Proxy] +---*/ + +var _handler, _target, _prop, _desc; +var target = {}; +var descriptor = { + configurable: true, + enumerable: true, + writable: true, + value: 1 +}; +var handler = { + defineProperty: function(t, prop, desc) { + _handler = this; + _target = t; + _prop = prop; + _desc = desc; + + return true; + } +}; +var p = new Proxy(target, handler); + +Object.defineProperty(p, "attr", descriptor); + +assert.sameValue(_handler, handler); +assert.sameValue(_target, target); +assert.sameValue(_prop, "attr"); + +assert.sameValue( + Object.keys(_desc).length, 4, + "descriptor arg has the same amount of keys as given descriptor" +); + +assert(_desc.configurable); +assert(_desc.writable); +assert(_desc.enumerable); +assert.sameValue(_desc.value, 1); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/defineProperty/desc-realm.js b/js/src/tests/test262/built-ins/Proxy/defineProperty/desc-realm.js new file mode 100644 index 0000000000..1e74848fd8 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/defineProperty/desc-realm.js @@ -0,0 +1,39 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-defineownproperty-p-desc +description: > + Property descriptor object is created in the Realm of the current execution + context +info: | + [[DefineOwnProperty]] (P, Desc) + + ... + 8. Let descObj be FromPropertyDescriptor(Desc). + 9. Let booleanTrapResult be ToBoolean(? Call(trap, handler, « target, P, + descObj »)). + ... + + 6.2.4.4 FromPropertyDescriptor + + ... + 2. Let obj be ObjectCreate(%ObjectPrototype%). + ... + 11. Return obj. +features: [cross-realm, Proxy] +---*/ + +var OProxy = $262.createRealm().global.Proxy; +var desc; +var p = new OProxy({}, { + defineProperty: function(_, __, _desc) { + desc = _desc; + return desc; + } +}); + +p.a = 0; + +assert.sameValue(Object.getPrototypeOf(desc), Object.prototype); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/defineProperty/null-handler-realm.js b/js/src/tests/test262/built-ins/Proxy/defineProperty/null-handler-realm.js new file mode 100644 index 0000000000..d3eccc12a0 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/defineProperty/null-handler-realm.js @@ -0,0 +1,24 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-defineownproperty-p-desc +description: > + Throws a TypeError exception if handler is null (honoring the realm of the + current execution context). +info: | + 1. Assert: IsPropertyKey(P) is true. + 2. Let handler be O.[[ProxyHandler]]. + 3. If handler is null, throw a TypeError exception. +features: [cross-realm, Proxy] +---*/ + +var OProxy = $262.createRealm().global.Proxy; +var p = OProxy.revocable(Object.create(null), {}); + +p.revoke(); + +assert.throws(TypeError, function() { + p.proxy.prop = null; +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/defineProperty/null-handler.js b/js/src/tests/test262/built-ins/Proxy/defineProperty/null-handler.js new file mode 100644 index 0000000000..7954d60a79 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/defineProperty/null-handler.js @@ -0,0 +1,21 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.6 +description: > + Throws a TypeError exception if handler is null. +features: [Proxy] +---*/ + +var p = Proxy.revocable({}, {}); + +p.revoke(); + +assert.throws(TypeError, function() { + Object.defineProperty(p.proxy, "foo", { + configurable: true, + enumerable: true + }); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/defineProperty/return-boolean-and-define-target.js b/js/src/tests/test262/built-ins/Proxy/defineProperty/return-boolean-and-define-target.js new file mode 100644 index 0000000000..51d25a03fa --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/defineProperty/return-boolean-and-define-target.js @@ -0,0 +1,48 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.6 +description: > + If a property has a corresponding target object property then applying the + Property Descriptor of the property to the target object using + [[DefineOwnProperty]] will not throw an exception. +features: [Proxy, Reflect] +includes: [propertyHelper.js] +---*/ + +var target = {}; +var p = new Proxy(target, { + defineProperty: function(t, prop, desc) { + return Object.defineProperty(t, prop, desc); + } +}); + +var result = Reflect.defineProperty(p, "attr", { + configurable: true, + enumerable: true, + writable: true, + value: 1 +}); + +assert.sameValue(result, true, "result === true"); + +verifyEqualTo(target, "attr", 1); +verifyWritable(target, "attr"); +verifyEnumerable(target, "attr"); +verifyConfigurable(target, "attr"); + +result = Reflect.defineProperty(p, "attr", { + configurable: false, + enumerable: false, + writable: false, + value: 2 +}); + +assert.sameValue(result, true, "result === true"); + +verifyEqualTo(target, "attr", 2); +verifyNotWritable(target, "attr"); +verifyNotEnumerable(target, "attr"); +verifyNotConfigurable(target, "attr"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/defineProperty/return-is-abrupt.js b/js/src/tests/test262/built-ins/Proxy/defineProperty/return-is-abrupt.js new file mode 100644 index 0000000000..bec126df89 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/defineProperty/return-is-abrupt.js @@ -0,0 +1,28 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.6 +description: > + Trap return is an abrupt. +info: | + [[DefineOwnProperty]] (P, Desc) + + ... + 10. Let booleanTrapResult be ToBoolean(Call(trap, handler, «target, P, + descObj»)). + 11. ReturnIfAbrupt(booleanTrapResult). + ... +features: [Proxy] +---*/ + +var p = new Proxy({}, { + defineProperty: function(t, prop, desc) { + throw new Test262Error(); + } +}); + +assert.throws(Test262Error, function() { + Object.defineProperty(p, "foo", {}); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/defineProperty/shell.js b/js/src/tests/test262/built-ins/Proxy/defineProperty/shell.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/defineProperty/shell.js diff --git a/js/src/tests/test262/built-ins/Proxy/defineProperty/targetdesc-configurable-desc-not-configurable-realm.js b/js/src/tests/test262/built-ins/Proxy/defineProperty/targetdesc-configurable-desc-not-configurable-realm.js new file mode 100644 index 0000000000..de3242c184 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/defineProperty/targetdesc-configurable-desc-not-configurable-realm.js @@ -0,0 +1,40 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-defineownproperty-p-desc +description: > + Throw a TypeError exception if Desc is not configurable and target property + descriptor is configurable and trap result is true (honoring the realm of + the current execution context). +info: | + [[DefineOwnProperty]] (P, Desc) + + ... + 20. Else targetDesc is not undefined, + b. If settingConfigFalse is true and targetDesc.[[Configurable]] is + true, throw a TypeError exception. + ... +features: [cross-realm, Proxy] +---*/ + +var OProxy = $262.createRealm().global.Proxy; +var target = Object.create(null); +var p = new OProxy(target, { + defineProperty: function() { + return true; + } +}); + +Object.defineProperty(target, 'prop', { + value: 1, + configurable: true +}); + +assert.throws(TypeError, function() { + Object.defineProperty(p, 'prop', { + value: 1, + configurable: false + }); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/defineProperty/targetdesc-configurable-desc-not-configurable.js b/js/src/tests/test262/built-ins/Proxy/defineProperty/targetdesc-configurable-desc-not-configurable.js new file mode 100644 index 0000000000..1e5a27273d --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/defineProperty/targetdesc-configurable-desc-not-configurable.js @@ -0,0 +1,38 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.6 +description: > + Throw a TypeError exception if Desc is not configurable and target property + descriptor is configurable and trap result is true. +info: | + [[DefineOwnProperty]] (P, Desc) + + ... + 20. Else targetDesc is not undefined, + b. If settingConfigFalse is true and targetDesc.[[Configurable]] is + true, throw a TypeError exception. + ... +features: [Proxy] +---*/ + +var target = {}; +var p = new Proxy(target, { + defineProperty: function(t, prop, desc) { + return true; + } +}); + +Object.defineProperty(target, "foo", { + value: 1, + configurable: true +}); + +assert.throws(TypeError, function() { + Object.defineProperty(p, "foo", { + value: 1, + configurable: false + }); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/defineProperty/targetdesc-not-compatible-descriptor-not-configurable-target-realm.js b/js/src/tests/test262/built-ins/Proxy/defineProperty/targetdesc-not-compatible-descriptor-not-configurable-target-realm.js new file mode 100644 index 0000000000..7daad2f400 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/defineProperty/targetdesc-not-compatible-descriptor-not-configurable-target-realm.js @@ -0,0 +1,39 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-defineownproperty-p-desc +description: > + Throw a TypeError exception if Desc and target property descriptor are not + compatible and trap result is true. +info: | + [[DefineOwnProperty]] (P, Desc) + + ... + 20. Else targetDesc is not undefined, + a. If IsCompatiblePropertyDescriptor(extensibleTarget, Desc , + targetDesc) is false, throw a TypeError exception. + ... +features: [cross-realm, Proxy] +---*/ + +var OProxy = $262.createRealm().global.Proxy; +var target = Object.create(null); +var p = new OProxy(target, { + defineProperty: function() { + return true; + } +}); + +Object.defineProperty(target, 'prop', { + value: 1, + configurable: false +}); + +assert.throws(TypeError, function() { + Object.defineProperty(p, 'prop', { + value: 1, + configurable: true + }); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/defineProperty/targetdesc-not-compatible-descriptor-not-configurable-target.js b/js/src/tests/test262/built-ins/Proxy/defineProperty/targetdesc-not-compatible-descriptor-not-configurable-target.js new file mode 100644 index 0000000000..c23e63cd9f --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/defineProperty/targetdesc-not-compatible-descriptor-not-configurable-target.js @@ -0,0 +1,38 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.6 +description: > + Throw a TypeError exception if Desc and target property descriptor are not + compatible and trap result is true. +info: | + [[DefineOwnProperty]] (P, Desc) + + ... + 20. Else targetDesc is not undefined, + a. If IsCompatiblePropertyDescriptor(extensibleTarget, Desc , + targetDesc) is false, throw a TypeError exception. + ... +features: [Proxy] +---*/ + +var target = {}; +var p = new Proxy(target, { + defineProperty: function(t, prop, desc) { + return true; + } +}); + +Object.defineProperty(target, "foo", { + value: 1, + configurable: false +}); + +assert.throws(TypeError, function() { + Object.defineProperty(p, "foo", { + value: 1, + configurable: true + }); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/defineProperty/targetdesc-not-compatible-descriptor-realm.js b/js/src/tests/test262/built-ins/Proxy/defineProperty/targetdesc-not-compatible-descriptor-realm.js new file mode 100644 index 0000000000..4d88618de6 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/defineProperty/targetdesc-not-compatible-descriptor-realm.js @@ -0,0 +1,38 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-defineownproperty-p-desc +description: > + Throw a TypeError exception if Desc and target property descriptor are not + compatible and trap result is true (honoring the realm of the current + execution context). +info: | + [[DefineOwnProperty]] (P, Desc) + + ... + 20. Else targetDesc is not undefined, + a. If IsCompatiblePropertyDescriptor(extensibleTarget, Desc , + targetDesc) is false, throw a TypeError exception. + ... +features: [cross-realm, Proxy] +---*/ + +var OProxy = $262.createRealm().global.Proxy; +var target = Object.create(null); +var p = new OProxy(target, { + defineProperty: function() { + return true; + } +}); + +Object.defineProperty(target, 'prop', { + value: 1 +}); + +assert.throws(TypeError, function() { + Object.defineProperty(p, 'prop', { + value: 2 + }); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/defineProperty/targetdesc-not-compatible-descriptor.js b/js/src/tests/test262/built-ins/Proxy/defineProperty/targetdesc-not-compatible-descriptor.js new file mode 100644 index 0000000000..bfa5fb2d32 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/defineProperty/targetdesc-not-compatible-descriptor.js @@ -0,0 +1,36 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.6 +description: > + Throw a TypeError exception if Desc and target property descriptor are not + compatible and trap result is true. +info: | + [[DefineOwnProperty]] (P, Desc) + + ... + 20. Else targetDesc is not undefined, + a. If IsCompatiblePropertyDescriptor(extensibleTarget, Desc , + targetDesc) is false, throw a TypeError exception. + ... +features: [Proxy] +---*/ + +var target = {}; +var p = new Proxy(target, { + defineProperty: function(t, prop, desc) { + return true; + } +}); + +Object.defineProperty(target, "foo", { + value: 1 +}); + +assert.throws(TypeError, function() { + Object.defineProperty(p, "foo", { + value: 2 + }); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/defineProperty/targetdesc-not-configurable-writable-desc-not-writable.js b/js/src/tests/test262/built-ins/Proxy/defineProperty/targetdesc-not-configurable-writable-desc-not-writable.js new file mode 100644 index 0000000000..902c835c04 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/defineProperty/targetdesc-not-configurable-writable-desc-not-writable.js @@ -0,0 +1,42 @@ +// Copyright (C) 2019 Aleksey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-defineownproperty-p-desc +description: > + Throw a TypeError exception if trap result is true, targetDesc is not configurable + and writable, while Desc is not writable. +info: | + [[DefineOwnProperty]] (P, Desc) + + ... + 16. Else targetDesc is not undefined, + ... + c. If IsDataDescriptor(targetDesc) is true, targetDesc.[[Configurable]] is + false, and targetDesc.[[Writable]] is true, then + i. If Desc has a [[Writable]] field and Desc.[[Writable]] is + false, throw a TypeError exception. + ... +features: [Proxy, Reflect, proxy-missing-checks] +---*/ + +var trapCalls = 0; +var p = new Proxy({}, { + defineProperty: function(t, prop, desc) { + Object.defineProperty(t, prop, { + configurable: false, + writable: true, + }); + + trapCalls++; + return true; + }, +}); + +assert.throws(TypeError, function() { + Reflect.defineProperty(p, "prop", { + writable: false, + }); +}); +assert.sameValue(trapCalls, 1); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/defineProperty/targetdesc-undefined-not-configurable-descriptor-realm.js b/js/src/tests/test262/built-ins/Proxy/defineProperty/targetdesc-undefined-not-configurable-descriptor-realm.js new file mode 100644 index 0000000000..b0cf2b1ce4 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/defineProperty/targetdesc-undefined-not-configurable-descriptor-realm.js @@ -0,0 +1,34 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-defineownproperty-p-desc +description: > + Throw a TypeError exception if Desc is not configurable and target property + descriptor is undefined, and trap result is true (honoring the realm of the + current execution context). +info: | + [[DefineOwnProperty]] (P, Desc) + + ... + 19. If targetDesc is undefined, then + ... + b. If settingConfigFalse is true, throw a TypeError exception. + ... +features: [cross-realm, Proxy] +---*/ + +var OProxy = $262.createRealm().global.Proxy; +var target = Object.create(null); +var p = new OProxy(target, { + defineProperty: function() { + return true; + } +}); + +assert.throws(TypeError, function() { + Object.defineProperty(p, 'prop', { + configurable: false + }); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/defineProperty/targetdesc-undefined-not-configurable-descriptor.js b/js/src/tests/test262/built-ins/Proxy/defineProperty/targetdesc-undefined-not-configurable-descriptor.js new file mode 100644 index 0000000000..a5a1806052 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/defineProperty/targetdesc-undefined-not-configurable-descriptor.js @@ -0,0 +1,32 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.6 +description: > + Throw a TypeError exception if Desc is not configurable and target property + descriptor is undefined, and trap result is true. +info: | + [[DefineOwnProperty]] (P, Desc) + + ... + 19. If targetDesc is undefined, then + ... + b. If settingConfigFalse is true, throw a TypeError exception. + ... +features: [Proxy] +---*/ + +var target = {}; +var p = new Proxy(target, { + defineProperty: function(t, prop, desc) { + return true; + } +}); + +assert.throws(TypeError, function() { + Object.defineProperty(p, "foo", { + configurable: false + }); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/defineProperty/targetdesc-undefined-target-is-not-extensible-realm.js b/js/src/tests/test262/built-ins/Proxy/defineProperty/targetdesc-undefined-target-is-not-extensible-realm.js new file mode 100644 index 0000000000..65851dc799 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/defineProperty/targetdesc-undefined-target-is-not-extensible-realm.js @@ -0,0 +1,33 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-defineownproperty-p-desc +description: > + Throw a TypeError exception if Desc is not configurable and target is not + extensible, and trap result is true (honoring the realm of the current + execution context). +info: | + [[DefineOwnProperty]] (P, Desc) + + ... + 19. If targetDesc is undefined, then + a. If extensibleTarget is false, throw a TypeError exception. + ... +features: [cross-realm, Proxy] +---*/ + +var OProxy = $262.createRealm().global.Proxy; +var target = Object.create(null); +var p = new OProxy(target, { + defineProperty: function() { + return true; + } +}); + +Object.preventExtensions(target); + +assert.throws(TypeError, function() { + p.prop = null; +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/defineProperty/targetdesc-undefined-target-is-not-extensible.js b/js/src/tests/test262/built-ins/Proxy/defineProperty/targetdesc-undefined-target-is-not-extensible.js new file mode 100644 index 0000000000..dedafb6ba6 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/defineProperty/targetdesc-undefined-target-is-not-extensible.js @@ -0,0 +1,31 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.6 +description: > + Throw a TypeError exception if Desc is not configurable and target is not + extensible, and trap result is true. +info: | + [[DefineOwnProperty]] (P, Desc) + + ... + 19. If targetDesc is undefined, then + a. If extensibleTarget is false, throw a TypeError exception. + ... +features: [Proxy] +---*/ + +var target = {}; +var p = new Proxy(target, { + defineProperty: function(t, prop, desc) { + return true; + } +}); + +Object.preventExtensions(target); + +assert.throws(TypeError, function() { + Object.defineProperty(p, "foo", {}); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/defineProperty/trap-is-missing-target-is-proxy.js b/js/src/tests/test262/built-ins/Proxy/defineProperty/trap-is-missing-target-is-proxy.js new file mode 100644 index 0000000000..0731dd58bb --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/defineProperty/trap-is-missing-target-is-proxy.js @@ -0,0 +1,50 @@ +// Copyright (C) 2020 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-defineownproperty-p-desc +description: > + If "defineProperty" trap is null or undefined, [[DefineOwnProperty]] call + is properly forwarded to [[ProxyTarget]] (which is also a Proxy object). +info: | + [[DefineOwnProperty]] (P, Desc) + + [...] + 5. Let target be O.[[ProxyTarget]]. + 6. Let trap be ? GetMethod(handler, "defineProperty"). + 7. If trap is undefined, then + a. Return ? target.[[DefineOwnProperty]](P, Desc). +features: [Proxy, Reflect] +---*/ + +var string = new String("str"); +var stringTarget = new Proxy(string, {}); +var stringProxy = new Proxy(stringTarget, {}); + +assert(Reflect.defineProperty(stringProxy, "4", {value: 4})); +assert.sameValue(string[4], 4); + +assert.throws(TypeError, function() { + Object.defineProperty(stringProxy, "0", { + value: "x", + }); +}); + +Object.preventExtensions(string); +assert(!Reflect.defineProperty(stringProxy, "foo", {value: 5})); + + +var func = function() {}; +var funcTarget = new Proxy(func, {}); +var funcProxy = new Proxy(funcTarget, {}); + +Object.defineProperty(funcProxy, "name", {value: "foo"}); +assert.sameValue(func.name, "foo"); + +assert.throws(TypeError, function() { + Object.defineProperty(funcProxy, "prototype", { + set: function(_value) {}, + }); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/defineProperty/trap-is-not-callable-realm.js b/js/src/tests/test262/built-ins/Proxy/defineProperty/trap-is-not-callable-realm.js new file mode 100644 index 0000000000..2f8adb54c5 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/defineProperty/trap-is-not-callable-realm.js @@ -0,0 +1,33 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-defineownproperty-p-desc +description: > + Throws if trap is not callable (honoring the Realm of the current execution + context) +info: | + [[DefineOwnProperty]] (P, Desc) + + ... + 6. Let trap be GetMethod(handler, "defineProperty"). + ... + 7.3.9 GetMethod (O, P) + ... + 2. Let func be GetV(O, P). + 5. If IsCallable(func) is false, throw a TypeError exception. + ... +features: [cross-realm, Proxy] +---*/ + +var OProxy = $262.createRealm().global.Proxy; +var p = new OProxy({}, { + defineProperty: {} +}); + +assert.throws(TypeError, function() { + Object.defineProperty(p, "foo", { + value: 1 + }); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/defineProperty/trap-is-not-callable.js b/js/src/tests/test262/built-ins/Proxy/defineProperty/trap-is-not-callable.js new file mode 100644 index 0000000000..96effe4ca6 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/defineProperty/trap-is-not-callable.js @@ -0,0 +1,32 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.6 +description: > + Throw a TypeError exception if trap is not callable. +info: | + [[DefineOwnProperty]] (P, Desc) + + ... + 6. Let trap be GetMethod(handler, "defineProperty"). + ... + 7.3.9 GetMethod (O, P) + ... + 2. Let func be GetV(O, P). + 5. If IsCallable(func) is false, throw a TypeError exception. + ... +features: [Proxy] +---*/ + +var target = {}; +var p = new Proxy(target, { + defineProperty: {} +}); + +assert.throws(TypeError, function() { + Object.defineProperty(p, "foo", { + value: 1 + }); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/defineProperty/trap-is-null-target-is-proxy.js b/js/src/tests/test262/built-ins/Proxy/defineProperty/trap-is-null-target-is-proxy.js new file mode 100644 index 0000000000..0beb8e52a0 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/defineProperty/trap-is-null-target-is-proxy.js @@ -0,0 +1,59 @@ +// Copyright (C) 2020 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-defineownproperty-p-desc +description: > + If "defineProperty" trap is null or undefined, [[DefineOwnProperty]] call + is properly forwarded to [[ProxyTarget]] (which is also a Proxy object). +info: | + [[DefineOwnProperty]] (P, Desc) + + [...] + 5. Let target be O.[[ProxyTarget]]. + 6. Let trap be ? GetMethod(handler, "defineProperty"). + 7. If trap is undefined, then + a. Return ? target.[[DefineOwnProperty]](P, Desc). +features: [Proxy, Reflect] +includes: [propertyHelper.js] +---*/ + +var plainObject = Object.create(null); +Object.defineProperty(plainObject, "foo", { + configurable: false, +}); + +var plainObjectTarget = new Proxy(plainObject, {}); +var plainObjectProxy = new Proxy(plainObjectTarget, { + defineProperty: null, +}); + +assert.throws(TypeError, function() { + Object.defineProperty(plainObjectProxy, "foo", { + configurable: true, + }); +}); + +Object.defineProperty(plainObjectProxy, "bar", { + get: function() { + return 2; + }, +}); +assert.sameValue(plainObject.bar, 2); + + +var regExp = /(?:)/g; +var regExpTarget = new Proxy(regExp, {}); +var regExpProxy = new Proxy(regExpTarget, { + defineProperty: null, +}); + +assert( + Reflect.defineProperty(regExpProxy, "lastIndex", { + writable: false, + }) +); + +verifyNotWritable(regExp, "lastIndex"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/defineProperty/trap-is-undefined-target-is-proxy.js b/js/src/tests/test262/built-ins/Proxy/defineProperty/trap-is-undefined-target-is-proxy.js new file mode 100644 index 0000000000..26934ca15f --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/defineProperty/trap-is-undefined-target-is-proxy.js @@ -0,0 +1,57 @@ +// Copyright (C) 2020 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-defineownproperty-p-desc +description: > + If "defineProperty" trap is null or undefined, [[DefineOwnProperty]] call + is properly forwarded to [[ProxyTarget]] (which is also a Proxy object). +info: | + [[DefineOwnProperty]] (P, Desc) + + [...] + 5. Let target be O.[[ProxyTarget]]. + 6. Let trap be ? GetMethod(handler, "defineProperty"). + 7. If trap is undefined, then + a. Return ? target.[[DefineOwnProperty]](P, Desc). +features: [Proxy, Reflect] +includes: [compareArray.js] +---*/ + +var array = []; +var arrayTarget = new Proxy(array, {}); +var arrayProxy = new Proxy(arrayTarget, { + defineProperty: undefined, +}); + +Object.defineProperty(arrayProxy, "0", {value: 1}); +assert.compareArray(array, [1]); + +assert.throws(TypeError, function() { + Object.defineProperty(arrayProxy, "length", { + get: function() {}, + }); +}); + + +var trapCalls = 0; +var target = new Proxy({}, { + defineProperty: function(_target, key) { + trapCalls++; + return key === "foo"; + }, +}); + +var proxy = new Proxy(target, { + defineProperty: undefined, +}); + +assert(Reflect.defineProperty(proxy, "foo", {})); +assert.sameValue(trapCalls, 1); + +assert.throws(TypeError, function() { + Object.defineProperty(proxy, "bar", {}); +}); +assert.sameValue(trapCalls, 2); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/defineProperty/trap-is-undefined.js b/js/src/tests/test262/built-ins/Proxy/defineProperty/trap-is-undefined.js new file mode 100644 index 0000000000..5a45b34631 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/defineProperty/trap-is-undefined.js @@ -0,0 +1,45 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.6 +description: > + Return target.[[DefineOwnProperty]](P, Desc) if trap is undefined. +info: | + [[DefineOwnProperty]] (P, Desc) + + ... + 8. If trap is undefined, then + a. Return target.[[DefineOwnProperty]](P, Desc). + ... +includes: [propertyHelper.js] +features: [Proxy] +---*/ + +var target = {}; +var p = new Proxy(target, {}); + +Object.defineProperty(p, "attr", { + configurable: true, + enumerable: true, + writable: true, + value: 1 +}); + +verifyEqualTo(target, "attr", 1); +verifyWritable(target, "attr"); +verifyEnumerable(target, "attr"); +verifyConfigurable(target, "attr"); + +Object.defineProperty(p, "attr", { + configurable: false, + enumerable: false, + writable: false, + value: 2 +}); + +verifyEqualTo(target, "attr", 2); +verifyNotWritable(target, "attr"); +verifyNotEnumerable(target, "attr"); +verifyNotConfigurable(target, "attr"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/defineProperty/trap-return-is-false.js b/js/src/tests/test262/built-ins/Proxy/defineProperty/trap-return-is-false.js new file mode 100644 index 0000000000..e34046be1a --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/defineProperty/trap-return-is-false.js @@ -0,0 +1,29 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.6 +description: > + Trap returns a boolean. Checking on false values. +info: | + [[DefineOwnProperty]] (P, Desc) + + ... + 12. If booleanTrapResult is false, return false. + ... +features: [Proxy, Reflect] +---*/ + +var target = {}; +var p = new Proxy(target, { + defineProperty: function(t, prop, desc) { + return 0; + } +}); + +assert.sameValue(Reflect.defineProperty(p, "attr", {}), false); +assert.sameValue( + Object.getOwnPropertyDescriptor(target, "attr"), + undefined +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/deleteProperty/boolean-trap-result-boolean-false.js b/js/src/tests/test262/built-ins/Proxy/deleteProperty/boolean-trap-result-boolean-false.js new file mode 100644 index 0000000000..5addc7638b --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/deleteProperty/boolean-trap-result-boolean-false.js @@ -0,0 +1,34 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.10 +description: > + [[Delete]] (P) + + The result is a Boolean value. +features: [Proxy, Reflect] +---*/ + +var target = {}; +var p = new Proxy(target, { + deleteProperty: function() { + return 0; + } +}); + +Object.defineProperties(target, { + isConfigurable: { + value: 1, + configurable: true + }, + notConfigurable: { + value: 1, + configurable: false + } +}); + +assert.sameValue(Reflect.deleteProperty(p, "attr"), false); +assert.sameValue(Reflect.deleteProperty(p, "isConfigurable"), false); +assert.sameValue(Reflect.deleteProperty(p, "notConfigurable"), false); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/deleteProperty/boolean-trap-result-boolean-true.js b/js/src/tests/test262/built-ins/Proxy/deleteProperty/boolean-trap-result-boolean-true.js new file mode 100644 index 0000000000..85c873e173 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/deleteProperty/boolean-trap-result-boolean-true.js @@ -0,0 +1,20 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.10 +description: > + [[Delete]] (P) + + The result is a Boolean value. +features: [Proxy, Reflect] +---*/ + +var p = new Proxy({}, { + deleteProperty: function() { + return 1; + } +}); + +assert.sameValue(Reflect.deleteProperty(p, "attr"), true); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/deleteProperty/browser.js b/js/src/tests/test262/built-ins/Proxy/deleteProperty/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/deleteProperty/browser.js diff --git a/js/src/tests/test262/built-ins/Proxy/deleteProperty/call-parameters.js b/js/src/tests/test262/built-ins/Proxy/deleteProperty/call-parameters.js new file mode 100644 index 0000000000..5f5c585a94 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/deleteProperty/call-parameters.js @@ -0,0 +1,36 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.10 +description: > + [[Delete]] (P) + + 9. Let booleanTrapResult be ToBoolean(Call(trap, handler, «target, P»)). +info: | + 6.1.7.2 Object Internal Methods and Internal Slots + + (...) Receiver is used as the this value when evaluating the code +features: [Proxy] +---*/ + +var _handler, _target, _prop; +var target = { + attr: 1 +}; +var handler = { + deleteProperty: function(t, prop) { + _handler = this; + _target = t; + _prop = prop; + return delete t[prop]; + } +}; +var p = new Proxy(target, handler); + +delete p.attr; + +assert.sameValue(_handler, handler, "handler object as the trap context"); +assert.sameValue(_target, target, "first argument is the target object"); +assert.sameValue(_prop, "attr", "second argument is the property name"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/deleteProperty/null-handler.js b/js/src/tests/test262/built-ins/Proxy/deleteProperty/null-handler.js new file mode 100644 index 0000000000..012a8aec02 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/deleteProperty/null-handler.js @@ -0,0 +1,22 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.10 +description: > + [[Delete]] (P) + + 3. If handler is null, throw a TypeError exception. +features: [Proxy] +---*/ + +var p = Proxy.revocable({ + attr: 1 +}, {}); + +p.revoke(); + +assert.throws(TypeError, function() { + delete p.proxy.attr; +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/deleteProperty/return-false-not-strict.js b/js/src/tests/test262/built-ins/Proxy/deleteProperty/return-false-not-strict.js new file mode 100644 index 0000000000..c6209578fc --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/deleteProperty/return-false-not-strict.js @@ -0,0 +1,21 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.10 +description: > + [[Delete]] (P) + + 11. If booleanTrapResult is false, return false. +flags: [noStrict] +features: [Proxy] +---*/ + +var p = new Proxy({}, { + deleteProperty: function() { + return false; + } +}); + +assert.sameValue(delete p.attr, false); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/deleteProperty/return-false-strict-strict.js b/js/src/tests/test262/built-ins/Proxy/deleteProperty/return-false-strict-strict.js new file mode 100644 index 0000000000..ae528d4416 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/deleteProperty/return-false-strict-strict.js @@ -0,0 +1,22 @@ +'use strict'; +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.10 +description: > + [[Delete]] (P) + + 11. If booleanTrapResult is false, return false. +flags: [onlyStrict] +features: [Proxy, Reflect] +---*/ + +var p = new Proxy({}, { + deleteProperty: function() { + return false; + } +}); + +assert.sameValue(Reflect.deleteProperty(p, "attr"), false); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/deleteProperty/return-is-abrupt.js b/js/src/tests/test262/built-ins/Proxy/deleteProperty/return-is-abrupt.js new file mode 100644 index 0000000000..e325aea4e8 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/deleteProperty/return-is-abrupt.js @@ -0,0 +1,23 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.10 +description: > + Trap return is an abrupt. +info: | + 9. Let booleanTrapResult be ToBoolean(Call(trap, handler, «target, P»)). + 10. ReturnIfAbrupt(booleanTrapResult). +features: [Proxy] +---*/ + +var p = new Proxy({}, { + deleteProperty: function(t, prop) { + throw new Test262Error(); + } +}); + +assert.throws(Test262Error, function() { + delete p.attr; +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/deleteProperty/shell.js b/js/src/tests/test262/built-ins/Proxy/deleteProperty/shell.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/deleteProperty/shell.js diff --git a/js/src/tests/test262/built-ins/Proxy/deleteProperty/targetdesc-is-configurable-target-is-not-extensible.js b/js/src/tests/test262/built-ins/Proxy/deleteProperty/targetdesc-is-configurable-target-is-not-extensible.js new file mode 100644 index 0000000000..4662f2ca04 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/deleteProperty/targetdesc-is-configurable-target-is-not-extensible.js @@ -0,0 +1,35 @@ +// Copyright (C) 2019 Aleksey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-delete-p +description: > + Throw a TypeError exception if trap result is true, targetDesc is configurable, + and target is not extensible. +info: | + [[Delete]] (P) + + ... + 13. Let extensibleTarget be ? IsExtensible(target). + 14. If extensibleTarget is false, throw a TypeError exception. + ... +features: [Proxy, Reflect, proxy-missing-checks] +---*/ + +var trapCalls = 0; +var p = new Proxy({prop: 1}, { + deleteProperty: function(t, prop) { + Object.preventExtensions(t); + trapCalls++; + return true; + }, +}); + +assert.throws(TypeError, function() { + Reflect.deleteProperty(p, "prop"); +}); +assert.sameValue(trapCalls, 1); + +assert(Reflect.deleteProperty(p, "nonExistent")); +assert.sameValue(trapCalls, 2); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/deleteProperty/targetdesc-is-not-configurable.js b/js/src/tests/test262/built-ins/Proxy/deleteProperty/targetdesc-is-not-configurable.js new file mode 100644 index 0000000000..9b6f079ad5 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/deleteProperty/targetdesc-is-not-configurable.js @@ -0,0 +1,31 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.10 +description: > + [[Delete]] (P) + + A property cannot be reported as deleted, if it exists as a non-configurable + own property of the target object. +info: | + 14. If targetDesc.[[Configurable]] is false, throw a TypeError exception. +features: [Proxy] +---*/ + +var target = {}; +var p = new Proxy(target, { + deleteProperty: function() { + return true; + } +}); + +Object.defineProperty(target, "attr", { + configurable: false, + value: 1 +}); + +assert.throws(TypeError, function() { + delete p.attr; +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/deleteProperty/targetdesc-is-undefined-return-true.js b/js/src/tests/test262/built-ins/Proxy/deleteProperty/targetdesc-is-undefined-return-true.js new file mode 100644 index 0000000000..62b5ca1872 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/deleteProperty/targetdesc-is-undefined-return-true.js @@ -0,0 +1,20 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.10 +description: > + [[Delete]] (P) + + 14. If targetDesc is undefined, return true. +features: [Proxy] +---*/ + +var p = new Proxy({}, { + deleteProperty: function() { + return true; + } +}); + +assert.sameValue(delete p.attr, true); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/deleteProperty/trap-is-missing-target-is-proxy.js b/js/src/tests/test262/built-ins/Proxy/deleteProperty/trap-is-missing-target-is-proxy.js new file mode 100644 index 0000000000..3c440dfd72 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/deleteProperty/trap-is-missing-target-is-proxy.js @@ -0,0 +1,58 @@ +// Copyright (C) 2020 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-delete-p +description: > + If "deleteProperty" trap is null or undefined, [[Delete]] call is + properly forwarded to [[ProxyTarget]] (which is also a Proxy object). +info: | + [[Delete]] ( P ) + + [...] + 5. Let target be O.[[ProxyTarget]]. + 6. Let trap be ? GetMethod(handler, "deleteProperty"). + 7. If trap is undefined, then + a. Return ? target.[[Delete]](P). +features: [Proxy, Reflect] +---*/ + +var plainObject = { + get foo() {}, +}; + +Object.defineProperty(plainObject, "bar", { + configurable: false, +}); + +var plainObjectTarget = new Proxy(plainObject, {}); +var plainObjectProxy = new Proxy(plainObjectTarget, {}); + +assert(delete plainObjectProxy.foo); +assert( + !Object.prototype.hasOwnProperty.call(plainObject, "foo"), + "'foo' property was deleted from original object" +); + +assert(!Reflect.deleteProperty(plainObjectProxy, "bar")); +assert( + Object.prototype.hasOwnProperty.call(plainObject, "bar"), + "'bar' property was not deleted from original object" +); + +var func = function() {}; +var funcTarget = new Proxy(func, {}); +var funcProxy = new Proxy(funcTarget, {}); + +assert(delete funcProxy.length); +assert( + !Object.prototype.hasOwnProperty.call(func, "length"), + "'length' property was deleted from original object" +); + +assert.throws(TypeError, function() { + "use strict"; + delete funcProxy.prototype; +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/deleteProperty/trap-is-not-callable-realm.js b/js/src/tests/test262/built-ins/Proxy/deleteProperty/trap-is-not-callable-realm.js new file mode 100644 index 0000000000..ac5a7a11c1 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/deleteProperty/trap-is-not-callable-realm.js @@ -0,0 +1,29 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-delete-p +description: > + Throws when trap is not callable. (honoring the Realm of the current + execution context) +info: | + 9.5.10 [[Delete]] (P) + + 6. Let trap be GetMethod(handler, "deleteProperty"). + ... + + 7.3.9 GetMethod (O, P) + + 5. If IsCallable(func) is false, throw a TypeError exception. +features: [cross-realm, Proxy] +---*/ + +var OProxy = $262.createRealm().global.Proxy; +var p = new OProxy({}, { + deleteProperty: {} +}); + +assert.throws(TypeError, function() { + delete p.attr; +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/deleteProperty/trap-is-not-callable.js b/js/src/tests/test262/built-ins/Proxy/deleteProperty/trap-is-not-callable.js new file mode 100644 index 0000000000..c6994fc13b --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/deleteProperty/trap-is-not-callable.js @@ -0,0 +1,27 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.10 +description: > + Throws when trap is not callable. +info: | + 9.5.10 [[Delete]] (P) + + 6. Let trap be GetMethod(handler, "deleteProperty"). + ... + + 7.3.9 GetMethod (O, P) + + 5. If IsCallable(func) is false, throw a TypeError exception. +features: [Proxy] +---*/ + +var p = new Proxy({}, { + deleteProperty: {} +}); + +assert.throws(TypeError, function() { + delete p.attr; +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/deleteProperty/trap-is-null-target-is-proxy.js b/js/src/tests/test262/built-ins/Proxy/deleteProperty/trap-is-null-target-is-proxy.js new file mode 100644 index 0000000000..3ba8d7b741 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/deleteProperty/trap-is-null-target-is-proxy.js @@ -0,0 +1,43 @@ +// Copyright (C) 2020 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-delete-p +description: > + If "deleteProperty" trap is null or undefined, [[Delete]] call is + properly forwarded to [[ProxyTarget]] (which is also a Proxy object). +info: | + [[Delete]] ( P ) + + [...] + 5. Let target be O.[[ProxyTarget]]. + 6. Let trap be ? GetMethod(handler, "deleteProperty"). + 7. If trap is undefined, then + a. Return ? target.[[Delete]](P). +features: [Proxy, Reflect] +---*/ + +var stringTarget = new Proxy(new String("str"), {}); +var stringProxy = new Proxy(stringTarget, { + deleteProperty: null, +}); + +assert(!Reflect.deleteProperty(stringProxy, "length")); +assert.throws(TypeError, function() { + "use strict"; + delete stringProxy[0]; +}); + + +var regExpTarget = new Proxy(/(?:)/g, {}); +var regExpProxy = new Proxy(regExpTarget, { + deleteProperty: null, +}); + +assert(delete regExpProxy.foo); +assert.throws(TypeError, function() { + "use strict"; + delete regExpProxy.lastIndex; +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/deleteProperty/trap-is-undefined-not-strict.js b/js/src/tests/test262/built-ins/Proxy/deleteProperty/trap-is-undefined-not-strict.js new file mode 100644 index 0000000000..f31c9a0e35 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/deleteProperty/trap-is-undefined-not-strict.js @@ -0,0 +1,33 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.10 +description: > + [[Delete]] (P) + + 8. If trap is undefined, then Return target.[[Delete]](P). +flags: [noStrict] +features: [Proxy] +---*/ + +var target = { + attr: 1 +}; +var p = new Proxy(target, {}); + +assert.sameValue(delete p.attr, true); +assert.sameValue(delete p.notThere, true); +assert.sameValue( + Object.getOwnPropertyDescriptor(target, "attr"), + undefined +); + +Object.defineProperty(target, "attr", { + configurable: false, + enumerable: true, + value: 1 +}); + +assert.sameValue(delete p.attr, false); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/deleteProperty/trap-is-undefined-strict-strict.js b/js/src/tests/test262/built-ins/Proxy/deleteProperty/trap-is-undefined-strict-strict.js new file mode 100644 index 0000000000..39195e7b89 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/deleteProperty/trap-is-undefined-strict-strict.js @@ -0,0 +1,34 @@ +'use strict'; +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.10 +description: > + [[Delete]] (P) + + 8. If trap is undefined, then Return target.[[Delete]](P). +flags: [onlyStrict] +features: [Proxy, Reflect] +---*/ + +var target = { + attr: 1 +}; +var p = new Proxy(target, {}); + +assert.sameValue(delete p.attr, true); +assert.sameValue(delete p.notThere, true); +assert.sameValue( + Object.getOwnPropertyDescriptor(target, "attr"), + undefined +); + +Object.defineProperty(target, "attr", { + configurable: false, + enumerable: true, + value: 1 +}); + +assert.sameValue(Reflect.deleteProperty(p, "attr"), false); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/deleteProperty/trap-is-undefined-target-is-proxy.js b/js/src/tests/test262/built-ins/Proxy/deleteProperty/trap-is-undefined-target-is-proxy.js new file mode 100644 index 0000000000..2195deca63 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/deleteProperty/trap-is-undefined-target-is-proxy.js @@ -0,0 +1,54 @@ +// Copyright (C) 2020 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-delete-p +description: > + If "deleteProperty" trap is null or undefined, [[Delete]] call is + properly forwarded to [[ProxyTarget]] (which is also a Proxy object). +info: | + [[Delete]] ( P ) + + [...] + 5. Let target be O.[[ProxyTarget]]. + 6. Let trap be ? GetMethod(handler, "deleteProperty"). + 7. If trap is undefined, then + a. Return ? target.[[Delete]](P). +features: [Proxy, Reflect] +---*/ + +var array = [1]; +var arrayTarget = new Proxy(array, {}); +var arrayProxy = new Proxy(arrayTarget, { + deleteProperty: undefined, +}); + +assert(delete arrayProxy[0]); +assert(!array.hasOwnProperty("0")); + +assert(!Reflect.deleteProperty(arrayProxy, "length")); +assert.sameValue(array.length, 1); + + +var trapCalls = 0; +var target = new Proxy({}, { + deleteProperty: function(_target, key) { + trapCalls++; + return key === "foo"; + }, +}); + +var proxy = new Proxy(target, { + deleteProperty: undefined, +}); + +assert(delete proxy.foo); +assert.sameValue(trapCalls, 1); + +assert.throws(TypeError, function() { + "use strict"; + delete proxy.bar; +}); +assert.sameValue(trapCalls, 2); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/enumerate/browser.js b/js/src/tests/test262/built-ins/Proxy/enumerate/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/enumerate/browser.js diff --git a/js/src/tests/test262/built-ins/Proxy/enumerate/removed-does-not-trigger.js b/js/src/tests/test262/built-ins/Proxy/enumerate/removed-does-not-trigger.js new file mode 100644 index 0000000000..c738d3adaa --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/enumerate/removed-does-not-trigger.js @@ -0,0 +1,49 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots +description: > + Enumerate trap was removed and it should not be triggered anymore. +includes: [compareArray.js] +features: [Proxy, Symbol, Symbol.iterator] +---*/ + +var x; +var target = [1, 2, 3]; +var p = new Proxy(target, { + enumerate: function() { + throw new Test262Error( + "An enumerate property on handler object shouldn't trigger a Proxy trap" + ); + } +}); + +var forInResults = []; +for (x in p) { + forInResults.push(x); +} + +assert.compareArray(forInResults, ["0", "1", "2"]); + +var forOfResults = []; +for (x of p) { + forOfResults.push(x); +} + +assert.compareArray(forOfResults, [1, 2, 3]); + +var itor = p[Symbol.iterator](); +var next = itor.next(); +assert.sameValue(next.value, 1); +assert.sameValue(next.done, false); +next = itor.next(); +assert.sameValue(next.value, 2); +assert.sameValue(next.done, false); +next = itor.next(); +assert.sameValue(next.value, 3); +assert.sameValue(next.done, false); +next = itor.next(); +assert.sameValue(next.value, undefined); +assert.sameValue(next.done, true); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/enumerate/shell.js b/js/src/tests/test262/built-ins/Proxy/enumerate/shell.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/enumerate/shell.js diff --git a/js/src/tests/test262/built-ins/Proxy/function-prototype.js b/js/src/tests/test262/built-ins/Proxy/function-prototype.js new file mode 100644 index 0000000000..915fc3fd80 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/function-prototype.js @@ -0,0 +1,17 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 26.2.2 +description: > + The value of the [[Prototype]] internal slot of the Proxy + constructor is the intrinsic object %FunctionPrototype% (19.2.3). +features: [Proxy] +---*/ + +assert.sameValue( + Object.getPrototypeOf(Proxy), + Function.prototype, + "`Object.getPrototypeOf(Proxy)` returns `Function.prototype`" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/get-fn-realm-recursive.js b/js/src/tests/test262/built-ins/Proxy/get-fn-realm-recursive.js new file mode 100644 index 0000000000..b06687a91c --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/get-fn-realm-recursive.js @@ -0,0 +1,59 @@ +// Copyright (C) 2019 Aleksey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-getfunctionrealm +description: > + The realm of a Proxy exotic object is the realm of its target function. + GetFunctionRealm is called recursively. +info: | + Boolean ( value ) + + [...] + 3. Let O be ? OrdinaryCreateFromConstructor(NewTarget, "%Boolean.prototype%", « [[BooleanData]] »). + [...] + 5. Return O. + + OrdinaryCreateFromConstructor ( constructor, intrinsicDefaultProto [ , internalSlotsList ] ) + + [...] + 2. Let proto be ? GetPrototypeFromConstructor(constructor, intrinsicDefaultProto). + 3. Return OrdinaryObjectCreate(proto, internalSlotsList). + + GetPrototypeFromConstructor ( constructor, intrinsicDefaultProto ) + + [...] + 3. Let proto be ? Get(constructor, "prototype"). + 4. If Type(proto) is not Object, then + a. Let realm be ? GetFunctionRealm(constructor). + b. Set proto to realm's intrinsic object named intrinsicDefaultProto. + 5. Return proto. + + GetFunctionRealm ( obj ) + + [...] + 2. If obj has a [[Realm]] internal slot, then + a. Return obj.[[Realm]]. + [...] + 4. If obj is a Proxy exotic object, then + [...] + b. Let proxyTarget be obj.[[ProxyTarget]]. + c. Return ? GetFunctionRealm(proxyTarget). +features: [cross-realm, Reflect, Proxy] +---*/ + +var realm1 = $262.createRealm().global; +var realm2 = $262.createRealm().global; +var realm3 = $262.createRealm().global; +var realm4 = $262.createRealm().global; + +var newTarget = new realm1.Function(); +newTarget.prototype = null; + +var newTargetProxy = new realm2.Proxy(newTarget, {}); +var newTargetProxyProxy = new realm3.Proxy(newTargetProxy, {}); +var boolean = Reflect.construct(realm4.Boolean, [], newTargetProxyProxy); + +assert(boolean instanceof realm1.Boolean); +assert.sameValue(Object.getPrototypeOf(boolean), realm1.Boolean.prototype); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/get-fn-realm.js b/js/src/tests/test262/built-ins/Proxy/get-fn-realm.js new file mode 100644 index 0000000000..5077891673 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/get-fn-realm.js @@ -0,0 +1,55 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-getfunctionrealm +description: > + The realm of a Proxy exotic object is the realm of its target function. +info: | + Array ( ) + + [...] + 4. Let proto be ? GetPrototypeFromConstructor(newTarget, "%Array.prototype%"). + 5. Return ! ArrayCreate(0, proto). + + OrdinaryCreateFromConstructor ( constructor, intrinsicDefaultProto [ , internalSlotsList ] ) + + [...] + 2. Let proto be ? GetPrototypeFromConstructor(constructor, intrinsicDefaultProto). + 3. Return OrdinaryObjectCreate(proto, internalSlotsList). + + GetPrototypeFromConstructor ( constructor, intrinsicDefaultProto ) + + [...] + 3. Let proto be ? Get(constructor, "prototype"). + 4. If Type(proto) is not Object, then + a. Let realm be ? GetFunctionRealm(constructor). + b. Set proto to realm's intrinsic object named intrinsicDefaultProto. + 5. Return proto. + + GetFunctionRealm ( obj ) + + [...] + 2. If obj has a [[Realm]] internal slot, then + a. Return obj.[[Realm]]. + [...] + 4. If obj is a Proxy exotic object, then + [...] + b. Let proxyTarget be obj.[[ProxyTarget]]. + c. Return ? GetFunctionRealm(proxyTarget). +features: [cross-realm, Reflect, Proxy] +---*/ + +var realm1 = $262.createRealm().global; +var realm2 = $262.createRealm().global; +var realm3 = $262.createRealm().global; + +var newTarget = new realm1.Function(); +newTarget.prototype = false; + +var newTargetProxy = new realm2.Proxy(newTarget, {}); +var array = Reflect.construct(realm3.Array, [], newTargetProxy); + +assert(array instanceof realm1.Array); +assert.sameValue(Object.getPrototypeOf(array), realm1.Array.prototype); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/get/accessor-get-is-undefined-throws.js b/js/src/tests/test262/built-ins/Proxy/get/accessor-get-is-undefined-throws.js new file mode 100644 index 0000000000..422a7a60aa --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/get/accessor-get-is-undefined-throws.js @@ -0,0 +1,39 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.8 +description: > + [[Get]] (P, Receiver) + + if trap result is not undefined, then proxy must report the same value for a + non-configurable accessor property with an undefined get. +info: | + 13. If targetDesc is not undefined, then + b. If IsAccessorDescriptor(targetDesc) and targetDesc.[[Configurable]] + is false and targetDesc.[[Get]] is undefined, then + i. If trapResult is not undefined, throw a TypeError exception. + +features: [Proxy] +---*/ + +var target = {}; +var p = new Proxy(target, { + get: function() { + return 2; + } +}); + +Object.defineProperty(target, 'attr', { + configurable: false, + get: undefined +}); + +assert.throws(TypeError, function() { + p.attr; +}); + +assert.throws(TypeError, function() { + p['attr']; +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/get/browser.js b/js/src/tests/test262/built-ins/Proxy/get/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/get/browser.js diff --git a/js/src/tests/test262/built-ins/Proxy/get/call-parameters.js b/js/src/tests/test262/built-ins/Proxy/get/call-parameters.js new file mode 100644 index 0000000000..538815bd4b --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/get/call-parameters.js @@ -0,0 +1,44 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.8 +description: > + [[Get]] (P, Receiver) + + 9. Let trapResult be Call(trap, handler, «target, P, Receiver»). +info: | + 6.1.7.2 Object Internal Methods and Internal Slots + + (...) Receiver is used as the this value when evaluating the code +features: [Proxy] +---*/ + +var _target, _handler, _prop, _receiver; +var target = { + attr: 1 +}; +var handler = { + get: function(t, prop, receiver) { + _handler = this; + _target = t; + _prop = prop; + _receiver = receiver; + } +}; +var p = new Proxy(target, handler); + +p.attr; + +assert.sameValue(_handler, handler); +assert.sameValue(_target, target); +assert.sameValue(_prop, "attr"); +assert.sameValue(_receiver, p, "receiver is the Proxy object"); + +_prop = null; +p["attr"]; +assert.sameValue( + _prop, "attr", + "trap is triggered both by p.attr and p['attr']" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/get/not-same-value-configurable-false-writable-false-throws.js b/js/src/tests/test262/built-ins/Proxy/get/not-same-value-configurable-false-writable-false-throws.js new file mode 100644 index 0000000000..790bf1997d --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/get/not-same-value-configurable-false-writable-false-throws.js @@ -0,0 +1,40 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.8 +description: > + Throws if proxy return has not the same value for a non-writable, + non-configurable property +info: | + [[Get]] (P, Receiver) + + 13. If targetDesc is not undefined, then + a. If IsDataDescriptor(targetDesc) and targetDesc.[[Configurable]] is + false and targetDesc.[[Writable]] is false, then + i. If SameValue(trapResult, targetDesc.[[Value]]) is false, throw a + TypeError exception. +features: [Proxy] +---*/ + +var target = {}; +var p = new Proxy(target, { + get: function() { + return 2; + } +}); + +Object.defineProperty(target, 'attr', { + configurable: false, + writable: false, + value: 1 +}); + +assert.throws(TypeError, function() { + p.attr; +}); + +assert.throws(TypeError, function() { + p['attr']; +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/get/null-handler.js b/js/src/tests/test262/built-ins/Proxy/get/null-handler.js new file mode 100644 index 0000000000..a5b4716301 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/get/null-handler.js @@ -0,0 +1,24 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.8 +description: > + [[Get]] (P, Receiver) + + 2. If handler is null, throw a TypeError exception. +features: [Proxy] +---*/ + +var p = Proxy.revocable({}, {}); + +p.revoke(); + +assert.throws(TypeError, function() { + p.proxy.attr; +}); + +assert.throws(TypeError, function() { + p.proxy['attr']; +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/get/return-is-abrupt.js b/js/src/tests/test262/built-ins/Proxy/get/return-is-abrupt.js new file mode 100644 index 0000000000..03bfe37967 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/get/return-is-abrupt.js @@ -0,0 +1,29 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.8 +description: > + Trap returns abrupt. +info: | + [[Get]] (P, Receiver) + + 9. Let trapResult be Call(trap, handler, «target, P, Receiver»). + 10. ReturnIfAbrupt(trapResult). +features: [Proxy] +---*/ + +var p = new Proxy({}, { + get: function() { + throw new Test262Error(); + } +}); + +assert.throws(Test262Error, function() { + p.attr; +}); + +assert.throws(Test262Error, function() { + p["attr"]; +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/get/return-trap-result-accessor-property.js b/js/src/tests/test262/built-ins/Proxy/get/return-trap-result-accessor-property.js new file mode 100644 index 0000000000..3c6b8c685e --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/get/return-trap-result-accessor-property.js @@ -0,0 +1,28 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.8 +description: > + [[Get]] (P, Receiver) + + 14. Return trapResult. +features: [Proxy] +---*/ + +var target = {}; +var p = new Proxy(target, { + get: function() { + return 2; + } +}); + +Object.defineProperty(target, 'attr', { + get: function() { + return 1; + } +}); + +assert.sameValue(p.attr, 2); +assert.sameValue(p['attr'], 2); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/get/return-trap-result-configurable-false-writable-true.js b/js/src/tests/test262/built-ins/Proxy/get/return-trap-result-configurable-false-writable-true.js new file mode 100644 index 0000000000..fae30cd0ff --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/get/return-trap-result-configurable-false-writable-true.js @@ -0,0 +1,28 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.8 +description: > + [[Get]] (P, Receiver) + + 14. Return trapResult. +features: [Proxy] +---*/ + +var target = {}; +var p = new Proxy(target, { + get: function() { + return 2; + } +}); + +Object.defineProperty(target, 'attr', { + configurable: false, + writable: true, + value: 1 +}); + +assert.sameValue(p.attr, 2); +assert.sameValue(p['attr'], 2); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/get/return-trap-result-configurable-true-assessor-get-undefined.js b/js/src/tests/test262/built-ins/Proxy/get/return-trap-result-configurable-true-assessor-get-undefined.js new file mode 100644 index 0000000000..03598c2187 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/get/return-trap-result-configurable-true-assessor-get-undefined.js @@ -0,0 +1,27 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.8 +description: > + [[Get]] (P, Receiver) + + 14. Return trapResult. +features: [Proxy] +---*/ + +var target = {}; +var p = new Proxy(target, { + get: function() { + return 2; + } +}); + +Object.defineProperty(target, 'attr', { + configurable: true, + get: undefined +}); + +assert.sameValue(p.attr, 2); +assert.sameValue(p['attr'], 2); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/get/return-trap-result-configurable-true-writable-false.js b/js/src/tests/test262/built-ins/Proxy/get/return-trap-result-configurable-true-writable-false.js new file mode 100644 index 0000000000..f24884412f --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/get/return-trap-result-configurable-true-writable-false.js @@ -0,0 +1,28 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.8 +description: > + [[Get]] (P, Receiver) + + 14. Return trapResult. +features: [Proxy] +---*/ + +var target = {}; +var p = new Proxy(target, { + get: function() { + return 2; + } +}); + +Object.defineProperty(target, 'attr', { + configurable: true, + writable: false, + value: 1 +}); + +assert.sameValue(p.attr, 2); +assert.sameValue(p['attr'], 2); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/get/return-trap-result-same-value-configurable-false-writable-false.js b/js/src/tests/test262/built-ins/Proxy/get/return-trap-result-same-value-configurable-false-writable-false.js new file mode 100644 index 0000000000..852873df97 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/get/return-trap-result-same-value-configurable-false-writable-false.js @@ -0,0 +1,37 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.8 +description: > + Proxy must report the same value for a non-writable, non-configurable + property. +info: | + [[Get]] (P, Receiver) + + 13. If targetDesc is not undefined, then + a. If IsDataDescriptor(targetDesc) and targetDesc.[[Configurable]] is + false and targetDesc.[[Writable]] is false, then + i. If SameValue(trapResult, targetDesc.[[Value]]) is false, throw a + TypeError exception. + ... + 14. Return trapResult. +features: [Proxy] +---*/ + +var target = {}; +var p = new Proxy(target, { + get: function() { + return 1; + } +}); + +Object.defineProperty(target, 'attr', { + configurable: false, + writable: false, + value: 1 +}); + +assert.sameValue(p.attr, 1); +assert.sameValue(p['attr'], 1); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/get/return-trap-result.js b/js/src/tests/test262/built-ins/Proxy/get/return-trap-result.js new file mode 100644 index 0000000000..f953d77ebe --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/get/return-trap-result.js @@ -0,0 +1,27 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.8 +description: > + [[Get]] (P, Receiver) + + 14. Return trapResult. +features: [Proxy] +---*/ + +var target = { + attr: 1 +}; +var p = new Proxy(target, { + get: function() { + return 2; + } +}); + +assert.sameValue(p.attr, 2); +assert.sameValue(p.foo, 2); + +assert.sameValue(p['attr'], 2); +assert.sameValue(p['foo'], 2); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/get/shell.js b/js/src/tests/test262/built-ins/Proxy/get/shell.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/get/shell.js diff --git a/js/src/tests/test262/built-ins/Proxy/get/trap-is-missing-target-is-proxy.js b/js/src/tests/test262/built-ins/Proxy/get/trap-is-missing-target-is-proxy.js new file mode 100644 index 0000000000..effefcacdb --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/get/trap-is-missing-target-is-proxy.js @@ -0,0 +1,33 @@ +// Copyright (C) 2020 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-get-p-receiver +description: > + If "get" trap is null or undefined, [[Get]] call is properly + forwarded to [[ProxyTarget]] (which is also a Proxy object). +info: | + [[Get]] ( P, Receiver ) + + [...] + 5. Let target be O.[[ProxyTarget]]. + 6. Let trap be ? GetMethod(handler, "get"). + 7. If trap is undefined, then + a. Return ? target.[[Get]](P, Receiver). +features: [Proxy, Symbol.match] +---*/ + +var regExp = /(?:)/i; +var regExpTarget = new Proxy(regExp, {}); +var regExpProxy = new Proxy(regExpTarget, {}); + +assert.sameValue(Object.create(regExpProxy).lastIndex, 0); +assert.sameValue(regExpProxy[Symbol.match], RegExp.prototype[Symbol.match]); + + +var functionTarget = new Proxy(function(_arg) {}, {}); +var functionProxy = new Proxy(functionTarget, {}); + +assert.sameValue(Object.create(functionProxy).length, 1); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/get/trap-is-not-callable-realm.js b/js/src/tests/test262/built-ins/Proxy/get/trap-is-not-callable-realm.js new file mode 100644 index 0000000000..a9e4cb115c --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/get/trap-is-not-callable-realm.js @@ -0,0 +1,33 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-get-p-receiver +description: > + Throws if trap is not callable (honoring the Realm of the current execution + context) +info: | + [[Get]] (P, Receiver) + + 6. Let trap be GetMethod(handler, "get"). + ... + + 7.3.9 GetMethod (O, P) + + 5. If IsCallable(func) is false, throw a TypeError exception. +features: [cross-realm, Proxy] +---*/ + +var OProxy = $262.createRealm().global.Proxy; +var p = new OProxy({}, { + get: {} +}); + +assert.throws(TypeError, function() { + p.attr; +}); + +assert.throws(TypeError, function() { + p["attr"]; +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/get/trap-is-not-callable.js b/js/src/tests/test262/built-ins/Proxy/get/trap-is-not-callable.js new file mode 100644 index 0000000000..f0b1d975e5 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/get/trap-is-not-callable.js @@ -0,0 +1,31 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.8 +description: > + Trap is not callable. +info: | + [[Get]] (P, Receiver) + + 6. Let trap be GetMethod(handler, "get"). + ... + + 7.3.9 GetMethod (O, P) + + 5. If IsCallable(func) is false, throw a TypeError exception. +features: [Proxy] +---*/ + +var p = new Proxy({}, { + get: {} +}); + +assert.throws(TypeError, function() { + p.attr; +}); + +assert.throws(TypeError, function() { + p["attr"]; +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/get/trap-is-null-target-is-proxy.js b/js/src/tests/test262/built-ins/Proxy/get/trap-is-null-target-is-proxy.js new file mode 100644 index 0000000000..6d9b09e759 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/get/trap-is-null-target-is-proxy.js @@ -0,0 +1,50 @@ +// Copyright (C) 2020 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-get-p-receiver +description: > + If "get" trap is null or undefined, [[Get]] call is properly + forwarded to [[ProxyTarget]] (which is also a Proxy object). +info: | + [[Get]] ( P, Receiver ) + + [...] + 5. Let target be O.[[ProxyTarget]]. + 6. Let trap be ? GetMethod(handler, "get"). + 7. If trap is undefined, then + a. Return ? target.[[Get]](P, Receiver). +features: [Proxy, Symbol] +---*/ + +var stringTarget = new Proxy(new String("str"), {}); +var stringProxy = new Proxy(stringTarget, { + get: null, +}); + +assert.sameValue(stringProxy.length, 3); +assert.sameValue(stringProxy[0], "s"); +assert.sameValue(stringProxy[4], undefined); + + +var sym = Symbol(); +var target = new Proxy({}, { + get: function(_target, key) { + switch (key) { + case sym: return 1; + case "10": return 2; + case "foo": return 3; + } + }, +}); + +var proxy = new Proxy(target, { + get: null, +}); + +assert.sameValue(proxy[sym], 1); +assert.sameValue(proxy[10], 2); +assert.sameValue(Object.create(proxy).foo, 3); +assert.sameValue(proxy.bar, undefined); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/get/trap-is-undefined-no-property.js b/js/src/tests/test262/built-ins/Proxy/get/trap-is-undefined-no-property.js new file mode 100644 index 0000000000..6a5dd05f1a --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/get/trap-is-undefined-no-property.js @@ -0,0 +1,22 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.8 +description: > + [[Get]] (P, Receiver) + + 8. If trap is undefined, then return target.[[Get]](P, Receiver). +features: [Proxy] +---*/ + +var target = { + attr: 1 +}; +var p = new Proxy(target, {}); + +assert.sameValue(p.attr, 1, 'return target.attr'); +assert.sameValue(p.foo, undefined, 'return target.foo'); +assert.sameValue(p['attr'], 1, 'return target.attr'); +assert.sameValue(p['foo'], undefined, 'return target.foo'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/get/trap-is-undefined-receiver.js b/js/src/tests/test262/built-ins/Proxy/get/trap-is-undefined-receiver.js new file mode 100644 index 0000000000..b714484819 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/get/trap-is-undefined-receiver.js @@ -0,0 +1,29 @@ +// Copyright (C) 2016 Aleksey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-get-p-receiver +description: > + Pass to target's [[Get]] correct receiver if trap is missing +info: | + [[Get]] (P, Receiver) + + 7. If trap is undefined, then + a. Return ? target.[[Get]](P, Receiver). +features: [Proxy] +---*/ + +var target = { + get attr() { + return this; + } +}; + +var p = new Proxy(target, { + get: null +}); +assert.sameValue(p.attr, p); + +var pParent = Object.create(new Proxy(target, {})); +assert.sameValue(pParent.attr, pParent); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/get/trap-is-undefined-target-is-proxy.js b/js/src/tests/test262/built-ins/Proxy/get/trap-is-undefined-target-is-proxy.js new file mode 100644 index 0000000000..a8e627d2e6 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/get/trap-is-undefined-target-is-proxy.js @@ -0,0 +1,47 @@ +// Copyright (C) 2020 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-get-p-receiver +description: > + If "get" trap is null or undefined, [[Get]] call is properly + forwarded to [[ProxyTarget]] (which is also a Proxy object). +info: | + [[Get]] ( P, Receiver ) + + [...] + 5. Let target be O.[[ProxyTarget]]. + 6. Let trap be ? GetMethod(handler, "get"). + 7. If trap is undefined, then + a. Return ? target.[[Get]](P, Receiver). +features: [Proxy] +includes: [compareArray.js] +---*/ + +var plainObject = { + get 0() { + return 1; + }, + foo: 2, + set bar(_value) {}, +}; + +var plainObjectTarget = new Proxy(plainObject, {}); +var plainObjectProxy = new Proxy(plainObjectTarget, { + get: undefined, +}); + +assert.sameValue(Object.create(plainObjectProxy)[0], 1); +assert.sameValue(plainObjectProxy.foo, 2); +assert.sameValue(plainObjectProxy.bar, undefined); + + +var array = [1, 2, 3]; +var arrayTarget = new Proxy(array, {}); +var arrayProxy = new Proxy(arrayTarget, { + get: undefined, +}); + +assert.compareArray(arrayProxy, array); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/get/trap-is-undefined.js b/js/src/tests/test262/built-ins/Proxy/get/trap-is-undefined.js new file mode 100644 index 0000000000..03bb20a99f --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/get/trap-is-undefined.js @@ -0,0 +1,23 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.8 +description: > + [[Get]] (P, Receiver) + + 8. If trap is undefined, then return target.[[Get]](P, Receiver). + +features: [Proxy] +---*/ + +var target = { + attr: 1 +}; +var p = new Proxy(target, { + get: undefined +}); + +assert.sameValue(p.attr, 1, 'return target.attr'); +assert.sameValue(p.foo, undefined, 'return target.foo'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/browser.js b/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/browser.js diff --git a/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/call-parameters.js b/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/call-parameters.js new file mode 100644 index 0000000000..e2de3003d0 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/call-parameters.js @@ -0,0 +1,37 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.5 +description: > + Trap is called with hander context and parameters are target and P +info: | + [[GetOwnProperty]] (P) + + ... + 9. Let trapResultObj be Call(trap, handler, «target, P»). + ... +features: [Proxy] +---*/ + +var _target, _handler, _prop; +var target = { + attr: 1 +}; +var handler = { + getOwnPropertyDescriptor: function(t, prop) { + _target = t; + _handler = this; + _prop = prop; + + return Object.getOwnPropertyDescriptor(t, prop); + } +}; +var p = new Proxy(target, handler); + +Object.getOwnPropertyDescriptor(p, "attr"); + +assert.sameValue(_handler, handler); +assert.sameValue(_target, target); +assert.sameValue(_prop, "attr"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/null-handler.js b/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/null-handler.js new file mode 100644 index 0000000000..85161e2289 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/null-handler.js @@ -0,0 +1,18 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.5 +description: > + Throws a TypeError exception if handler is null. +features: [Proxy] +---*/ + +var p = Proxy.revocable({}, {}); + +p.revoke(); + +assert.throws(TypeError, function() { + Object.getOwnPropertyDescriptor(p.proxy); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/result-is-undefined-target-is-not-extensible.js b/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/result-is-undefined-target-is-not-extensible.js new file mode 100644 index 0000000000..8e18c836ce --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/result-is-undefined-target-is-not-extensible.js @@ -0,0 +1,35 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.5 +description: > + Throws a TypeError exception if trap result is undefined and target is not + extensible +info: | + [[GetOwnProperty]] (P) + + ... + 14. If trapResultObj is undefined, then + ... + e. If ToBoolean(extensibleTarget) is false, throw a TypeError exception. + ... +features: [Proxy] +---*/ + +var target = { + foo: 1 +}; + +var p = new Proxy(target, { + getOwnPropertyDescriptor: function(t, prop) { + return; + } +}); + +Object.preventExtensions(target); + +assert.throws(TypeError, function() { + Object.getOwnPropertyDescriptor(p, "foo"); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/result-is-undefined-targetdesc-is-not-configurable.js b/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/result-is-undefined-targetdesc-is-not-configurable.js new file mode 100644 index 0000000000..42d6655c65 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/result-is-undefined-targetdesc-is-not-configurable.js @@ -0,0 +1,36 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.5 +description: > + Throws a TypeError exception if trap result is undefined and target property + descriptor is not configurable +info: | + [[GetOwnProperty]] (P) + + ... + 14. If trapResultObj is undefined, then + ... + b. If targetDesc.[[Configurable]] is false, throw a TypeError exception. + ... +features: [Proxy] +---*/ + +var target = {}; +Object.defineProperty(target, "foo", { + configurable: false, + enumerable: false, + value: 1 +}); + +var p = new Proxy(target, { + getOwnPropertyDescriptor: function(t, prop) { + return; + } +}); + +assert.throws(TypeError, function() { + Object.getOwnPropertyDescriptor(p, "foo"); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/result-is-undefined-targetdesc-is-undefined.js b/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/result-is-undefined-targetdesc-is-undefined.js new file mode 100644 index 0000000000..babd3624c7 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/result-is-undefined-targetdesc-is-undefined.js @@ -0,0 +1,34 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.5 +description: > + Throws a TypeError exception if trap result is undefined and target property + descriptor is undefined. +info: | + [[GetOwnProperty]] (P) + + ... + 14. If trapResultObj is undefined, then + a. If targetDesc is undefined, return undefined. + ... +features: [Proxy] +---*/ + +var t = {}; +var trapped; +var p = new Proxy(t, { + getOwnPropertyDescriptor: function(target, prop) { + trapped = true; + return; + } +}); + +assert.sameValue( + Object.getOwnPropertyDescriptor(p, "attr"), + undefined +); + +assert(trapped); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/result-is-undefined.js b/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/result-is-undefined.js new file mode 100644 index 0000000000..4029362b98 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/result-is-undefined.js @@ -0,0 +1,31 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.5 +description: > + Return undefined if trap result is undefined and target is extensible and + the target property descriptor is configurable. +info: | + [[GetOwnProperty]] (P) + + ... + 14. If trapResultObj is undefined, then + ... + f. Return undefined. + ... +features: [Proxy] +---*/ + +var target = { + attr: 1 +}; + +var p = new Proxy(target, { + getOwnPropertyDescriptor: function(t, prop) { + return; + } +}); + +assert.sameValue(Object.getOwnPropertyDescriptor(p, "attr"), undefined); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/result-type-is-not-object-nor-undefined-realm.js b/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/result-type-is-not-object-nor-undefined-realm.js new file mode 100644 index 0000000000..ad53efeab7 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/result-type-is-not-object-nor-undefined-realm.js @@ -0,0 +1,27 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-getownproperty-p +description: > + Error when trap result is neither Object nor undefined (honoring the Realm of + the current execution context) +info: | + [...] + 9. If Type(trapResultObj) is neither Object nor Undefined, throw a TypeError + exception. +features: [cross-realm, Proxy] +---*/ + +var OProxy = $262.createRealm().global.Proxy; + +var p = new OProxy({}, { + getOwnPropertyDescriptor: function() { + return null; + } +}); + +assert.throws(TypeError, function() { + Object.getOwnPropertyDescriptor(p, 'x'); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/result-type-is-not-object-nor-undefined.js b/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/result-type-is-not-object-nor-undefined.js new file mode 100644 index 0000000000..5d93892e5f --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/result-type-is-not-object-nor-undefined.js @@ -0,0 +1,45 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.5 +description: > + Throws a TypeError exception if trap result is neither Object nor Undefined +info: | + [[GetOwnProperty]] (P) + + ... + 11. If Type(trapResultObj) is neither Object nor Undefined, throw a + TypeError exception. + ... +features: [Proxy, Symbol] +---*/ + +var target = { + number: 1, + symbol: Symbol(), + string: '', + boolean: true +}; +var p = new Proxy(target, { + getOwnPropertyDescriptor: function(t, prop) { + return t[prop]; + } +}); + +assert.throws(TypeError, function() { + Object.getOwnPropertyDescriptor(p, "number"); +}); + +assert.throws(TypeError, function() { + Object.getOwnPropertyDescriptor(p, "string"); +}); + +assert.throws(TypeError, function() { + Object.getOwnPropertyDescriptor(p, "symbol"); +}); + +assert.throws(TypeError, function() { + Object.getOwnPropertyDescriptor(p, "boolean"); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/resultdesc-is-invalid-descriptor.js b/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/resultdesc-is-invalid-descriptor.js new file mode 100644 index 0000000000..f8a20d2d33 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/resultdesc-is-invalid-descriptor.js @@ -0,0 +1,36 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.5 +description: > + Throws a TypeError exception if trap result and target property descriptors + are not compatible. +info: | + [[GetOwnProperty]] (P) + + ... + 20. Let valid be IsCompatiblePropertyDescriptor (extensibleTarget, + resultDesc, targetDesc). + 21. If valid is false, throw a TypeError exception. +features: [Proxy] +---*/ + +var target = {}; + +var p = new Proxy(target, { + getOwnPropertyDescriptor: function(t, prop) { + var foo = { + bar: 1 + }; + + return Object.getOwnPropertyDescriptor(foo, "bar"); + } +}); + +Object.preventExtensions(target); + +assert.throws(TypeError, function() { + Object.getOwnPropertyDescriptor(p, "bar"); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/resultdesc-is-not-configurable-not-writable-targetdesc-is-writable.js b/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/resultdesc-is-not-configurable-not-writable-targetdesc-is-writable.js new file mode 100644 index 0000000000..bc4537b651 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/resultdesc-is-not-configurable-not-writable-targetdesc-is-writable.js @@ -0,0 +1,42 @@ +// Copyright (C) 2019 Aleksey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-getownproperty-p +description: > + Throws a TypeError exception if resultDesc is both non-configurable and + non-writable, while targetDesc is writable. +info: | + [[GetOwnProperty]] (P) + + ... + 17. If resultDesc.[[Configurable]] is false, then + ... + b. If resultDesc has a [[Writable]] field and resultDesc.[[Writable]] is + false, then + i. If targetDesc.[[Writable]] is true, throw a TypeError exception. + ... +features: [Proxy, proxy-missing-checks] +---*/ + +var trapCalls = 0; +var p = new Proxy({}, { + getOwnPropertyDescriptor: function(t, prop) { + Object.defineProperty(t, prop, { + configurable: false, + writable: true, + }); + + trapCalls++; + return { + configurable: false, + writable: false, + }; + }, +}); + +assert.throws(TypeError, function() { + Object.getOwnPropertyDescriptor(p, "prop"); +}); +assert.sameValue(trapCalls, 1); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/resultdesc-is-not-configurable-targetdesc-is-configurable.js b/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/resultdesc-is-not-configurable-targetdesc-is-configurable.js new file mode 100644 index 0000000000..50d8bdc080 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/resultdesc-is-not-configurable-targetdesc-is-configurable.js @@ -0,0 +1,42 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.5 +description: > + Throws a TypeError exception if trap result is not configurable but target + property descriptor is configurable. +info: | + [[GetOwnProperty]] (P) + + ... + 22. If resultDesc.[[Configurable]] is false, then + a. If targetDesc is undefined or targetDesc.[[Configurable]] is true, + then + i. Throw a TypeError exception. + ... +features: [Proxy] +---*/ + +var target = { + bar: 1 +}; + +var p = new Proxy(target, { + getOwnPropertyDescriptor: function(t, prop) { + var foo = {}; + + Object.defineProperty(foo, "bar", { + configurable: false, + enumerable: true, + value: 1 + }); + + return Object.getOwnPropertyDescriptor(foo, prop); + } +}); + +assert.throws(TypeError, function() { + Object.getOwnPropertyDescriptor(p, "bar"); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/resultdesc-is-not-configurable-targetdesc-is-undefined.js b/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/resultdesc-is-not-configurable-targetdesc-is-undefined.js new file mode 100644 index 0000000000..0b10a46f15 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/resultdesc-is-not-configurable-targetdesc-is-undefined.js @@ -0,0 +1,50 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.5 +description: > + Throws a TypeError exception if trap result is not configurable but target + property descriptor is undefined. +info: | + [[GetOwnProperty]] (P) + + ... + 2. Let handler be the value of the [[ProxyHandler]] internal slot of O. + ... + 5. Let target be the value of the [[ProxyTarget]] internal slot of O. + 6. Let trap be GetMethod(handler, "getOwnPropertyDescriptor"). + ... + 9. Let trapResultObj be Call(trap, handler, «target, P»). + ... + 12. Let targetDesc be target.[[GetOwnProperty]](P). + ... + 17. Let resultDesc be ToPropertyDescriptor(trapResultObj). + ... + 22. If resultDesc.[[Configurable]] is false, then + a. If targetDesc is undefined or targetDesc.[[Configurable]] is true, then + i. Throw a TypeError exception. + +features: [Proxy] +---*/ + +var target = {}; + +var p = new Proxy(target, { + getOwnPropertyDescriptor: function(t, prop) { + var foo = {}; + + Object.defineProperty(foo, "bar", { + configurable: false, + enumerable: true, + value: 1 + }); + + return Object.getOwnPropertyDescriptor(foo, prop); + } +}); + +assert.throws(TypeError, function() { + Object.getOwnPropertyDescriptor(p, "bar"); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/resultdesc-return-configurable.js b/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/resultdesc-return-configurable.js new file mode 100644 index 0000000000..f33fe9201e --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/resultdesc-return-configurable.js @@ -0,0 +1,33 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.5 +description: > + Return descriptor from trap result if it has the same value as the target + property descriptor. +features: [Proxy] +---*/ + +var target = {}; +var descriptor = { + configurable: true, + enumerable: true, + value: 1 +}; + +Object.defineProperty(target, "bar", descriptor); + +var p = new Proxy(target, { + getOwnPropertyDescriptor: function(t, prop) { + return Object.getOwnPropertyDescriptor(t, prop); + } +}); + +var proxyDesc = Object.getOwnPropertyDescriptor(p, "bar"); + +assert(proxyDesc.configurable); +assert(proxyDesc.enumerable); +assert.sameValue(proxyDesc.value, 1); +assert.sameValue(proxyDesc.writable, false); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/resultdesc-return-not-configurable.js b/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/resultdesc-return-not-configurable.js new file mode 100644 index 0000000000..9c6bd04c92 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/resultdesc-return-not-configurable.js @@ -0,0 +1,32 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.5 +description: > + Return descriptor from trap result if it has the same value as the target + property descriptor and they're not configurable. +features: [Proxy] +---*/ + +var target = {}; + +Object.defineProperty(target, "attr", { + configurable: false, + enumerable: true, + value: 1 +}); + +var p = new Proxy(target, { + getOwnPropertyDescriptor: function(t, prop) { + return Object.getOwnPropertyDescriptor(t, prop); + } +}); + +var proxyDesc = Object.getOwnPropertyDescriptor(p, "attr"); + +assert.sameValue(proxyDesc.configurable, false); +assert(proxyDesc.enumerable); +assert.sameValue(proxyDesc.value, 1); +assert.sameValue(proxyDesc.writable, false); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/return-is-abrupt.js b/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/return-is-abrupt.js new file mode 100644 index 0000000000..2d0a0f8613 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/return-is-abrupt.js @@ -0,0 +1,27 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.5 +description: > + Trap returns abrupt. +info: | + [[GetOwnProperty]] (P) + + ... + 9. Let trapResultObj be Call(trap, handler, «target, P»). + 10. ReturnIfAbrupt(trapResultObj). + ... +features: [Proxy] +---*/ + +var p = new Proxy({}, { + getOwnPropertyDescriptor: function(t, prop) { + throw new Test262Error(); + } +}); + +assert.throws(Test262Error, function() { + Object.getOwnPropertyDescriptor(p, "attr"); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/shell.js b/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/shell.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/shell.js diff --git a/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/trap-is-missing-target-is-proxy.js b/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/trap-is-missing-target-is-proxy.js new file mode 100644 index 0000000000..4a81b6dab4 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/trap-is-missing-target-is-proxy.js @@ -0,0 +1,48 @@ +// Copyright (C) 2020 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-getownproperty-p +description: > + If "getOwnPropertyDescriptor" trap is null or undefined, [[GetOwnProperty]] + call is properly forwarded to [[ProxyTarget]] (which is also a Proxy object). +info: | + [[GetOwnProperty]] ( P ) + + [...] + 5. Let target be O.[[ProxyTarget]]. + 6. Let trap be ? GetMethod(handler, "getOwnPropertyDescriptor"). + 7. If trap is undefined, then + a. Return ? target.[[GetOwnProperty]](P). +includes: [propertyHelper.js] +features: [Proxy] +---*/ + +var stringTarget = new Proxy(new String("str"), {}); +var stringProxy = new Proxy(stringTarget, {}); + +verifyProperty(stringProxy, "0", { + value: "s", + writable: false, + enumerable: true, + configurable: false, +}); + +verifyProperty(stringProxy, "length", { + value: 3, + writable: false, + enumerable: false, + configurable: false, +}); + + +var functionTarget = new Proxy(function() {}, {}); +var functionProxy = new Proxy(functionTarget, {}); + +verifyProperty(functionProxy, "prototype", { + writable: true, + enumerable: false, + configurable: false, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/trap-is-not-callable-realm.js b/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/trap-is-not-callable-realm.js new file mode 100644 index 0000000000..4af4ed3a63 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/trap-is-not-callable-realm.js @@ -0,0 +1,34 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-getownproperty-p +description: > + Throws if trap is not callable (honoring the Realm of the current execution + context) +info: | + [[GetOwnProperty]] (P) + + ... + 2. Let handler be the value of the [[ProxyHandler]] internal slot of O. + ... + 5. Let target be the value of the [[ProxyTarget]] internal slot of O. + 6. Let trap be GetMethod(handler, "getOwnPropertyDescriptor"). + ... + 7.3.9 GetMethod (O, P) + ... + 2. Let func be GetV(O, P). + 5. If IsCallable(func) is false, throw a TypeError exception. + ... +features: [cross-realm, Proxy] +---*/ + +var OProxy = $262.createRealm().global.Proxy; +var p = new OProxy({}, { + getOwnPropertyDescriptor: {} +}); + +assert.throws(TypeError, function() { + Object.getOwnPropertyDescriptor(p, "foo"); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/trap-is-not-callable.js b/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/trap-is-not-callable.js new file mode 100644 index 0000000000..912d38c5ea --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/trap-is-not-callable.js @@ -0,0 +1,33 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.5 +description: > + Throws a TypeError exception if trap is not callable. +info: | + [[GetOwnProperty]] (P) + + ... + 2. Let handler be the value of the [[ProxyHandler]] internal slot of O. + ... + 5. Let target be the value of the [[ProxyTarget]] internal slot of O. + 6. Let trap be GetMethod(handler, "getOwnPropertyDescriptor"). + ... + 7.3.9 GetMethod (O, P) + ... + 2. Let func be GetV(O, P). + 5. If IsCallable(func) is false, throw a TypeError exception. + ... +features: [Proxy] +---*/ + +var target = {}; +var p = new Proxy(target, { + getOwnPropertyDescriptor: {} +}); + +assert.throws(TypeError, function() { + Object.getOwnPropertyDescriptor(p, "foo"); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/trap-is-null-target-is-proxy.js b/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/trap-is-null-target-is-proxy.js new file mode 100644 index 0000000000..3e4d33c74e --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/trap-is-null-target-is-proxy.js @@ -0,0 +1,64 @@ +// Copyright (C) 2020 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-getownproperty-p +description: > + If "getOwnPropertyDescriptor" trap is null or undefined, [[GetOwnProperty]] + call is properly forwarded to [[ProxyTarget]] (which is also a Proxy object). +info: | + [[GetOwnProperty]] ( P ) + + [...] + 5. Let target be O.[[ProxyTarget]]. + 6. Let trap be ? GetMethod(handler, "getOwnPropertyDescriptor"). + 7. If trap is undefined, then + a. Return ? target.[[GetOwnProperty]](P). +includes: [propertyHelper.js] +features: [Proxy] +---*/ + +var plainObjectTarget = new Proxy({foo: 1}, {}); +var plainObjectProxy = new Proxy(plainObjectTarget, { + getOwnPropertyDescriptor: null, +}); + +verifyProperty(plainObjectProxy, "bar", undefined); +verifyProperty(plainObjectProxy, "foo", { + value: 1, + writable: true, + enumerable: true, + configurable: true, +}); + + +var fooDescriptor = { + get: function() {}, + set: function(_value) {}, + enumerable: false, + configurable: true, +}; + +var target = new Proxy({}, { + getOwnPropertyDescriptor: function(_target, key) { + if (key === "foo") { + return fooDescriptor; + } + }, + deleteProperty: function(_target, key) { + if (key === "foo") { + fooDescriptor = undefined; + } + + return true; + }, +}); + +var proxy = new Proxy(target, { + getOwnPropertyDescriptor: null, +}); + +verifyProperty(proxy, "bar", undefined); +verifyProperty(proxy, "foo", fooDescriptor); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/trap-is-undefined-target-is-proxy.js b/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/trap-is-undefined-target-is-proxy.js new file mode 100644 index 0000000000..38b797de3a --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/trap-is-undefined-target-is-proxy.js @@ -0,0 +1,53 @@ +// Copyright (C) 2020 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-getownproperty-p +description: > + If "getOwnPropertyDescriptor" trap is null or undefined, [[GetOwnProperty]] + call is properly forwarded to [[ProxyTarget]] (which is also a Proxy object). +info: | + [[GetOwnProperty]] ( P ) + + [...] + 5. Let target be O.[[ProxyTarget]]. + 6. Let trap be ? GetMethod(handler, "getOwnPropertyDescriptor"). + 7. If trap is undefined, then + a. Return ? target.[[GetOwnProperty]](P). +includes: [propertyHelper.js] +features: [Proxy] +---*/ + +var arrayTarget = new Proxy([42], {}); +var arrayProxy = new Proxy(arrayTarget, { + getOwnPropertyDescriptor: undefined, +}); + +verifyProperty(arrayProxy, "0", { + value: 42, + writable: true, + enumerable: true, + configurable: true, +}); + +verifyProperty(arrayProxy, "length", { + value: 1, + // writable: true, + enumerable: false, + configurable: false, +}); + + +var regExpTarget = new Proxy(/(?:)/, {}); +var regExpProxy = new Proxy(regExpTarget, { + getOwnPropertyDescriptor: undefined, +}); + +verifyProperty(regExpProxy, "lastIndex", { + value: 0, + writable: true, + enumerable: false, + configurable: false, +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/trap-is-undefined.js b/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/trap-is-undefined.js new file mode 100644 index 0000000000..3b23435417 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/getOwnPropertyDescriptor/trap-is-undefined.js @@ -0,0 +1,30 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.5 +description: > + Return target.[[GetOwnProperty]](P) if trap is undefined. +info: | + [[GetOwnProperty]] (P) + + ... + 8. If trap is undefined, then + a. Return target.[[GetOwnProperty]](P). + ... +includes: [propertyHelper.js] +features: [Proxy] +---*/ + +var target = { + attr: 1 +}; +var p = new Proxy(target, {}); + +var proxyDesc = Object.getOwnPropertyDescriptor(p, "attr"); + +verifyEqualTo(p, "attr", 1); +verifyWritable(p, "attr"); +verifyEnumerable(p, "attr"); +verifyConfigurable(p, "attr"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/getPrototypeOf/browser.js b/js/src/tests/test262/built-ins/Proxy/getPrototypeOf/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/getPrototypeOf/browser.js diff --git a/js/src/tests/test262/built-ins/Proxy/getPrototypeOf/call-parameters.js b/js/src/tests/test262/built-ins/Proxy/getPrototypeOf/call-parameters.js new file mode 100644 index 0000000000..a85ec120ca --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/getPrototypeOf/call-parameters.js @@ -0,0 +1,34 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.1 +description: > + Trap is called with handler as context and target as the first parameter. +info: | + [[GetPrototypeOf]] ( ) + + ... + 8. Let handlerProto be Call(trap, handler, «target»). + ... + +features: [Proxy] +---*/ + +var _handler, _target; +var target = {}; +var handler = { + getPrototypeOf: function(t) { + _handler = this; + _target = t; + return {}; + } +}; + +var p = new Proxy(target, handler); + +Object.getPrototypeOf(p); + +assert.sameValue(_handler, handler); +assert.sameValue(_target, target); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/getPrototypeOf/extensible-target-return-handlerproto.js b/js/src/tests/test262/built-ins/Proxy/getPrototypeOf/extensible-target-return-handlerproto.js new file mode 100644 index 0000000000..f9ba75c1b3 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/getPrototypeOf/extensible-target-return-handlerproto.js @@ -0,0 +1,37 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.1 +description: > + Return trap result if it's an Object and target is extensible. +info: | + [[GetPrototypeOf]] ( ) + + ... + 1. Let handler be the value of the [[ProxyHandler]] internal slot of O. + ... + 4. Let target be the value of the [[ProxyTarget]] internal slot of O. + 5. Let trap be GetMethod(handler, "getPrototypeOf"). + ... + 8. Let handlerProto be Call(trap, handler, «target»). + ... + 11. Let extensibleTarget be IsExtensible(target). + 12. ReturnIfAbrupt(extensibleTarget). + 13. If extensibleTarget is true, return handlerProto. + ... + +features: [Proxy] +---*/ + +var prot = { + foo: 1 +}; +var p = new Proxy({}, { + getPrototypeOf: function() { + return prot; + } +}); + +assert.sameValue(Object.getPrototypeOf(p), prot); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/getPrototypeOf/instanceof-custom-return-accepted.js b/js/src/tests/test262/built-ins/Proxy/getPrototypeOf/instanceof-custom-return-accepted.js new file mode 100644 index 0000000000..ab82562dc4 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/getPrototypeOf/instanceof-custom-return-accepted.js @@ -0,0 +1,40 @@ +// Copyright (C) 2019 ta7sudan. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-getprototypeof +description: > + instanceof operator will return true if trap result is the prototype of the function. +info: | + Runtime Semantics: InstanceofOperator ( V, target ) + + 5. Return ? OrdinaryHasInstance(target, V). + + OrdinaryHasInstance ( C, O ) + + 4. Let P be ? Get(C, "prototype"). + ... + 6. Repeat, + a. Set O to ? O.[[GetPrototypeOf]](). + b. If O is null, return false. + c. If SameValue(P, O) is true, return true. + + [[GetPrototypeOf]] ( ) + + 7. Let handlerProto be ? Call(trap, handler, « target »). + 8. If Type(handlerProto) is neither Object nor Null, throw a TypeError exception. + 9. Let extensibleTarget be ? IsExtensible(target). + 10. If extensibleTarget is true, return handlerProto. +features: [Proxy] +---*/ + +function Custom() {} + +var p = new Proxy({}, { + getPrototypeOf() { + return Custom.prototype; + } +}); + +assert(p instanceof Custom); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/getPrototypeOf/instanceof-target-not-extensible-not-same-proto-throws.js b/js/src/tests/test262/built-ins/Proxy/getPrototypeOf/instanceof-target-not-extensible-not-same-proto-throws.js new file mode 100644 index 0000000000..7084f5e92a --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/getPrototypeOf/instanceof-target-not-extensible-not-same-proto-throws.js @@ -0,0 +1,49 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-getprototypeof +description: > + instanceof operator observes the TypeError from a custom trap result that would return true if + the target were extensible. +info: | + Runtime Semantics: InstanceofOperator ( V, target ) + + 5. Return ? OrdinaryHasInstance(target, V). + + OrdinaryHasInstance ( C, O ) + + 4. Let P be ? Get(C, "prototype"). + ... + 6. Repeat, + a. Set O to ? O.[[GetPrototypeOf]](). + b. If O is null, return false. + c. If SameValue(P, O) is true, return true. + + [[GetPrototypeOf]] ( ) + + 7. Let handlerProto be ? Call(trap, handler, « target »). + 8. If Type(handlerProto) is neither Object nor Null, throw a TypeError exception. + 9. Let extensibleTarget be ? IsExtensible(target). + 10. If extensibleTarget is true, return handlerProto. + 11. Let targetProto be ? target.[[GetPrototypeOf]](). + 12. If SameValue(handlerProto, targetProto) is false, throw a TypeError exception. +features: [Proxy] +---*/ + +function Custom() {} + +var target = {}; + +var p = new Proxy(target, { + getPrototypeOf() { + return Custom.prototype; + } +}); + +Object.preventExtensions(target); + +assert.throws(TypeError, () => { + p instanceof Custom +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/getPrototypeOf/not-extensible-not-same-proto-throws.js b/js/src/tests/test262/built-ins/Proxy/getPrototypeOf/not-extensible-not-same-proto-throws.js new file mode 100644 index 0000000000..8d454a5aa4 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/getPrototypeOf/not-extensible-not-same-proto-throws.js @@ -0,0 +1,45 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.1 +description: > + Throws a TypeError if the target is not extensible and the trap result is + not the same as the target.[[GetPrototypeOf]] result. +info: | + [[GetPrototypeOf]] ( ) + + ... + 1. Let handler be the value of the [[ProxyHandler]] internal slot of O. + ... + 4. Let target be the value of the [[ProxyTarget]] internal slot of O. + 5. Let trap be GetMethod(handler, "getPrototypeOf"). + ... + 8. Let handlerProto be Call(trap, handler, «target»). + ... + 11. Let extensibleTarget be IsExtensible(target). + ... + 14. Let targetProto be target.[[GetPrototypeOf]](). + 15. ReturnIfAbrupt(targetProto). + 16. If SameValue(handlerProto, targetProto) is false, throw a TypeError + exception. + ... +features: [Proxy] +---*/ + +var target = Object.create({ + foo: 1 +}); + +var p = new Proxy(target, { + getPrototypeOf: function() { + return {}; + } +}); + +Object.preventExtensions(target); + +assert.throws(TypeError, function() { + Object.getPrototypeOf(p); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/getPrototypeOf/not-extensible-same-proto.js b/js/src/tests/test262/built-ins/Proxy/getPrototypeOf/not-extensible-same-proto.js new file mode 100644 index 0000000000..3ee48b1581 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/getPrototypeOf/not-extensible-same-proto.js @@ -0,0 +1,40 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.1 +description: > + Return trap result is target is not extensible, but trap result has the same + value as target.[[GetPrototypeOf]] result. +info: | + [[GetPrototypeOf]] ( ) + + ... + 1. Let handler be the value of the [[ProxyHandler]] internal slot of O. + ... + 4. Let target be the value of the [[ProxyTarget]] internal slot of O. + 5. Let trap be GetMethod(handler, "getPrototypeOf"). + ... + 8. Let handlerProto be Call(trap, handler, «target»). + ... + 11. Let extensibleTarget be IsExtensible(target). + ... + 14. Let targetProto be target.[[GetPrototypeOf]](). + ... + 17. Return handlerProto. + +features: [Proxy] +---*/ + +var target = Object.create(Array.prototype); + +var p = new Proxy(target, { + getPrototypeOf: function() { + return Array.prototype; + } +}); + +Object.preventExtensions(target); + +assert.sameValue(Object.getPrototypeOf(p), Array.prototype); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/getPrototypeOf/null-handler.js b/js/src/tests/test262/built-ins/Proxy/getPrototypeOf/null-handler.js new file mode 100644 index 0000000000..4899c2c091 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/getPrototypeOf/null-handler.js @@ -0,0 +1,18 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.1 +description: > + Throws a TypeError exception if handler is null. +features: [Proxy] +---*/ + +var p = Proxy.revocable({}, {}); + +p.revoke(); + +assert.throws(TypeError, function() { + Object.getPrototypeOf(p.proxy); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/getPrototypeOf/return-is-abrupt.js b/js/src/tests/test262/built-ins/Proxy/getPrototypeOf/return-is-abrupt.js new file mode 100644 index 0000000000..c55a7dca39 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/getPrototypeOf/return-is-abrupt.js @@ -0,0 +1,23 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.1 +description: > + Trap returns abrupt. +info: | + 8. Let handlerProto be Call(trap, handler, «target»). + 9. ReturnIfAbrupt(handlerProto). +features: [Proxy] +---*/ + +var p = new Proxy({}, { + getPrototypeOf: function() { + throw new Test262Error(); + } +}); + +assert.throws(Test262Error, function() { + Object.getPrototypeOf(p); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/getPrototypeOf/shell.js b/js/src/tests/test262/built-ins/Proxy/getPrototypeOf/shell.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/getPrototypeOf/shell.js diff --git a/js/src/tests/test262/built-ins/Proxy/getPrototypeOf/trap-is-missing-target-is-proxy.js b/js/src/tests/test262/built-ins/Proxy/getPrototypeOf/trap-is-missing-target-is-proxy.js new file mode 100644 index 0000000000..d391cba76f --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/getPrototypeOf/trap-is-missing-target-is-proxy.js @@ -0,0 +1,38 @@ +// Copyright (C) 2020 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-getprototypeof +description: > + If "getPrototypeOf" trap is null or undefined, [[GetPrototypeOf]] call + is properly forwarded to [[ProxyTarget]] (which is also a Proxy object). +info: | + [[GetPrototypeOf]] ( ) + + [...] + 4. Let target be O.[[ProxyTarget]]. + 5. Let trap be ? GetMethod(handler, "getPrototypeOf"). + 6. If trap is undefined, then + a. Return ? target.[[GetPrototypeOf]]() + + [[GetPrototypeOf]] ( ) + + [...] + 7. Let handlerProto be ? Call(trap, handler, « target »). + [...] + 13. Return handlerProto. +features: [Proxy] +---*/ + +var targetPrototype = {}; +var target = new Proxy({}, { + getPrototypeOf: function(_target) { + return targetPrototype; + }, +}); + +var proxy = new Proxy(target, {}); + +assert.sameValue(Object.getPrototypeOf(proxy), targetPrototype); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/getPrototypeOf/trap-is-not-callable-realm.js b/js/src/tests/test262/built-ins/Proxy/getPrototypeOf/trap-is-not-callable-realm.js new file mode 100644 index 0000000000..a4f15eff41 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/getPrototypeOf/trap-is-not-callable-realm.js @@ -0,0 +1,20 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-getprototypeof +description: > + Throws if trap is not callable (honoring the Realm of the current execution + context) +features: [cross-realm, Proxy] +---*/ + +var OProxy = $262.createRealm().global.Proxy; +var p = new OProxy({}, { + getPrototypeOf: {} +}); + +assert.throws(TypeError, function() { + Object.getPrototypeOf(p); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/getPrototypeOf/trap-is-not-callable.js b/js/src/tests/test262/built-ins/Proxy/getPrototypeOf/trap-is-not-callable.js new file mode 100644 index 0000000000..9dc697dfdb --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/getPrototypeOf/trap-is-not-callable.js @@ -0,0 +1,18 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.1 +description: > + Throws if trap is not callable. +features: [Proxy] +---*/ + +var p = new Proxy({}, { + getPrototypeOf: {} +}); + +assert.throws(TypeError, function() { + Object.getPrototypeOf(p); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/getPrototypeOf/trap-is-null-target-is-proxy.js b/js/src/tests/test262/built-ins/Proxy/getPrototypeOf/trap-is-null-target-is-proxy.js new file mode 100644 index 0000000000..d48d7fa789 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/getPrototypeOf/trap-is-null-target-is-proxy.js @@ -0,0 +1,27 @@ +// Copyright (C) 2020 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-getprototypeof +description: > + If "getPrototypeOf" trap is null or undefined, [[GetPrototypeOf]] call + is properly forwarded to [[ProxyTarget]] (which is also a Proxy object). +info: | + [[GetPrototypeOf]] ( ) + + [...] + 4. Let target be O.[[ProxyTarget]]. + 5. Let trap be ? GetMethod(handler, "getPrototypeOf"). + 6. If trap is undefined, then + a. Return ? target.[[GetPrototypeOf]]() +features: [Proxy] +---*/ + +var plainObjectTarget = new Proxy(Object.create(null), {}); +var plainObjectProxy = new Proxy(plainObjectTarget, { + getPrototypeOf: null, +}); + +assert.sameValue(Object.getPrototypeOf(plainObjectProxy), null); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/getPrototypeOf/trap-is-undefined-target-is-proxy.js b/js/src/tests/test262/built-ins/Proxy/getPrototypeOf/trap-is-undefined-target-is-proxy.js new file mode 100644 index 0000000000..00146ad19e --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/getPrototypeOf/trap-is-undefined-target-is-proxy.js @@ -0,0 +1,27 @@ +// Copyright (C) 2020 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-getprototypeof +description: > + If "getPrototypeOf" trap is null or undefined, [[GetPrototypeOf]] call + is properly forwarded to [[ProxyTarget]] (which is also a Proxy object). +info: | + [[GetPrototypeOf]] ( ) + + [...] + 4. Let target be O.[[ProxyTarget]]. + 5. Let trap be ? GetMethod(handler, "getPrototypeOf"). + 6. If trap is undefined, then + a. Return ? target.[[GetPrototypeOf]]() +features: [Proxy] +---*/ + +var arrayTarget = new Proxy([], {}); +var arrayProxy = new Proxy(arrayTarget, { + getPrototypeOf: undefined, +}); + +assert.sameValue(Object.getPrototypeOf(arrayProxy), Array.prototype); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/getPrototypeOf/trap-is-undefined.js b/js/src/tests/test262/built-ins/Proxy/getPrototypeOf/trap-is-undefined.js new file mode 100644 index 0000000000..21cf51daf6 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/getPrototypeOf/trap-is-undefined.js @@ -0,0 +1,15 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.1 +description: > + Return target.[[GetPrototypeOf]]() if trap is undefined. +features: [Proxy] +---*/ + +var target = Object.create(Array.prototype); +var p = new Proxy(target, {}); + +assert.sameValue(Object.getPrototypeOf(p), Array.prototype); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/getPrototypeOf/trap-result-neither-object-nor-null-throws-boolean.js b/js/src/tests/test262/built-ins/Proxy/getPrototypeOf/trap-result-neither-object-nor-null-throws-boolean.js new file mode 100644 index 0000000000..fcdc647b84 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/getPrototypeOf/trap-result-neither-object-nor-null-throws-boolean.js @@ -0,0 +1,20 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.1 +description: > + Throw a TypeError exception if trap result is false. +features: [Proxy] +---*/ + +var p = new Proxy({}, { + getPrototypeOf: function() { + return false; + } +}); + +assert.throws(TypeError, function() { + Object.getPrototypeOf(p); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/getPrototypeOf/trap-result-neither-object-nor-null-throws-number.js b/js/src/tests/test262/built-ins/Proxy/getPrototypeOf/trap-result-neither-object-nor-null-throws-number.js new file mode 100644 index 0000000000..115d015f89 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/getPrototypeOf/trap-result-neither-object-nor-null-throws-number.js @@ -0,0 +1,20 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.1 +description: > + Throw a TypeError exception if trap result is a Number. +features: [Proxy] +---*/ + +var p = new Proxy({}, { + getPrototypeOf: function() { + return 0; + } +}); + +assert.throws(TypeError, function() { + Object.getPrototypeOf(p); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/getPrototypeOf/trap-result-neither-object-nor-null-throws-string.js b/js/src/tests/test262/built-ins/Proxy/getPrototypeOf/trap-result-neither-object-nor-null-throws-string.js new file mode 100644 index 0000000000..2307f58cfc --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/getPrototypeOf/trap-result-neither-object-nor-null-throws-string.js @@ -0,0 +1,20 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.1 +description: > + throw a TypeError exception if trap result is a String. +features: [Proxy] +---*/ + +var p = new Proxy({}, { + getPrototypeOf: function() { + return ""; + } +}); + +assert.throws(TypeError, function() { + Object.getPrototypeOf(p); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/getPrototypeOf/trap-result-neither-object-nor-null-throws-symbol.js b/js/src/tests/test262/built-ins/Proxy/getPrototypeOf/trap-result-neither-object-nor-null-throws-symbol.js new file mode 100644 index 0000000000..569723a04e --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/getPrototypeOf/trap-result-neither-object-nor-null-throws-symbol.js @@ -0,0 +1,20 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.1 +description: > + Throw a TypeError exception if trap result is a Symbol. +features: [Proxy, Symbol] +---*/ + +var p = new Proxy({}, { + getPrototypeOf: function() { + return Symbol(); + } +}); + +assert.throws(TypeError, function() { + Object.getPrototypeOf(p); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/getPrototypeOf/trap-result-neither-object-nor-null-throws-undefined.js b/js/src/tests/test262/built-ins/Proxy/getPrototypeOf/trap-result-neither-object-nor-null-throws-undefined.js new file mode 100644 index 0000000000..80bd0c9bd3 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/getPrototypeOf/trap-result-neither-object-nor-null-throws-undefined.js @@ -0,0 +1,20 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.1 +description: > + Throw a TypeError exception if trap result is undefined. +features: [Proxy] +---*/ + +var p = new Proxy({}, { + getPrototypeOf: function() { + return undefined; + } +}); + +assert.throws(TypeError, function() { + Object.getPrototypeOf(p); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/has/browser.js b/js/src/tests/test262/built-ins/Proxy/has/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/has/browser.js diff --git a/js/src/tests/test262/built-ins/Proxy/has/call-in-prototype-index.js b/js/src/tests/test262/built-ins/Proxy/has/call-in-prototype-index.js new file mode 100644 index 0000000000..075cf4b6d2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/has/call-in-prototype-index.js @@ -0,0 +1,47 @@ +// Copyright (C) 2019 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-hasproperty-p +description: > + Ordinary [[HasProperty]] forwards call to Proxy "has" trap with correct arguments. + (integer index property name) +info: | + OrdinaryHasProperty ( O, P ) + + ... + 4. Let parent be ? O.[[GetPrototypeOf]](). + 5. If parent is not null, then + a. Return ? parent.[[HasProperty]](P). + + [[HasProperty]] ( P ) + + ... + 8. Let booleanTrapResult be ! ToBoolean(? Call(trap, handler, « target, P »)). + ... + 10. Return booleanTrapResult. +includes: [proxyTrapsHelper.js] +features: [Proxy] +---*/ + +var _handler, _target, _prop; +var proto = [14]; +var target = Object.create(proto); +var handler = allowProxyTraps({ + has: function(target, prop) { + _handler = this; + _target = target; + _prop = prop; + + return false; + }, +}); +var proxy = new Proxy(target, handler); +var array = []; +Object.setPrototypeOf(array, proxy); + +assert.sameValue(1 in array, false); +assert.sameValue(_handler, handler, 'handler is context'); +assert.sameValue(_target, target, 'target is the first parameter'); +assert.sameValue(_prop, '1', 'given prop is the second paramter'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/has/call-in-prototype.js b/js/src/tests/test262/built-ins/Proxy/has/call-in-prototype.js new file mode 100644 index 0000000000..e6ffeb443e --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/has/call-in-prototype.js @@ -0,0 +1,45 @@ +// Copyright (C) 2019 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-hasproperty-p +description: > + Ordinary [[HasProperty]] forwards call to Proxy "has" trap with correct arguments. +info: | + OrdinaryHasProperty ( O, P ) + + ... + 4. Let parent be ? O.[[GetPrototypeOf]](). + 5. If parent is not null, then + a. Return ? parent.[[HasProperty]](P). + + [[HasProperty]] ( P ) + + ... + 8. Let booleanTrapResult be ! ToBoolean(? Call(trap, handler, « target, P »)). + ... + 10. Return booleanTrapResult. +includes: [proxyTrapsHelper.js] +features: [Proxy] +---*/ + +var _handler, _target, _prop; +var proto = {prop: 1}; +var target = Object.create(proto); +var handler = allowProxyTraps({ + has: function(target, prop) { + _handler = this; + _target = target; + _prop = prop; + + return false; + }, +}); +var proxy = new Proxy(target, handler); +var heir = Object.create(proxy); + +assert.sameValue('prop' in heir, false); +assert.sameValue(_handler, handler, 'handler is context'); +assert.sameValue(_target, target, 'target is the first parameter'); +assert.sameValue(_prop, 'prop', 'given prop is the second paramter'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/has/call-in.js b/js/src/tests/test262/built-ins/Proxy/has/call-in.js new file mode 100644 index 0000000000..7159d4feee --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/has/call-in.js @@ -0,0 +1,35 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.7 +description: > + A `in` check trigger trap.call(handler, target, P); +info: | + [[HasProperty]] (P) + + ... + 9. Let booleanTrapResult be ToBoolean(Call(trap, handler, «target, P»)). + ... +features: [Proxy] +---*/ + +var _handler, _target, _prop; +var target = {}; +var handler = { + has: function(t, prop) { + _handler = this; + _target = t; + _prop = prop; + + return prop in t; + } +}; +var p = new Proxy(target, handler); + +"attr" in p; + +assert.sameValue(_handler, handler, "handler is context"); +assert.sameValue(_target, target, "target is the first parameter"); +assert.sameValue(_prop, "attr", "given prop is the second paramter"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/has/call-object-create.js b/js/src/tests/test262/built-ins/Proxy/has/call-object-create.js new file mode 100644 index 0000000000..fcf866b5b5 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/has/call-object-create.js @@ -0,0 +1,40 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.7 +description: > + `.. in Object.create(proxy)` triggers trap.call(handler, target, P); +info: | + [[HasProperty]] (P) + + ... + 2. Let handler be the value of the [[ProxyHandler]] internal slot of O. + ... + 5. Let target be the value of the [[ProxyTarget]] internal slot of O. + 6. Let trap be GetMethod(handler, "has"). + ... + 9. Let booleanTrapResult be ToBoolean(Call(trap, handler, «target, P»)). + ... +features: [Proxy] +---*/ + +var _handler, _target, _prop; +var target = {}; +var handler = { + has: function(t, prop) { + _handler = this; + _target = t; + _prop = prop; + + return false; + } +}; +var p = new Proxy(target, handler); + +"attr" in Object.create(p); + +assert.sameValue(_handler, handler, "handler is context"); +assert.sameValue(_target, target, "target is the first parameter"); +assert.sameValue(_prop, "attr", "given prop is the second paramter"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/has/call-with.js b/js/src/tests/test262/built-ins/Proxy/has/call-with.js new file mode 100644 index 0000000000..4169d0a54b --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/has/call-with.js @@ -0,0 +1,38 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.7 +description: > + A `with` variable check trigger trap.call(handler, target, P); +info: | + [[HasProperty]] (P) + + ... + 9. Let booleanTrapResult be ToBoolean(Call(trap, handler, «target, P»)). + ... +flags: [noStrict] +features: [Proxy] +---*/ + +var _handler, _target, _prop; +var target = {}; +var handler = { + has: function(t, prop) { + _handler = this; + _target = t; + _prop = prop; + + return true; + } +}; +var p = new Proxy(target, handler); + +with(p) { + (attr); +} + +assert.sameValue(_handler, handler); +assert.sameValue(_target, target); +assert.sameValue(_prop, "attr"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/has/null-handler-using-with.js b/js/src/tests/test262/built-ins/Proxy/has/null-handler-using-with.js new file mode 100644 index 0000000000..d82edb099e --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/has/null-handler-using-with.js @@ -0,0 +1,21 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.7 +description: > + Throws a TypeError exception if handler is null. +flags: [noStrict] +features: [Proxy] +---*/ + +var p = Proxy.revocable({}, {}); + +p.revoke(); + +assert.throws(TypeError, function() { + with(p.proxy) { + (attr); + } +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/has/null-handler.js b/js/src/tests/test262/built-ins/Proxy/has/null-handler.js new file mode 100644 index 0000000000..506225e6ec --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/has/null-handler.js @@ -0,0 +1,18 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.7 +description: > + Throws a TypeError exception if handler is null. +features: [Proxy] +---*/ + +var p = Proxy.revocable({}, {}); + +p.revoke(); + +assert.throws(TypeError, function() { + "attr" in p.proxy; +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/has/return-false-target-not-extensible-using-with.js b/js/src/tests/test262/built-ins/Proxy/has/return-false-target-not-extensible-using-with.js new file mode 100644 index 0000000000..d3749a6774 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/has/return-false-target-not-extensible-using-with.js @@ -0,0 +1,46 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.7 +description: > + A property cannot be reported as non-existent, if it exists as an own + property of the target object and the target object is not extensible. +info: | + [[HasProperty]] (P) + + ... + 11. If booleanTrapResult is false, then + a. Let targetDesc be target.[[GetOwnProperty]](P). + b. ReturnIfAbrupt(targetDesc). + c. If targetDesc is not undefined, then + ... + ii. Let extensibleTarget be IsExtensible(target). + ... + iv. If extensibleTarget is false, throw a TypeError exception. + ... +flags: [noStrict] +features: [Proxy] +---*/ + +var target = {}; +var handler = { + has: function(t, prop) { + return 0; + } +}; +var p = new Proxy(target, handler); + +Object.defineProperty(target, 'attr', { + configurable: true, + value: 1 +}); + +Object.preventExtensions(target); + +assert.throws(TypeError, function() { + with(p) { + (attr); + } +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/has/return-false-target-not-extensible.js b/js/src/tests/test262/built-ins/Proxy/has/return-false-target-not-extensible.js new file mode 100644 index 0000000000..2cb55fd76f --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/has/return-false-target-not-extensible.js @@ -0,0 +1,43 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.7 +description: > + A property cannot be reported as non-existent, if it exists as an own + property of the target object and the target object is not extensible. +info: | + [[HasProperty]] (P) + + ... + 11. If booleanTrapResult is false, then + a. Let targetDesc be target.[[GetOwnProperty]](P). + b. ReturnIfAbrupt(targetDesc). + c. If targetDesc is not undefined, then + ... + ii. Let extensibleTarget be IsExtensible(target). + ... + iv. If extensibleTarget is false, throw a TypeError exception. + ... +features: [Proxy] +---*/ + +var target = {}; +var handler = { + has: function(t, prop) { + return 0; + } +}; +var p = new Proxy(target, handler); + +Object.defineProperty(target, "attr", { + configurable: true, + value: 1 +}); + +Object.preventExtensions(target); + +assert.throws(TypeError, function() { + "attr" in p; +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/has/return-false-target-prop-exists-using-with.js b/js/src/tests/test262/built-ins/Proxy/has/return-false-target-prop-exists-using-with.js new file mode 100644 index 0000000000..c7d81d43cf --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/has/return-false-target-prop-exists-using-with.js @@ -0,0 +1,31 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.7 +description: > + The result of [[HasProperty]] is a Boolean value and will affect has + checkings. False returned when target property exists; +info: | + [[HasProperty]] (P) + + ... + 12. Return booleanTrapResult. +flags: [noStrict] +features: [Proxy] +---*/ + +var target = { + attr: 1 +}; +var p = new Proxy(target, { + has: function(t, prop) { + return false; + } +}); + +var attr = 0; +with(p) { + assert.sameValue(attr, 0); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/has/return-false-target-prop-exists.js b/js/src/tests/test262/built-ins/Proxy/has/return-false-target-prop-exists.js new file mode 100644 index 0000000000..c67ea4ace0 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/has/return-false-target-prop-exists.js @@ -0,0 +1,27 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.7 +description: > + The result of [[HasProperty]] is a Boolean value and will affect has + checkings. False returned when target property exists; +info: | + [[HasProperty]] (P) + + ... + 12. Return booleanTrapResult. +features: [Proxy] +---*/ + +var target = { + attr: 1 +}; +var p = new Proxy(target, { + has: function(t, prop) { + return false; + } +}); + +assert.sameValue(("attr" in p), false); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/has/return-false-targetdesc-not-configurable-using-with.js b/js/src/tests/test262/built-ins/Proxy/has/return-false-targetdesc-not-configurable-using-with.js new file mode 100644 index 0000000000..c7e114a82f --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/has/return-false-targetdesc-not-configurable-using-with.js @@ -0,0 +1,41 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.7 +description: > + A property cannot be reported as non-existent, if it exists as a + non-configurable own property of the target object. +info: | + [[HasProperty]] (P) + + ... + 11. If booleanTrapResult is false, then + ... + c. If targetDesc is not undefined, then + i. If targetDesc.[[Configurable]] is false, throw a TypeError + exception. + ... +flags: [noStrict] +features: [Proxy] +---*/ + +var target = {}; +var handler = { + has: function(t, prop) { + return 0; + } +}; +var p = new Proxy(target, handler); + +Object.defineProperty(target, "attr", { + configurable: false, + value: 1 +}); + +assert.throws(TypeError, function() { + with(p) { + (attr); + } +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/has/return-false-targetdesc-not-configurable.js b/js/src/tests/test262/built-ins/Proxy/has/return-false-targetdesc-not-configurable.js new file mode 100644 index 0000000000..b77da04378 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/has/return-false-targetdesc-not-configurable.js @@ -0,0 +1,38 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.7 +description: > + A property cannot be reported as non-existent, if it exists as a + non-configurable own property of the target object. +info: | + [[HasProperty]] (P) + + ... + 11. If booleanTrapResult is false, then + ... + c. If targetDesc is not undefined, then + i. If targetDesc.[[Configurable]] is false, throw a TypeError + exception. + ... +features: [Proxy] +---*/ + +var target = {}; +var handler = { + has: function(t, prop) { + return 0; + } +}; +var p = new Proxy(target, handler); + +Object.defineProperty(target, "attr", { + configurable: false, + value: 1 +}); + +assert.throws(TypeError, function() { + "attr" in p; +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/has/return-is-abrupt-in.js b/js/src/tests/test262/built-ins/Proxy/has/return-is-abrupt-in.js new file mode 100644 index 0000000000..7c38719533 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/has/return-is-abrupt-in.js @@ -0,0 +1,27 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.7 +description: > + Trap returns abrupt. Using `prop in obj`. +info: | + [[HasProperty]] (P) + + ... + 9. Let booleanTrapResult be ToBoolean(Call(trap, handler, «target, P»)). + 10. ReturnIfAbrupt(booleanTrapResult). + ... +features: [Proxy] +---*/ + +var p = new Proxy({}, { + has: function() { + throw new Test262Error(); + } +}); + +assert.throws(Test262Error, function() { + "attr" in p; +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/has/return-is-abrupt-with.js b/js/src/tests/test262/built-ins/Proxy/has/return-is-abrupt-with.js new file mode 100644 index 0000000000..6958d5b8f5 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/has/return-is-abrupt-with.js @@ -0,0 +1,30 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.7 +description: > + Trap returns abrupt. Using `with`. +info: | + [[HasProperty]] (P) + + ... + 9. Let booleanTrapResult be ToBoolean(Call(trap, handler, «target, P»)). + 10. ReturnIfAbrupt(booleanTrapResult). + ... +flags: [noStrict] +features: [Proxy] +---*/ + +var p = new Proxy({}, { + has: function() { + throw new Test262Error(); + } +}); + +assert.throws(Test262Error, function() { + with(p) { + (attr); + } +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/has/return-true-target-prop-exists-using-with.js b/js/src/tests/test262/built-ins/Proxy/has/return-true-target-prop-exists-using-with.js new file mode 100644 index 0000000000..e2df526588 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/has/return-true-target-prop-exists-using-with.js @@ -0,0 +1,28 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.7 +description: > + The result of [[HasProperty]] is a Boolean value and will affect has + checkings. True returned when target property exists; +flags: [noStrict] +features: [Proxy] +---*/ + +var target = { + attr: 1 +}; +var p = new Proxy(target, { + has: function(t, prop) { + if (prop !== "assert") { + return 42; + } + } +}); + +var attr = 0; +with(p) { + assert.sameValue(attr, 1); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/has/return-true-target-prop-exists.js b/js/src/tests/test262/built-ins/Proxy/has/return-true-target-prop-exists.js new file mode 100644 index 0000000000..1cf6201a33 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/has/return-true-target-prop-exists.js @@ -0,0 +1,22 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.7 +description: > + The result of [[HasProperty]] is a Boolean value and will affect has + checkings. True returned when target property exists; +features: [Proxy] +---*/ + +var target = { + attr: 1 +}; +var p = new Proxy(target, { + has: function(t, prop) { + return 1; + } +}); + +assert.sameValue(("attr" in p), true); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/has/return-true-without-same-target-prop.js b/js/src/tests/test262/built-ins/Proxy/has/return-true-without-same-target-prop.js new file mode 100644 index 0000000000..a0b5b926b4 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/has/return-true-without-same-target-prop.js @@ -0,0 +1,19 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.7 +description: > + The result of [[HasProperty]] is a Boolean value and will affect has + checkings. True returned when target property doesn't exists; +features: [Proxy] +---*/ + +var p = new Proxy({}, { + has: function(t, prop) { + return true; + } +}); + +assert.sameValue(("attr" in p), true); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/has/shell.js b/js/src/tests/test262/built-ins/Proxy/has/shell.js new file mode 100644 index 0000000000..bc72493f03 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/has/shell.js @@ -0,0 +1,33 @@ +// GENERATED, DO NOT EDIT +// file: proxyTrapsHelper.js +// Copyright (C) 2016 Jordan Harband. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: | + Used to assert the correctness of object behavior in the presence + and context of Proxy objects. +defines: [allowProxyTraps] +---*/ + +function allowProxyTraps(overrides) { + function throwTest262Error(msg) { + return function () { throw new Test262Error(msg); }; + } + if (!overrides) { overrides = {}; } + return { + getPrototypeOf: overrides.getPrototypeOf || throwTest262Error('[[GetPrototypeOf]] trap called'), + setPrototypeOf: overrides.setPrototypeOf || throwTest262Error('[[SetPrototypeOf]] trap called'), + isExtensible: overrides.isExtensible || throwTest262Error('[[IsExtensible]] trap called'), + preventExtensions: overrides.preventExtensions || throwTest262Error('[[PreventExtensions]] trap called'), + getOwnPropertyDescriptor: overrides.getOwnPropertyDescriptor || throwTest262Error('[[GetOwnProperty]] trap called'), + has: overrides.has || throwTest262Error('[[HasProperty]] trap called'), + get: overrides.get || throwTest262Error('[[Get]] trap called'), + set: overrides.set || throwTest262Error('[[Set]] trap called'), + deleteProperty: overrides.deleteProperty || throwTest262Error('[[Delete]] trap called'), + defineProperty: overrides.defineProperty || throwTest262Error('[[DefineOwnProperty]] trap called'), + enumerate: throwTest262Error('[[Enumerate]] trap called: this trap has been removed'), + ownKeys: overrides.ownKeys || throwTest262Error('[[OwnPropertyKeys]] trap called'), + apply: overrides.apply || throwTest262Error('[[Call]] trap called'), + construct: overrides.construct || throwTest262Error('[[Construct]] trap called') + }; +} diff --git a/js/src/tests/test262/built-ins/Proxy/has/trap-is-missing-target-is-proxy.js b/js/src/tests/test262/built-ins/Proxy/has/trap-is-missing-target-is-proxy.js new file mode 100644 index 0000000000..edee560115 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/has/trap-is-missing-target-is-proxy.js @@ -0,0 +1,35 @@ +// Copyright (C) 2020 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-hasproperty-p +description: > + If "has" trap is null or undefined, [[HasProperty]] call is properly + forwarded to [[ProxyTarget]] (which is also a Proxy object). +info: | + [[HasProperty]] ( P ) + + [...] + 5. Let target be O.[[ProxyTarget]]. + 6. Let trap be ? GetMethod(handler, "has"). + 7. If trap is undefined, then + a. Return ? target.[[HasProperty]](P). +features: [Proxy, Symbol.replace, Reflect] +---*/ + +var regExp = /(?:)/m; +var regExpTarget = new Proxy(regExp, {}); +var regExpProxy = new Proxy(regExpTarget, {}); + +assert(Reflect.has(regExpProxy, "ignoreCase")); +assert(Symbol.replace in regExpProxy); +assert("lastIndex" in Object.create(regExpProxy)); + + +var functionTarget = new Proxy(function() {}, {}); +var functionProxy = new Proxy(functionTarget, {}); + +assert("name" in functionProxy); +assert("length" in Object.create(functionProxy)); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/has/trap-is-not-callable-realm.js b/js/src/tests/test262/built-ins/Proxy/has/trap-is-not-callable-realm.js new file mode 100644 index 0000000000..9479a244a8 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/has/trap-is-not-callable-realm.js @@ -0,0 +1,31 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-hasproperty-p +description: > + Throws if trap is not callable (honoring the Realm of the current execution + context) +info: | + [[HasProperty]] (P) + + ... + 6. Let trap be GetMethod(handler, "has"). + ... + 7.3.9 GetMethod (O, P) + ... + 2. Let func be GetV(O, P). + 5. If IsCallable(func) is false, throw a TypeError exception. + ... +features: [cross-realm, Proxy] +---*/ + +var OProxy = $262.createRealm().global.Proxy; +var p = new OProxy({}, { + has: {} +}); + +assert.throws(TypeError, function() { + "attr" in p; +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/has/trap-is-not-callable-using-with.js b/js/src/tests/test262/built-ins/Proxy/has/trap-is-not-callable-using-with.js new file mode 100644 index 0000000000..2658804db3 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/has/trap-is-not-callable-using-with.js @@ -0,0 +1,33 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.7 +description: > + Throws a TypeError exception if trap is not callable. +info: | + [[HasProperty]] (P) + + ... + 6. Let trap be GetMethod(handler, "has"). + ... + 7.3.9 GetMethod (O, P) + ... + 2. Let func be GetV(O, P). + 5. If IsCallable(func) is false, throw a TypeError exception. + ... +flags: [noStrict] +features: [Proxy] +---*/ + +var target = {}; +var p = new Proxy(target, { + has: {} +}); + +assert.throws(TypeError, function() { + with(p) { + (attr); + } +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/has/trap-is-not-callable.js b/js/src/tests/test262/built-ins/Proxy/has/trap-is-not-callable.js new file mode 100644 index 0000000000..77067dd42a --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/has/trap-is-not-callable.js @@ -0,0 +1,30 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.7 +description: > + Throws a TypeError exception if trap is not callable. +info: | + [[HasProperty]] (P) + + ... + 6. Let trap be GetMethod(handler, "has"). + ... + 7.3.9 GetMethod (O, P) + ... + 2. Let func be GetV(O, P). + 5. If IsCallable(func) is false, throw a TypeError exception. + ... +features: [Proxy] +---*/ + +var target = {}; +var p = new Proxy(target, { + has: {} +}); + +assert.throws(TypeError, function() { + "attr" in p; +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/has/trap-is-null-target-is-proxy.js b/js/src/tests/test262/built-ins/Proxy/has/trap-is-null-target-is-proxy.js new file mode 100644 index 0000000000..72b4443c95 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/has/trap-is-null-target-is-proxy.js @@ -0,0 +1,46 @@ +// Copyright (C) 2020 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-hasproperty-p +description: > + If "has" trap is null or undefined, [[HasProperty]] call is properly + forwarded to [[ProxyTarget]] (which is also a Proxy object). +info: | + [[HasProperty]] ( P ) + + [...] + 5. Let target be O.[[ProxyTarget]]. + 6. Let trap be ? GetMethod(handler, "has"). + 7. If trap is undefined, then + a. Return ? target.[[HasProperty]](P). +features: [Proxy, Symbol, Reflect, Array.prototype.includes] +---*/ + +var stringTarget = new Proxy(new String("str"), {}); +var stringProxy = new Proxy(stringTarget, { + get: null, +}); + +assert(Reflect.has(stringProxy, "length")); +assert(0 in stringProxy); +assert(!(4 in stringProxy)); + + +var sym = Symbol(); +var target = new Proxy({}, { + has: function(_target, key) { + return [sym, "6", "foo"].includes(key); + }, +}); + +var proxy = new Proxy(target, { + get: null, +}); + +assert(Reflect.has(proxy, sym)); +assert("6" in proxy); +assert("foo" in Object.create(proxy)); +assert(!("bar" in proxy)); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/has/trap-is-undefined-target-is-proxy.js b/js/src/tests/test262/built-ins/Proxy/has/trap-is-undefined-target-is-proxy.js new file mode 100644 index 0000000000..270a17e158 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/has/trap-is-undefined-target-is-proxy.js @@ -0,0 +1,47 @@ +// Copyright (C) 2020 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-hasproperty-p +description: > + If "has" trap is null or undefined, [[HasProperty]] call is properly + forwarded to [[ProxyTarget]] (which is also a Proxy object). +info: | + [[HasProperty]] ( P ) + + [...] + 5. Let target be O.[[ProxyTarget]]. + 6. Let trap be ? GetMethod(handler, "has"). + 7. If trap is undefined, then + a. Return ? target.[[HasProperty]](P). +features: [Proxy, Reflect] +---*/ + +var plainObject = { + get 0() { + return 1; + }, + foo: 2, + set bar(_value) {}, +}; + +var plainObjectTarget = new Proxy(plainObject, {}); +var plainObjectProxy = new Proxy(plainObjectTarget, { + get: undefined, +}); + +assert(0 in Object.create(plainObjectProxy)); +assert("foo" in plainObjectProxy); +assert(Reflect.has(plainObjectProxy, "bar")); + + +var arrayTarget = new Proxy([1, 2], {}); +var arrayProxy = new Proxy(arrayTarget, { + get: undefined, +}); + +assert("length" in Object.create(arrayProxy)); +assert("1" in arrayProxy); +assert(!("2" in arrayProxy)); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/has/trap-is-undefined-using-with.js b/js/src/tests/test262/built-ins/Proxy/has/trap-is-undefined-using-with.js new file mode 100644 index 0000000000..5fed552af0 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/has/trap-is-undefined-using-with.js @@ -0,0 +1,27 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.7 +description: > + Return target.[[HasProperty]](P) if trap is undefined. +info: | + [[HasProperty]] (P) + + ... + 8. If trap is undefined, then + a. Return target.[[HasProperty]](P). + ... +flags: [noStrict] +features: [Proxy] +---*/ + +var target = Object.create(Array.prototype); +var p = new Proxy(target, {}); + +var foo = 3; +with(target) { + assert.sameValue(length, 0); + assert.sameValue(foo, 3); +} + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/has/trap-is-undefined.js b/js/src/tests/test262/built-ins/Proxy/has/trap-is-undefined.js new file mode 100644 index 0000000000..d19bdefc8e --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/has/trap-is-undefined.js @@ -0,0 +1,23 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.7 +description: > + Return target.[[HasProperty]](P) if trap is undefined. +info: | + [[HasProperty]] (P) + + ... + 8. If trap is undefined, then + a. Return target.[[HasProperty]](P). + ... +features: [Proxy] +---*/ + +var target = Object.create(Array.prototype); +var p = new Proxy(target, {}); + +assert.sameValue(("foo" in p), false); +assert.sameValue(("length" in p), true); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/isExtensible/browser.js b/js/src/tests/test262/built-ins/Proxy/isExtensible/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/isExtensible/browser.js diff --git a/js/src/tests/test262/built-ins/Proxy/isExtensible/call-parameters.js b/js/src/tests/test262/built-ins/Proxy/isExtensible/call-parameters.js new file mode 100644 index 0000000000..e6782da76a --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/isExtensible/call-parameters.js @@ -0,0 +1,34 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.3 +description: > + The trap is called with handler on its context and the target object as the + first parabeter +info: | + [[IsExtensible]] ( ) + + ... + 8. Let booleanTrapResult be ToBoolean(Call(trap, handler, «target»)). + ... + +features: [Proxy] +---*/ + +var _target, _handler; +var target = {}; +var handler = { + isExtensible: function(t) { + _handler = this; + _target = t; + return Object.isExtensible(t); + } +} +var p = new Proxy(target, handler); + +Object.isExtensible(p); + +assert.sameValue(_handler, handler); +assert.sameValue(_target, target); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/isExtensible/null-handler.js b/js/src/tests/test262/built-ins/Proxy/isExtensible/null-handler.js new file mode 100644 index 0000000000..87c5304599 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/isExtensible/null-handler.js @@ -0,0 +1,18 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.3 +description: > + Throws a TypeError exception if handler is null +features: [Proxy] +---*/ + +var p = Proxy.revocable({}, {}); + +p.revoke(); + +assert.throws(TypeError, function() { + Object.isExtensible(p.proxy); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/isExtensible/return-is-abrupt.js b/js/src/tests/test262/built-ins/Proxy/isExtensible/return-is-abrupt.js new file mode 100644 index 0000000000..7976c4ee36 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/isExtensible/return-is-abrupt.js @@ -0,0 +1,27 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.3 +description: > + Trap returns abrupt. +info: | + [[IsExtensible]] ( ) + + ... + 8. Let booleanTrapResult be ToBoolean(Call(trap, handler, «target»)). + 9. ReturnIfAbrupt(booleanTrapResult). + ... +features: [Proxy] +---*/ + +var p = new Proxy({}, { + isExtensible: function(t) { + throw new Test262Error(); + } +}); + +assert.throws(Test262Error, function() { + Object.isExtensible(p); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/isExtensible/return-is-boolean.js b/js/src/tests/test262/built-ins/Proxy/isExtensible/return-is-boolean.js new file mode 100644 index 0000000000..127251ac8a --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/isExtensible/return-is-boolean.js @@ -0,0 +1,27 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.3 +description: > + The trap returns a boolean result. +features: [Proxy] +---*/ + +var target = {}; +var p = new Proxy(target, { + isExtensible: function(t) { + if (Object.isExtensible(t)) { + return 1; + } else { + return 0; + } + } +}); + +assert.sameValue(Object.isExtensible(p), true); + +Object.preventExtensions(target); + +assert.sameValue(Object.isExtensible(p), false); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/isExtensible/return-is-different-from-target.js b/js/src/tests/test262/built-ins/Proxy/isExtensible/return-is-different-from-target.js new file mode 100644 index 0000000000..e05b225188 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/isExtensible/return-is-different-from-target.js @@ -0,0 +1,28 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.3 +description: > + Throws a TypeError exception if boolean trap result is not the same as + target.[[IsExtensible]]() result +info: | + [[IsExtensible]] ( ) + + ... + 12. If SameValue(booleanTrapResult, targetResult) is false, throw a + TypeError exception. + ... +features: [Proxy] +---*/ + +var p = new Proxy({}, { + isExtensible: function(t) { + return false; + } +}); + +assert.throws(TypeError, function() { + Object.isExtensible(p); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/isExtensible/return-same-result-from-target.js b/js/src/tests/test262/built-ins/Proxy/isExtensible/return-same-result-from-target.js new file mode 100644 index 0000000000..b4d2155b85 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/isExtensible/return-same-result-from-target.js @@ -0,0 +1,23 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.3 +description: > + Return trap result. +features: [Proxy] +---*/ + +var target = {}; +var p = new Proxy(target, { + isExtensible: function(t) { + return Object.isExtensible(t); + } +}); + +assert.sameValue(Object.isExtensible(p), true); + +Object.preventExtensions(target); + +assert.sameValue(Object.isExtensible(p), false); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/isExtensible/shell.js b/js/src/tests/test262/built-ins/Proxy/isExtensible/shell.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/isExtensible/shell.js diff --git a/js/src/tests/test262/built-ins/Proxy/isExtensible/trap-is-missing-target-is-proxy.js b/js/src/tests/test262/built-ins/Proxy/isExtensible/trap-is-missing-target-is-proxy.js new file mode 100644 index 0000000000..266db31b77 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/isExtensible/trap-is-missing-target-is-proxy.js @@ -0,0 +1,33 @@ +// Copyright (C) 2020 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-isextensible +description: > + If "isExtensible" trap is null or undefined, [[IsExtensible]] call is + properly forwarded to [[ProxyTarget]] (which is also a Proxy object). +info: | + [[IsExtensible]] ( ) + + [...] + 4. Let target be O.[[ProxyTarget]]. + 5. Let trap be ? GetMethod(handler, "isExtensible"). + 6. If trap is undefined, then + a. Return ? IsExtensible(target). + + IsExtensible ( O ) + + 1. Assert: Type(O) is Object. + 2. Return ? O.[[IsExtensible]](). +features: [Proxy] +---*/ + +var regExp = /(?:)/g; +Object.preventExtensions(regExp); + +var regExpTarget = new Proxy(regExp, {}); +var regExpProxy = new Proxy(regExpTarget, {}); + +assert(!Object.isExtensible(regExpProxy)); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/isExtensible/trap-is-not-callable-realm.js b/js/src/tests/test262/built-ins/Proxy/isExtensible/trap-is-not-callable-realm.js new file mode 100644 index 0000000000..8406275aa3 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/isExtensible/trap-is-not-callable-realm.js @@ -0,0 +1,33 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-isextensible +description: > + Throws if trap is not callable (honoring the Realm of the current execution + context) +info: | + [[IsExtensible]] ( ) + + ... + 1. Let handler be the value of the [[ProxyHandler]] internal slot of O. + ... + 5. Let trap be GetMethod(handler, "isExtensible"). + ... + 7.3.9 GetMethod (O, P) + ... + 2. Let func be GetV(O, P). + 5. If IsCallable(func) is false, throw a TypeError exception. + ... +features: [cross-realm, Proxy] +---*/ + +var OProxy = $262.createRealm().global.Proxy; +var p = new OProxy({}, { + isExtensible: {} +}); + +assert.throws(TypeError, function() { + Object.isExtensible(p); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/isExtensible/trap-is-not-callable.js b/js/src/tests/test262/built-ins/Proxy/isExtensible/trap-is-not-callable.js new file mode 100644 index 0000000000..b253fdebf6 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/isExtensible/trap-is-not-callable.js @@ -0,0 +1,33 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.3 +description: > + Throws a TypeError exception if trap is not callable. +info: | + [[IsExtensible]] ( ) + + ... + 1. Let handler be the value of the [[ProxyHandler]] internal slot of O. + ... + 5. Let trap be GetMethod(handler, "isExtensible"). + ... + 7.3.9 GetMethod (O, P) + ... + 2. Let func be GetV(O, P). + 5. If IsCallable(func) is false, throw a TypeError exception. + ... +features: [Proxy] +---*/ + + +var target = {}; +var p = new Proxy(target, { + isExtensible: {} +}); + +assert.throws(TypeError, function() { + Object.isExtensible(p); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/isExtensible/trap-is-null-target-is-proxy.js b/js/src/tests/test262/built-ins/Proxy/isExtensible/trap-is-null-target-is-proxy.js new file mode 100644 index 0000000000..406c5969ea --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/isExtensible/trap-is-null-target-is-proxy.js @@ -0,0 +1,32 @@ +// Copyright (C) 2020 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-isextensible +description: > + If "isExtensible" trap is null or undefined, [[IsExtensible]] call is + properly forwarded to [[ProxyTarget]] (which is also a Proxy object). +info: | + [[IsExtensible]] ( ) + + [...] + 4. Let target be O.[[ProxyTarget]]. + 5. Let trap be ? GetMethod(handler, "isExtensible"). + 6. If trap is undefined, then + a. Return ? IsExtensible(target). + + IsExtensible ( O ) + + 1. Assert: Type(O) is Object. + 2. Return ? O.[[IsExtensible]](). +features: [Proxy] +---*/ + +var plainObjectTarget = new Proxy({}, {}); +var plainObjectProxy = new Proxy(plainObjectTarget, { + isExtensible: null, +}); + +assert(Object.isExtensible(plainObjectProxy)); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/isExtensible/trap-is-undefined-target-is-proxy.js b/js/src/tests/test262/built-ins/Proxy/isExtensible/trap-is-undefined-target-is-proxy.js new file mode 100644 index 0000000000..7830be1286 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/isExtensible/trap-is-undefined-target-is-proxy.js @@ -0,0 +1,51 @@ +// Copyright (C) 2020 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-isextensible +description: > + If "isExtensible" trap is null or undefined, [[IsExtensible]] call is + properly forwarded to [[ProxyTarget]] (which is also a Proxy object). +info: | + [[IsExtensible]] ( ) + + [...] + 4. Let target be O.[[ProxyTarget]]. + 5. Let trap be ? GetMethod(handler, "isExtensible"). + 6. If trap is undefined, then + a. Return ? IsExtensible(target). + + IsExtensible ( O ) + + 1. Assert: Type(O) is Object. + 2. Return ? O.[[IsExtensible]](). + + [[IsExtensible]] ( ) + + [...] + 7. Let booleanTrapResult be ! ToBoolean(? Call(trap, handler, « target »)). + [...] + 10. Return booleanTrapResult. +features: [Proxy] +---*/ + +var array = []; +var arrayExtensible = true; +var arrayTarget = new Proxy(array, { + isExtensible: function() { + return arrayExtensible; + }, +}); + +var arrayProxy = new Proxy(arrayTarget, { + isExtensible: undefined, +}); + +assert(Object.isExtensible(arrayProxy)); + +Object.preventExtensions(array); +arrayExtensible = false; + +assert(!Object.isExtensible(arrayProxy)); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/isExtensible/trap-is-undefined.js b/js/src/tests/test262/built-ins/Proxy/isExtensible/trap-is-undefined.js new file mode 100644 index 0000000000..e95601b80f --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/isExtensible/trap-is-undefined.js @@ -0,0 +1,26 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.3 +description: > + Return target.[[IsExtensible]]() if trap is undefined. +info: | + [[IsExtensible]] ( ) + + ... + 7. If trap is undefined, then + a. Return target.[[IsExtensible]](). + ... +features: [Proxy] +---*/ + +var target = {}; +var p = new Proxy(target, {}); + +assert.sameValue(Object.isExtensible(p), true); + +Object.preventExtensions(target); + +assert.sameValue(Object.isExtensible(p), false); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/length.js b/js/src/tests/test262/built-ins/Proxy/length.js new file mode 100644 index 0000000000..9bacc49713 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/length.js @@ -0,0 +1,20 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 26.2.2 +description: > + Properties of the Proxy Constructor + + Besides the length property (whose value is 2) + +includes: [propertyHelper.js] +features: [Proxy] +---*/ + +assert.sameValue(Proxy.length, 2, "The value of `Proxy.length` is `2`"); + +verifyNotEnumerable(Proxy, "length"); +verifyNotWritable(Proxy, "length"); +verifyConfigurable(Proxy, "length"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/name.js b/js/src/tests/test262/built-ins/Proxy/name.js new file mode 100644 index 0000000000..31d3ec097d --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/name.js @@ -0,0 +1,20 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 26.2.1.1 +description: > + Proxy ( target, handler ) + + 17 ECMAScript Standard Built-in Objects + +includes: [propertyHelper.js] +features: [Proxy] +---*/ + +assert.sameValue(Proxy.name, "Proxy", "The value of `Proxy.name` is `'Proxy'`"); + +verifyNotEnumerable(Proxy, "name"); +verifyNotWritable(Proxy, "name"); +verifyConfigurable(Proxy, "name"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/ownKeys/browser.js b/js/src/tests/test262/built-ins/Proxy/ownKeys/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/ownKeys/browser.js diff --git a/js/src/tests/test262/built-ins/Proxy/ownKeys/call-parameters-object-getownpropertynames.js b/js/src/tests/test262/built-ins/Proxy/ownKeys/call-parameters-object-getownpropertynames.js new file mode 100644 index 0000000000..556ad71dfd --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/ownKeys/call-parameters-object-getownpropertynames.js @@ -0,0 +1,35 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-ownpropertykeys +description: > + [[OwnPropertyKeys]] ( ) + + 7. Let trapResultArray be ? Call(trap, handler, « target »). +features: [Proxy] +---*/ + +var _target, _handler; +var target = { + foo: 1, + bar: 2 +}; + +var handler = { + ownKeys: function(t) { + _handler = this; + _target = t; + return Object.getOwnPropertyNames(t); + } +} +var p = new Proxy(target, handler); + +var names = Object.getOwnPropertyNames(p); + +assert.sameValue(names[0], "foo"); +assert.sameValue(names[1], "bar"); +assert.sameValue(names.length, 2); +assert.sameValue(_handler, handler); +assert.sameValue(_target, target); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/ownKeys/call-parameters-object-getownpropertysymbols.js b/js/src/tests/test262/built-ins/Proxy/ownKeys/call-parameters-object-getownpropertysymbols.js new file mode 100644 index 0000000000..6b79a2fb70 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/ownKeys/call-parameters-object-getownpropertysymbols.js @@ -0,0 +1,38 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-ownpropertykeys +description: > + [[OwnPropertyKeys]] ( ) + + 7. Let trapResultArray be ? Call(trap, handler, « target »). + +features: [Proxy, Symbol] +---*/ + +var _target, _handler; +var target = {}; +var a = Symbol('a'); +var b = Symbol('b'); + +target[a] = 1; +target[b] = 2; + +var handler = { + ownKeys: function(t) { + _handler = this; + _target = t; + return Object.getOwnPropertySymbols(t); + } +} +var p = new Proxy(target, handler); + +var symbols = Object.getOwnPropertySymbols(p); + +assert.sameValue(symbols[0], a); +assert.sameValue(symbols[1], b); +assert.sameValue(symbols.length, 2); +assert.sameValue(_handler, handler); +assert.sameValue(_target, target); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/ownKeys/call-parameters-object-keys.js b/js/src/tests/test262/built-ins/Proxy/ownKeys/call-parameters-object-keys.js new file mode 100644 index 0000000000..6277f0c8cd --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/ownKeys/call-parameters-object-keys.js @@ -0,0 +1,34 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-ownpropertykeys +description: > + [[OwnPropertyKeys]] ( ) + + 7. Let trapResultArray be ? Call(trap, handler, « target »). +features: [Proxy] +---*/ + +var _target, _handler; +var target = { + foo: 1, + bar: 2 +}; +var handler = { + ownKeys: function(t) { + _handler = this; + _target = t; + return Object.keys(t); + } +}; +var p = new Proxy(target, handler); + +var keys = Object.keys(p); + +assert.sameValue(keys[0], "foo"); +assert.sameValue(keys[1], "bar"); +assert.sameValue(keys.length, 2); +assert.sameValue(_handler, handler); +assert.sameValue(_target, target); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/ownKeys/extensible-return-trap-result-absent-not-configurable-keys.js b/js/src/tests/test262/built-ins/Proxy/ownKeys/extensible-return-trap-result-absent-not-configurable-keys.js new file mode 100644 index 0000000000..8037edd33e --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/ownKeys/extensible-return-trap-result-absent-not-configurable-keys.js @@ -0,0 +1,32 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-ownpropertykeys +description: > + If target is extensible, return the non-falsy trap result if target doesn't + contain any non-configurable keys. +info: | + [[OwnPropertyKeys]] ( ) + + ... + 15. If extensibleTarget is true and targetNonconfigurableKeys is empty, then + a. Return trapResult. +features: [Proxy] +---*/ + +var p = new Proxy({ + attr: 42 +}, { + ownKeys: function() { + return ["foo", "bar"]; + } +}); + +var keys = Object.getOwnPropertyNames(p); + +assert.sameValue(keys[0], "foo"); +assert.sameValue(keys[1], "bar"); + +assert.sameValue(keys.length, 2); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/ownKeys/extensible-return-trap-result.js b/js/src/tests/test262/built-ins/Proxy/ownKeys/extensible-return-trap-result.js new file mode 100644 index 0000000000..e4f43ddd44 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/ownKeys/extensible-return-trap-result.js @@ -0,0 +1,37 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-ownpropertykeys +description: > + If target is extensible, return the non-falsy trap result if it contains all + of target's non-configurable keys. +info: | + [[OwnPropertyKeys]] ( ) + + ... + 18. If extensibleTarget is true, return trapResult. +features: [Proxy] +---*/ + +var target = {}; + +Object.defineProperty(target, "foo", { + configurable: false, + enumerable: true, + value: true +}); + +var p = new Proxy(target, { + ownKeys: function() { + return ["foo", "bar"]; + } +}); + +var keys = Object.getOwnPropertyNames(p); + +assert.sameValue(keys[0], "foo"); +assert.sameValue(keys[1], "bar"); + +assert.sameValue(keys.length, 2); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/ownKeys/not-extensible-missing-keys-throws.js b/js/src/tests/test262/built-ins/Proxy/ownKeys/not-extensible-missing-keys-throws.js new file mode 100644 index 0000000000..c18605198c --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/ownKeys/not-extensible-missing-keys-throws.js @@ -0,0 +1,35 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-ownpropertykeys +description: > + If target is not extensible, the result must contain all the keys of the own + properties of the target object. +info: | + [[OwnPropertyKeys]] ( ) + + ... + 19. For each key that is an element of targetConfigurableKeys, do + a. If key is not an element of uncheckedResultKeys, throw a TypeError + exception. +features: [Proxy] +---*/ + +var target = { + foo: 1, + bar: 2 +}; + +var p = new Proxy(target, { + ownKeys: function() { + return ["foo"]; + } +}); + +Object.preventExtensions(target); + +assert.throws(TypeError, function() { + Object.keys(p); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/ownKeys/not-extensible-new-keys-throws.js b/js/src/tests/test262/built-ins/Proxy/ownKeys/not-extensible-new-keys-throws.js new file mode 100644 index 0000000000..dda61a8aab --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/ownKeys/not-extensible-new-keys-throws.js @@ -0,0 +1,32 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-ownpropertykeys +description: > + If target is not extensible, the result can't contain keys names not + contained in the target object. +info: | + [[OwnPropertyKeys]] ( ) + + ... + 20. If uncheckedResultKeys is not empty, throw a TypeError exception. +features: [Proxy] +---*/ + +var target = { + foo: 1 +}; + +var p = new Proxy(target, { + ownKeys: function() { + return ["foo", "bar"]; + } +}); + +Object.preventExtensions(target); + +assert.throws(TypeError, function() { + Object.keys(p); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/ownKeys/not-extensible-return-keys.js b/js/src/tests/test262/built-ins/Proxy/ownKeys/not-extensible-return-keys.js new file mode 100644 index 0000000000..640264b8b0 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/ownKeys/not-extensible-return-keys.js @@ -0,0 +1,36 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-ownpropertykeys +description: > + If target is not extensible, the result must contain all the keys of the own + properties of the target object and no other values +info: | + [[OwnPropertyKeys]] ( ) + + ... + 21. Return trapResult. +features: [Proxy] +---*/ + +var target = { + foo: 1, + bar: 2 +}; + +var p = new Proxy(target, { + ownKeys: function() { + return ["foo", "bar"]; + } +}); + +Object.preventExtensions(target); + +var keys = Object.getOwnPropertyNames(p); + +assert.sameValue(keys[0], "foo"); +assert.sameValue(keys[1], "bar"); + +assert.sameValue(keys.length, 2); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/ownKeys/null-handler.js b/js/src/tests/test262/built-ins/Proxy/ownKeys/null-handler.js new file mode 100644 index 0000000000..f28f8ec52f --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/ownKeys/null-handler.js @@ -0,0 +1,20 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-ownpropertykeys +description: > + [[OwnPropertyKeys]] ( ) + + 2. If handler is null, throw a TypeError exception. +features: [Proxy] +---*/ + +var p = Proxy.revocable({}, {}); + +p.revoke(); + +assert.throws(TypeError, function() { + Object.keys(p.proxy); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/ownKeys/return-all-non-configurable-keys.js b/js/src/tests/test262/built-ins/Proxy/ownKeys/return-all-non-configurable-keys.js new file mode 100644 index 0000000000..e14b210b12 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/ownKeys/return-all-non-configurable-keys.js @@ -0,0 +1,39 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-ownpropertykeys +description: > + The result List must contain the keys of all non-configurable own properties + of the target object. +info: | + [[OwnPropertyKeys]] ( ) + + ... + 17. For each key that is an element of targetNonconfigurableKeys, do + a. If key is not an element of uncheckedResultKeys, throw a TypeError + exception. + +features: [Proxy] +---*/ + +var target = { + foo: 1 +}; + +Object.defineProperty(target, "attr", { + configurable: false, + enumerable: true, + value: true +}); + +var p = new Proxy(target, { + ownKeys: function() { + return ["foo"]; + } +}); + +assert.throws(TypeError, function() { + Object.keys(p); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/ownKeys/return-duplicate-entries-throws.js b/js/src/tests/test262/built-ins/Proxy/ownKeys/return-duplicate-entries-throws.js new file mode 100644 index 0000000000..a1c2c8aad6 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/ownKeys/return-duplicate-entries-throws.js @@ -0,0 +1,25 @@ +// Copyright (C) 2017 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-ownpropertykeys +description: > + The returned list must not contain any duplicate entries. +info: | + [[OwnPropertyKeys]] ( ) + + ... + 9. If trapResult contains any duplicate entries, throw a TypeError exception. +features: [Proxy] +---*/ + +var p = new Proxy({}, { + ownKeys: function() { + return ["a", "a"]; + } +}); + +assert.throws(TypeError, function() { + Object.keys(p); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/ownKeys/return-duplicate-symbol-entries-throws.js b/js/src/tests/test262/built-ins/Proxy/ownKeys/return-duplicate-symbol-entries-throws.js new file mode 100644 index 0000000000..09d2697890 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/ownKeys/return-duplicate-symbol-entries-throws.js @@ -0,0 +1,26 @@ +// Copyright (C) 2017 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-ownpropertykeys +description: > + The returned list must not contain any duplicate entries. +info: | + [[OwnPropertyKeys]] ( ) + + ... + 9. If trapResult contains any duplicate entries, throw a TypeError exception. +features: [Proxy, Symbol] +---*/ + +var s = Symbol(); +var p = new Proxy({}, { + ownKeys: function() { + return [s, s]; + } +}); + +assert.throws(TypeError, function() { + Object.keys(p); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/ownKeys/return-is-abrupt.js b/js/src/tests/test262/built-ins/Proxy/ownKeys/return-is-abrupt.js new file mode 100644 index 0000000000..673d40ec0a --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/ownKeys/return-is-abrupt.js @@ -0,0 +1,27 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-ownpropertykeys +description: > + Trap returns abrupt. +info: | + [[OwnPropertyKeys]] ( ) + + ... + 7. Let trapResultArray be ? Call(trap, handler, « target »). + 8. Let trapResult be ? CreateListFromArrayLike(trapResultArray, « String, Symbol »). + +features: [Proxy] +---*/ + +var p = new Proxy({}, { + ownKeys: function() { + throw new Test262Error(); + } +}); + +assert.throws(Test262Error, function() { + Object.keys(p); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/ownKeys/return-not-list-object-throws-realm.js b/js/src/tests/test262/built-ins/Proxy/ownKeys/return-not-list-object-throws-realm.js new file mode 100644 index 0000000000..efe0aabcd5 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/ownKeys/return-not-list-object-throws-realm.js @@ -0,0 +1,34 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-ownpropertykeys +description: > + If return is not a list object, throw a TypeError exception (honoring + the Realm of the current execution context) +info: | + ... + 7. Let trapResultArray be ? Call(trap, handler, « target »). + 8. Let trapResult be ? CreateListFromArrayLike(trapResultArray, « String, + Symbol »). + ... + + #sec-createlistfromarraylike + 7.3.17 CreateListFromArrayLike (obj [, elementTypes] ) + + 2. If Type(obj) is not Object, throw a TypeError exception. + +features: [cross-realm, Proxy, Symbol] +---*/ + +var other = $262.createRealm().global; +var p = new other.Proxy({}, { + ownKeys: function() { + return undefined; + } +}); + +assert.throws(TypeError, function() { + Object.keys(p); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/ownKeys/return-not-list-object-throws.js b/js/src/tests/test262/built-ins/Proxy/ownKeys/return-not-list-object-throws.js new file mode 100644 index 0000000000..858ca75c89 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/ownKeys/return-not-list-object-throws.js @@ -0,0 +1,34 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-ownpropertykeys +description: > + If return is not a list object, throw a TypeError exception +info: | + [[OwnPropertyKeys]] ( ) + + 7. Let trapResultArray be ? Call(trap, handler, « target »). + 8. Let trapResult be ? CreateListFromArrayLike(trapResultArray, « String, + Symbol »). + ... + + #sec-createlistfromarraylike + 7.3.17 CreateListFromArrayLike (obj [, elementTypes] ) + + 2. If Type(obj) is not Object, throw a TypeError exception. + +features: [Proxy, Symbol] +---*/ + +var target = {}; +var p = new Proxy(target, { + ownKeys: function() { + return undefined; + } +}); + +assert.throws(TypeError, function() { + Object.keys(p); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/ownKeys/return-type-throws-array.js b/js/src/tests/test262/built-ins/Proxy/ownKeys/return-type-throws-array.js new file mode 100644 index 0000000000..37fb021f30 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/ownKeys/return-type-throws-array.js @@ -0,0 +1,39 @@ +// Copyright (C) 2017 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-ownpropertykeys +description: > + The returned list must not have entries whose type does not match + « String, Symbol ». +info: | + [[OwnPropertyKeys]] ( ) + + ... + 7. Let trapResultArray be ? Call(trap, handler, « target »). + 8. Let trapResult be ? + CreateListFromArrayLike(trapResultArray, « String, Symbol »). + ... + + CreateListFromArrayLike ( obj [ , elementTypes ] ) + + ... + 6. Repeat, while index < len + ... + d. If Type(next) is not an element of elementTypes, + throw a TypeError exception. +features: [Proxy] +---*/ + +var p = new Proxy({}, { + ownKeys: function() { + return [ + [] + ]; + } +}); + +assert.throws(TypeError, function() { + Object.keys(p); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/ownKeys/return-type-throws-boolean.js b/js/src/tests/test262/built-ins/Proxy/ownKeys/return-type-throws-boolean.js new file mode 100644 index 0000000000..b4755c9f9d --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/ownKeys/return-type-throws-boolean.js @@ -0,0 +1,37 @@ +// Copyright (C) 2017 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-ownpropertykeys +description: > + The returned list must not have entries whose type does not match + « String, Symbol ». +info: | + [[OwnPropertyKeys]] ( ) + + ... + 7. Let trapResultArray be ? Call(trap, handler, « target »). + 8. Let trapResult be ? + CreateListFromArrayLike(trapResultArray, « String, Symbol »). + ... + + CreateListFromArrayLike ( obj [ , elementTypes ] ) + + ... + 6. Repeat, while index < len + ... + d. If Type(next) is not an element of elementTypes, + throw a TypeError exception. +features: [Proxy] +---*/ + +var p = new Proxy({}, { + ownKeys: function() { + return [true]; + } +}); + +assert.throws(TypeError, function() { + Object.keys(p); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/ownKeys/return-type-throws-null.js b/js/src/tests/test262/built-ins/Proxy/ownKeys/return-type-throws-null.js new file mode 100644 index 0000000000..3bb2aac425 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/ownKeys/return-type-throws-null.js @@ -0,0 +1,37 @@ +// Copyright (C) 2017 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-ownpropertykeys +description: > + The returned list must not have entries whose type does not match + « String, Symbol ». +info: | + [[OwnPropertyKeys]] ( ) + + ... + 7. Let trapResultArray be ? Call(trap, handler, « target »). + 8. Let trapResult be ? + CreateListFromArrayLike(trapResultArray, « String, Symbol »). + ... + + CreateListFromArrayLike ( obj [ , elementTypes ] ) + + ... + 6. Repeat, while index < len + ... + d. If Type(next) is not an element of elementTypes, + throw a TypeError exception. +features: [Proxy] +---*/ + +var p = new Proxy({}, { + ownKeys: function() { + return [null]; + } +}); + +assert.throws(TypeError, function() { + Object.keys(p); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/ownKeys/return-type-throws-number.js b/js/src/tests/test262/built-ins/Proxy/ownKeys/return-type-throws-number.js new file mode 100644 index 0000000000..b576e027ec --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/ownKeys/return-type-throws-number.js @@ -0,0 +1,37 @@ +// Copyright (C) 2017 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-ownpropertykeys +description: > + The returned list must not have entries whose type does not match + « String, Symbol ». +info: | + [[OwnPropertyKeys]] ( ) + + ... + 7. Let trapResultArray be ? Call(trap, handler, « target »). + 8. Let trapResult be ? + CreateListFromArrayLike(trapResultArray, « String, Symbol »). + ... + + CreateListFromArrayLike ( obj [ , elementTypes ] ) + + ... + 6. Repeat, while index < len + ... + d. If Type(next) is not an element of elementTypes, + throw a TypeError exception. +features: [Proxy] +---*/ + +var p = new Proxy({}, { + ownKeys: function() { + return [1]; + } +}); + +assert.throws(TypeError, function() { + Object.keys(p); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/ownKeys/return-type-throws-object.js b/js/src/tests/test262/built-ins/Proxy/ownKeys/return-type-throws-object.js new file mode 100644 index 0000000000..18d80e88a7 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/ownKeys/return-type-throws-object.js @@ -0,0 +1,37 @@ +// Copyright (C) 2017 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-ownpropertykeys +description: > + The returned list must not have entries whose type does not match + « String, Symbol ». +info: | + [[OwnPropertyKeys]] ( ) + + ... + 7. Let trapResultArray be ? Call(trap, handler, « target »). + 8. Let trapResult be ? + CreateListFromArrayLike(trapResultArray, « String, Symbol »). + ... + + CreateListFromArrayLike ( obj [ , elementTypes ] ) + + ... + 6. Repeat, while index < len + ... + d. If Type(next) is not an element of elementTypes, + throw a TypeError exception. +features: [Proxy] +---*/ + +var p = new Proxy({}, { + ownKeys: function() { + return [{}]; + } +}); + +assert.throws(TypeError, function() { + Object.keys(p); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/ownKeys/return-type-throws-undefined.js b/js/src/tests/test262/built-ins/Proxy/ownKeys/return-type-throws-undefined.js new file mode 100644 index 0000000000..bd1e8be030 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/ownKeys/return-type-throws-undefined.js @@ -0,0 +1,37 @@ +// Copyright (C) 2017 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-ownpropertykeys +description: > + The returned list must not have entries whose type does not match + « String, Symbol ». +info: | + [[OwnPropertyKeys]] ( ) + + ... + 7. Let trapResultArray be ? Call(trap, handler, « target »). + 8. Let trapResult be ? + CreateListFromArrayLike(trapResultArray, « String, Symbol »). + ... + + CreateListFromArrayLike ( obj [ , elementTypes ] ) + + ... + 6. Repeat, while index < len + ... + d. If Type(next) is not an element of elementTypes, + throw a TypeError exception. +features: [Proxy] +---*/ + +var p = new Proxy({}, { + ownKeys: function() { + return [undefined]; + } +}); + +assert.throws(TypeError, function() { + Object.keys(p); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/ownKeys/shell.js b/js/src/tests/test262/built-ins/Proxy/ownKeys/shell.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/ownKeys/shell.js diff --git a/js/src/tests/test262/built-ins/Proxy/ownKeys/trap-is-missing-target-is-proxy.js b/js/src/tests/test262/built-ins/Proxy/ownKeys/trap-is-missing-target-is-proxy.js new file mode 100644 index 0000000000..0d189524f2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/ownKeys/trap-is-missing-target-is-proxy.js @@ -0,0 +1,48 @@ +// Copyright (C) 2020 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-ownpropertykeys +description: > + If "ownKeys" trap is null or undefined, [[OwnPropertyKeys]] call is + properly forwarded to [[ProxyTarget]] (which is also a Proxy object). +info: | + [[OwnPropertyKeys]] ( ) + + [...] + 4. Let target be O.[[ProxyTarget]]. + 5. Let trap be ? GetMethod(handler, "ownKeys"). + 6. If trap is undefined, then + a. Return ? target.[[OwnPropertyKeys]](). + + [[OwnPropertyKeys]] ( ) + + 1. Let keys be a new empty List. + [...] + 5. For each integer i starting with 0 such that i < len, in ascending order, do + a. Add ! ToString(i) as the last element of keys. + [...] + 7. For each own property key P of O such that Type(P) is String and P is not an + array index, in ascending chronological order of property creation, do + a. Add P as the last element of keys. + 8. For each own property key P of O such that Type(P) is Symbol, in ascending + chronological order of property creation, do + a. Add P as the last element of keys. + 9. Return keys. +includes: [compareArray.js] +features: [Symbol, Proxy, Reflect] +---*/ + +var sym = Symbol(); +var string = new String("str"); +string[sym] = 1; + +var stringTarget = new Proxy(string, {}); +var stringProxy = new Proxy(stringTarget, {}); + +assert.compareArray( + Reflect.ownKeys(stringProxy), + ["0", "1", "2", "length", sym] +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/ownKeys/trap-is-not-callable-realm.js b/js/src/tests/test262/built-ins/Proxy/ownKeys/trap-is-not-callable-realm.js new file mode 100644 index 0000000000..df9f37abdf --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/ownKeys/trap-is-not-callable-realm.js @@ -0,0 +1,32 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-ownpropertykeys +description: > + Throws if trap is not callable (honoring the Realm of the current execution + context) +info: | + [[OwnPropertyKeys]] ( ) + + 5. Let trap be GetMethod(handler, "ownKeys"). + ... + + #sec-getmethod + 7.3.9 GetMethod (O, P) + + 4. If IsCallable(func) is false, throw a TypeError exception. +features: [cross-realm, Proxy] +---*/ + +var OProxy = $262.createRealm().global.Proxy; +var p = new OProxy({ + attr: 1 +}, { + ownKeys: {} +}); + +assert.throws(TypeError, function() { + Object.keys(p); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/ownKeys/trap-is-not-callable.js b/js/src/tests/test262/built-ins/Proxy/ownKeys/trap-is-not-callable.js new file mode 100644 index 0000000000..fefd983c8d --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/ownKeys/trap-is-not-callable.js @@ -0,0 +1,30 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-ownpropertykeys +description: > + Trap is not callable. +info: | + [[OwnPropertyKeys]] ( ) + + 5. Let trap be ? GetMethod(handler, "ownKeys"). + ... + + #sec-getmethod + 7.3.9 GetMethod (O, P) + + 4. If IsCallable(func) is false, throw a TypeError exception. +features: [Proxy] +---*/ + +var p = new Proxy({ + attr: 1 +}, { + ownKeys: {} +}); + +assert.throws(TypeError, function() { + Object.keys(p); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/ownKeys/trap-is-null-target-is-proxy.js b/js/src/tests/test262/built-ins/Proxy/ownKeys/trap-is-null-target-is-proxy.js new file mode 100644 index 0000000000..ea5a1ddb08 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/ownKeys/trap-is-null-target-is-proxy.js @@ -0,0 +1,50 @@ +// Copyright (C) 2020 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-ownpropertykeys +description: > + If "ownKeys" trap is null or undefined, [[OwnPropertyKeys]] call is + properly forwarded to [[ProxyTarget]] (which is also a Proxy object). +info: | + [[OwnPropertyKeys]] ( ) + + [...] + 4. Let target be O.[[ProxyTarget]]. + 5. Let trap be ? GetMethod(handler, "ownKeys"). + 6. If trap is undefined, then + a. Return ? target.[[OwnPropertyKeys]](). + + OrdinaryOwnPropertyKeys ( O ) + + 1. Let keys be a new empty List. + 2. For each own property key P of O that is an array index, + in ascending numeric index order, do + a. Add P as the last element of keys. + 3. For each own property key P of O that is a String but is not an + array index, in ascending chronological order of property creation, do + a. Add P as the last element of keys. + [...] + 5. Return keys. +includes: [compareArray.js] +features: [Proxy] +---*/ + +var plainObject = { + foo: 1, + "0": 2, + get bar() {}, + "1": 4, +}; + +var plainObjectTarget = new Proxy(plainObject, {}); +var plainObjectProxy = new Proxy(plainObjectTarget, { + ownKeys: null, +}); + +assert.compareArray( + Object.keys(plainObjectProxy), + ["0", "1", "foo", "bar"] +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/ownKeys/trap-is-undefined-target-is-proxy.js b/js/src/tests/test262/built-ins/Proxy/ownKeys/trap-is-undefined-target-is-proxy.js new file mode 100644 index 0000000000..1ffb92a119 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/ownKeys/trap-is-undefined-target-is-proxy.js @@ -0,0 +1,42 @@ +// Copyright (C) 2020 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-ownpropertykeys +description: > + If "ownKeys" trap is null or undefined, [[OwnPropertyKeys]] call is + properly forwarded to [[ProxyTarget]] (which is also a Proxy object). +info: | + [[OwnPropertyKeys]] ( ) + + [...] + 4. Let target be O.[[ProxyTarget]]. + 5. Let trap be ? GetMethod(handler, "ownKeys"). + 6. If trap is undefined, then + a. Return ? target.[[OwnPropertyKeys]](). + + [[OwnPropertyKeys]] ( ) + + [...] + 7. Let trapResultArray be ? Call(trap, handler, « target »). + 8. Let trapResult be ? CreateListFromArrayLike(trapResultArray, « String, Symbol »). + [...] + 23. Return trapResult. +includes: [compareArray.js] +features: [Symbol, Proxy, Reflect] +---*/ + +var trapResult = [Symbol(), "length", "foo", "0"]; +var target = new Proxy([], { + ownKeys: function(_target) { + return trapResult; + }, +}); + +var proxy = new Proxy(target, { + ownKeys: undefined, +}); + +assert.compareArray(Reflect.ownKeys(proxy), trapResult); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/ownKeys/trap-is-undefined.js b/js/src/tests/test262/built-ins/Proxy/ownKeys/trap-is-undefined.js new file mode 100644 index 0000000000..84e2db2098 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/ownKeys/trap-is-undefined.js @@ -0,0 +1,25 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-ownpropertykeys +description: > + [[OwnPropertyKeys]] ( ) + + 6. If trap is undefined, then Return target.[[OwnPropertyKeys]]() +features: [Proxy] +---*/ + +var target = { + foo: 1, + bar: 2 +}; +var p = new Proxy(target, {}); + +var keys = Object.getOwnPropertyNames(p); + +assert.sameValue(keys[0], "foo"); +assert.sameValue(keys[1], "bar"); + +assert.sameValue(keys.length, 2); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/preventExtensions/browser.js b/js/src/tests/test262/built-ins/Proxy/preventExtensions/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/preventExtensions/browser.js diff --git a/js/src/tests/test262/built-ins/Proxy/preventExtensions/call-parameters.js b/js/src/tests/test262/built-ins/Proxy/preventExtensions/call-parameters.js new file mode 100644 index 0000000000..77dd0b70b9 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/preventExtensions/call-parameters.js @@ -0,0 +1,34 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.4 +description: > + Trap is called with handler on its context and target as the first + parameter. +info: | + [[PreventExtensions]] ( ) + + ... + 8. Let booleanTrapResult be ToBoolean(Call(trap, handler, «target»)). + ... +features: [Proxy] +---*/ + +var _target, _handler; +var target = {}; +var handler = { + preventExtensions: function(t) { + _handler = this; + _target = t; + + return Object.preventExtensions(target); + } +}; +var p = new Proxy(target, handler); + +Object.preventExtensions(p); + +assert.sameValue(_handler, handler); +assert.sameValue(_target, target); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/preventExtensions/null-handler.js b/js/src/tests/test262/built-ins/Proxy/preventExtensions/null-handler.js new file mode 100644 index 0000000000..695808bb19 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/preventExtensions/null-handler.js @@ -0,0 +1,18 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.4 +description: > + Throws a TypeError exception if handler is null. +features: [Proxy] +---*/ + +var p = Proxy.revocable({}, {}); + +p.revoke(); + +assert.throws(TypeError, function() { + Object.preventExtensions(p.proxy); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/preventExtensions/return-false.js b/js/src/tests/test262/built-ins/Proxy/preventExtensions/return-false.js new file mode 100644 index 0000000000..a15f57b7fe --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/preventExtensions/return-false.js @@ -0,0 +1,23 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.4 +description: > + If boolean trap result if false, return false. +features: [Proxy, Reflect] +---*/ + +var target = {}; +var p = new Proxy({}, { + preventExtensions: function(t) { + return 0; + } +}); + +assert.sameValue(Reflect.preventExtensions(p), false); + +Object.preventExtensions(target); + +assert.sameValue(Reflect.preventExtensions(p), false); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/preventExtensions/return-is-abrupt.js b/js/src/tests/test262/built-ins/Proxy/preventExtensions/return-is-abrupt.js new file mode 100644 index 0000000000..a120c3685c --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/preventExtensions/return-is-abrupt.js @@ -0,0 +1,27 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.4 +description: > + Trap returns abrupt. +info: | + [[PreventExtensions]] ( ) + + ... + 8. Let booleanTrapResult be ToBoolean(Call(trap, handler, «target»)). + 9. ReturnIfAbrupt(booleanTrapResult). + ... +features: [Proxy] +---*/ + +var p = new Proxy({}, { + preventExtensions: function(t) { + throw new Test262Error(); + } +}); + +assert.throws(Test262Error, function() { + Object.preventExtensions(p); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/preventExtensions/return-true-target-is-extensible.js b/js/src/tests/test262/built-ins/Proxy/preventExtensions/return-true-target-is-extensible.js new file mode 100644 index 0000000000..3e0614d18a --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/preventExtensions/return-true-target-is-extensible.js @@ -0,0 +1,30 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.4 +description: > + Throws a TypeError exception if boolean trap result is true and target is + extensible. +info: | + [[PreventExtensions]] ( ) + + ... + 10. If booleanTrapResult is true, then + ... + c. If targetIsExtensible is true, throw a TypeError exception. + 11. Return booleanTrapResult. + ... +features: [Proxy] +---*/ + +var p = new Proxy({}, { + preventExtensions: function(t) { + return true; + } +}); + +assert.throws(TypeError, function() { + Object.preventExtensions(p); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/preventExtensions/return-true-target-is-not-extensible.js b/js/src/tests/test262/built-ins/Proxy/preventExtensions/return-true-target-is-not-extensible.js new file mode 100644 index 0000000000..35966b8acc --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/preventExtensions/return-true-target-is-not-extensible.js @@ -0,0 +1,21 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.4 +description: > + Return boolean trap result if its true and target is not extensible. +features: [Proxy, Reflect] +---*/ + +var target = {}; +var p = new Proxy(target, { + preventExtensions: function(t) { + return 1; + } +}); + +Object.preventExtensions(target); + +assert(Reflect.preventExtensions(p)); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/preventExtensions/shell.js b/js/src/tests/test262/built-ins/Proxy/preventExtensions/shell.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/preventExtensions/shell.js diff --git a/js/src/tests/test262/built-ins/Proxy/preventExtensions/trap-is-missing-target-is-proxy.js b/js/src/tests/test262/built-ins/Proxy/preventExtensions/trap-is-missing-target-is-proxy.js new file mode 100644 index 0000000000..908029e0a4 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/preventExtensions/trap-is-missing-target-is-proxy.js @@ -0,0 +1,32 @@ +// Copyright (C) 2020 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-preventextensions +description: > + If "preventExtensions" trap is null or undefined, [[PreventExtensions]] call + is properly forwarded to [[ProxyTarget]] (which is also a Proxy object). +info: | + [[PreventExtensions]] ( ) + + [...] + 4. Let target be O.[[ProxyTarget]]. + 5. Let trap be ? GetMethod(handler, "preventExtensions"). + 6. If trap is undefined, then + a. Return ? target.[[PreventExtensions]](). +features: [Proxy] +---*/ + +var target = new Proxy({}, { + preventExtensions: function(_target) { + return false; + }, +}); + +var proxy = new Proxy(target, {}); + +assert.throws(TypeError, function() { + Object.preventExtensions(proxy); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/preventExtensions/trap-is-not-callable-realm.js b/js/src/tests/test262/built-ins/Proxy/preventExtensions/trap-is-not-callable-realm.js new file mode 100644 index 0000000000..f08292862d --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/preventExtensions/trap-is-not-callable-realm.js @@ -0,0 +1,33 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-preventextensions +description: > + Throws if trap is not callable (honoring the Realm of the current execution + context) +info: | + [[PreventExtensions]] ( ) + + ... + 1. Let handler be the value of the [[ProxyHandler]] internal slot of O. + ... + 5. Let trap be GetMethod(handler, "preventExtensions"). + ... + 7.3.9 GetMethod (O, P) + ... + 2. Let func be GetV(O, P). + 5. If IsCallable(func) is false, throw a TypeError exception. + ... +features: [cross-realm, Proxy] +---*/ + +var OProxy = $262.createRealm().global.Proxy; +var p = new OProxy({}, { + preventExtensions: {} +}); + +assert.throws(TypeError, function() { + Object.preventExtensions(p); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/preventExtensions/trap-is-not-callable.js b/js/src/tests/test262/built-ins/Proxy/preventExtensions/trap-is-not-callable.js new file mode 100644 index 0000000000..e6d23e969b --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/preventExtensions/trap-is-not-callable.js @@ -0,0 +1,32 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.4 +description: > + Throws a TypeError exception if trap is not callable. +info: | + [[PreventExtensions]] ( ) + + ... + 1. Let handler be the value of the [[ProxyHandler]] internal slot of O. + ... + 5. Let trap be GetMethod(handler, "preventExtensions"). + ... + 7.3.9 GetMethod (O, P) + ... + 2. Let func be GetV(O, P). + 5. If IsCallable(func) is false, throw a TypeError exception. + ... +features: [Proxy] +---*/ + +var target = {}; +var p = new Proxy(target, { + preventExtensions: {} +}); + +assert.throws(TypeError, function() { + Object.preventExtensions(p); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/preventExtensions/trap-is-null-target-is-proxy.js b/js/src/tests/test262/built-ins/Proxy/preventExtensions/trap-is-null-target-is-proxy.js new file mode 100644 index 0000000000..c35cf085b1 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/preventExtensions/trap-is-null-target-is-proxy.js @@ -0,0 +1,29 @@ +// Copyright (C) 2020 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-preventextensions +description: > + If "preventExtensions" trap is null or undefined, [[PreventExtensions]] call + is properly forwarded to [[ProxyTarget]] (which is also a Proxy object). +info: | + [[PreventExtensions]] ( ) + + [...] + 4. Let target be O.[[ProxyTarget]]. + 5. Let trap be ? GetMethod(handler, "preventExtensions"). + 6. If trap is undefined, then + a. Return ? target.[[PreventExtensions]](). +features: [Proxy] +---*/ + +var plainObject = {}; +var plainObjectTarget = new Proxy(plainObject, {}); +var plainObjectProxy = new Proxy(plainObjectTarget, { + preventExtensions: null, +}); + +Object.preventExtensions(plainObjectProxy); +assert(!Object.isExtensible(plainObject)); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/preventExtensions/trap-is-undefined-target-is-proxy.js b/js/src/tests/test262/built-ins/Proxy/preventExtensions/trap-is-undefined-target-is-proxy.js new file mode 100644 index 0000000000..4eda6cef6b --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/preventExtensions/trap-is-undefined-target-is-proxy.js @@ -0,0 +1,35 @@ +// |reftest| module +// Copyright (C) 2020 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-preventextensions +description: > + If "preventExtensions" trap is null or undefined, [[PreventExtensions]] call + is properly forwarded to [[ProxyTarget]] (which is also a Proxy object). +info: | + [[PreventExtensions]] ( ) + + [...] + 4. Let target be O.[[ProxyTarget]]. + 5. Let trap be ? GetMethod(handler, "preventExtensions"). + 6. If trap is undefined, then + a. Return ? target.[[PreventExtensions]](). + + [[PreventExtensions]] ( ) + + 1. Return true. +features: [Proxy, Reflect] +flags: [module] +---*/ + +import * as ns from "./trap-is-undefined-target-is-proxy.js"; + +var nsTarget = new Proxy(ns, {}); +var nsProxy = new Proxy(nsTarget, { + preventExtensions: undefined, +}); + +assert(Reflect.preventExtensions(nsProxy)); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/preventExtensions/trap-is-undefined.js b/js/src/tests/test262/built-ins/Proxy/preventExtensions/trap-is-undefined.js new file mode 100644 index 0000000000..234bb0945f --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/preventExtensions/trap-is-undefined.js @@ -0,0 +1,15 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.4 +description: > + Return target.[[PreventExtensions]]() if target is undefined. +features: [Proxy, Reflect] +---*/ + +var target = {}; +var p = new Proxy(target, {}); + +assert.sameValue(Reflect.preventExtensions(p), true); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/property-order.js b/js/src/tests/test262/built-ins/Proxy/property-order.js new file mode 100644 index 0000000000..73b46ced6b --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/property-order.js @@ -0,0 +1,18 @@ +// Copyright (C) 2020 ExE Boss. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-createbuiltinfunction +description: Proxy constructor property order +info: | + Set order: "length", "name", ... +features: [Proxy] +---*/ + +var propNames = Object.getOwnPropertyNames(Proxy); +var lengthIndex = propNames.indexOf("length"); +var nameIndex = propNames.indexOf("name"); + +assert(lengthIndex >= 0 && nameIndex === lengthIndex + 1, + "The `length` property comes before the `name` property on built-in functions"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/proxy-newtarget.js b/js/src/tests/test262/built-ins/Proxy/proxy-newtarget.js new file mode 100644 index 0000000000..cadbbc8744 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/proxy-newtarget.js @@ -0,0 +1,31 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 26.2.1.1 +description: > + Proxy ( target, handler ) + + When Proxy is called with arguments target and handler performs + the following steps: + + ... + 2. Return ProxyCreate(target, handler). (9.5.15) + ... + 9.5.15 ProxyCreate(target, handler) + ... + 5. Let P be a newly created object. + ... + 10. Return P. + +features: [Proxy] +---*/ + +var p1 = new Proxy({}, {}); + +assert.sameValue( + typeof p1, + 'object', + 'Return a newly created Object' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/proxy-no-prototype.js b/js/src/tests/test262/built-ins/Proxy/proxy-no-prototype.js new file mode 100644 index 0000000000..187f8e2fd9 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/proxy-no-prototype.js @@ -0,0 +1,17 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 26.2.2 +description: > + The Proxy constructor does not have a prototype property because + proxy exotic objects do not have a [[Prototype]] internal slot + that requires initialization. +features: [Proxy] +---*/ + +assert( + !Object.prototype.hasOwnProperty.call(Proxy, 'prototype'), + "Proxy constructor does not have a prototype property" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/proxy-undefined-newtarget.js b/js/src/tests/test262/built-ins/Proxy/proxy-undefined-newtarget.js new file mode 100644 index 0000000000..3c8249f03b --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/proxy-undefined-newtarget.js @@ -0,0 +1,21 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 26.2.1.1 +description: > + Proxy ( target, handler ) + + When Proxy is called with arguments target and handler performs + the following steps: + + 1. If NewTarget is undefined, throw a TypeError exception. + ... + +features: [Proxy] +---*/ + +assert.throws(TypeError, function() { + Proxy({}, {}); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/proxy.js b/js/src/tests/test262/built-ins/Proxy/proxy.js new file mode 100644 index 0000000000..794856c7f6 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/proxy.js @@ -0,0 +1,17 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 26.2.1.1 +description: > + Proxy ( target, handler ) + + 17 ECMAScript Standard Built-in Objects + +includes: [propertyHelper.js] +---*/ + +verifyNotEnumerable(this, "Proxy"); +verifyWritable(this, "Proxy"); +verifyConfigurable(this, "Proxy"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/revocable/browser.js b/js/src/tests/test262/built-ins/Proxy/revocable/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/revocable/browser.js diff --git a/js/src/tests/test262/built-ins/Proxy/revocable/builtin.js b/js/src/tests/test262/built-ins/Proxy/revocable/builtin.js new file mode 100644 index 0000000000..90413beaa1 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/revocable/builtin.js @@ -0,0 +1,30 @@ +// Copyright (C) 2020 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy.revocable +description: > + Requirements for built-in functions, defined in introduction of chapter 17, + are satisfied. +features: [Proxy, Reflect.construct] +---*/ + +assert(Object.isExtensible(Proxy.revocable), 'Object.isExtensible(Proxy.revocable) must return true'); +assert.sameValue(typeof Proxy.revocable, 'function', 'The value of `typeof Proxy.revocable` is "function"'); +assert.sameValue( + Object.prototype.toString.call(Proxy.revocable), + '[object Function]', + 'Object.prototype.toString.call(Proxy.revocable) must return "[object Function]"' +); +assert.sameValue( + Object.getPrototypeOf(Proxy.revocable), + Function.prototype, + 'Object.getPrototypeOf(Proxy.revocable) must return the value of Function.prototype' +); + +assert.sameValue( + Proxy.revocable.hasOwnProperty('prototype'), + false, + 'Proxy.revocable.hasOwnProperty(\'prototype\') must return false' +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/revocable/handler-is-revoked-proxy.js b/js/src/tests/test262/built-ins/Proxy/revocable/handler-is-revoked-proxy.js new file mode 100644 index 0000000000..c2bf8a2a1b --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/revocable/handler-is-revoked-proxy.js @@ -0,0 +1,24 @@ +// Copyright (C) 2020 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxycreate +description: > + A Proxy is created with its [[ProxyHandler]] as revoked Proxy. +info: | + ProxyCreate ( target, handler ) + + [...] + 3. Let P be ! MakeBasicObject(« [[ProxyHandler]], [[ProxyTarget]] »). + [...] + 7. Set P.[[ProxyHandler]] to handler. + 8. Return P. +features: [Proxy] +---*/ + +var revocableHandler = Proxy.revocable({}, {}); +revocableHandler.revoke(); + +var revocable = Proxy.revocable({}, revocableHandler.proxy); +assert.sameValue(typeof revocable.proxy, "object"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/revocable/length.js b/js/src/tests/test262/built-ins/Proxy/revocable/length.js new file mode 100644 index 0000000000..8c1b055371 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/revocable/length.js @@ -0,0 +1,32 @@ +// Copyright (C) 2015 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +es6id: 26.2.2.1 +description: > + Proxy.revocable.length is 2. +info: | + Proxy.revocable ( target, handler ) + + 17 ECMAScript Standard Built-in Objects: + Every built-in Function object, including constructors, has a length + property whose value is an integer. Unless otherwise specified, this + value is equal to the largest number of named arguments shown in the + subclause headings for the function description, including optional + parameters. However, rest parameters shown using the form “...name” + are not included in the default argument count. + + Unless otherwise specified, the length property of a built-in Function + object has the attributes { [[Writable]]: false, [[Enumerable]]: false, + [[Configurable]]: true }. +includes: [propertyHelper.js] +features: [Proxy] +---*/ + +assert.sameValue(Proxy.revocable.length, 2); + +verifyNotEnumerable(Proxy.revocable, "length"); +verifyNotWritable(Proxy.revocable, "length"); +verifyConfigurable(Proxy.revocable, "length"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/revocable/name.js b/js/src/tests/test262/built-ins/Proxy/revocable/name.js new file mode 100644 index 0000000000..0e7ce54890 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/revocable/name.js @@ -0,0 +1,29 @@ +// Copyright (C) 2015 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +es6id: 26.2.2.1 +description: > + Proxy.revocable.name is "revocable". +info: | + Proxy.revocable ( target, handler ) + + 17 ECMAScript Standard Built-in Objects: + Every built-in Function object, including constructors, that is not + identified as an anonymous function has a name property whose value + is a String. + + Unless otherwise specified, the name property of a built-in Function + object, if it exists, has the attributes { [[Writable]]: false, + [[Enumerable]]: false, [[Configurable]]: true }. +includes: [propertyHelper.js] +features: [Proxy] +---*/ + +assert.sameValue(Proxy.revocable.name, "revocable"); + +verifyNotEnumerable(Proxy.revocable, "name"); +verifyNotWritable(Proxy.revocable, "name"); +verifyConfigurable(Proxy.revocable, "name"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/revocable/not-a-constructor.js b/js/src/tests/test262/built-ins/Proxy/revocable/not-a-constructor.js new file mode 100644 index 0000000000..0d1e9bdff5 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/revocable/not-a-constructor.js @@ -0,0 +1,31 @@ +// Copyright (C) 2020 Rick Waldron. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-ecmascript-standard-built-in-objects +description: > + Proxy.revocable does not implement [[Construct]], is not new-able +info: | + ECMAScript Function Objects + + Built-in function objects that are not identified as constructors do not + implement the [[Construct]] internal method unless otherwise specified in + the description of a particular function. + + sec-evaluatenew + + ... + 7. If IsConstructor(constructor) is false, throw a TypeError exception. + ... +includes: [isConstructor.js] +features: [Reflect.construct, Reflect, arrow-function, Proxy] +---*/ + +assert.sameValue(isConstructor(Proxy.revocable), false, 'isConstructor(Proxy.revocable) must return false'); + +assert.throws(TypeError, () => { + new Proxy.revocable({}, {}); +}, '`new Proxy.revocable({}, {})` throws TypeError'); + + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/revocable/proxy.js b/js/src/tests/test262/built-ins/Proxy/revocable/proxy.js new file mode 100644 index 0000000000..2de6b80295 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/revocable/proxy.js @@ -0,0 +1,26 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 26.2.2.1 +description: > + The returned object has a proxy property which is the created Proxy object + built with the given target and handler given parameters. +info: | + Proxy.revocable ( target, handler ) + + 6. Perform CreateDataProperty(result, "proxy", p). +features: [Proxy] +---*/ + +var target = { + attr: "foo" +}; +var r = Proxy.revocable(target, { + get: function(t, prop) { + return t[prop] + "!"; + } +}); + +assert.sameValue(r.proxy.attr, "foo!"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/revocable/revocation-function-extensible.js b/js/src/tests/test262/built-ins/Proxy/revocable/revocation-function-extensible.js new file mode 100644 index 0000000000..cf354bb1ee --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/revocable/revocation-function-extensible.js @@ -0,0 +1,18 @@ +// Copyright (C) 2015 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +es6id: 26.2.2.1.1 +description: The [[Extensible]] slot of Proxy Revocation functions +info: | + 17 ECMAScript Standard Built-in Objects: + Unless specified otherwise, the [[Extensible]] internal slot + of a built-in object initially has the value true. +features: [Proxy] +---*/ + +var revocationFunction = Proxy.revocable({}, {}).revoke; + +assert(Object.isExtensible(revocationFunction)); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/revocable/revocation-function-length.js b/js/src/tests/test262/built-ins/Proxy/revocable/revocation-function-length.js new file mode 100644 index 0000000000..ac59134301 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/revocable/revocation-function-length.js @@ -0,0 +1,26 @@ +// Copyright (C) 2015 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +es6id: 26.2.2.1.1 +description: The `length` property of Proxy Revocation functions +info: | + The length property of a Proxy revocation function is 0. + + 17 ECMAScript Standard Built-in Objects: + Unless otherwise specified, the length property of a built-in Function + object has the attributes { [[Writable]]: false, [[Enumerable]]: false, + [[Configurable]]: true }. +includes: [propertyHelper.js] +features: [Proxy] +---*/ + +var revocationFunction = Proxy.revocable({}, {}).revoke; + +assert.sameValue(revocationFunction.length, 0); + +verifyNotEnumerable(revocationFunction, "length"); +verifyNotWritable(revocationFunction, "length"); +verifyConfigurable(revocationFunction, "length"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/revocable/revocation-function-name.js b/js/src/tests/test262/built-ins/Proxy/revocable/revocation-function-name.js new file mode 100644 index 0000000000..5f066ff1bb --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/revocable/revocation-function-name.js @@ -0,0 +1,28 @@ +// Copyright (C) 2015 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +es6id: 26.2.2.1.1 +description: The `name` property of Proxy Revocation functions +info: | + A Proxy revocation function is an anonymous function. + + 17 ECMAScript Standard Built-in Objects: + Every built-in function object, including constructors, has a `name` + property whose value is a String. Functions that are identified as + anonymous functions use the empty string as the value of the `name` + property. + Unless otherwise specified, the `name` property of a built-in function + object has the attributes { [[Writable]]: *false*, [[Enumerable]]: *false*, + [[Configurable]]: *true* }. +includes: [propertyHelper.js] +features: [Proxy] +---*/ + +var revocationFunction = Proxy.revocable({}, {}).revoke; + +verifyProperty(revocationFunction, "name", { + value: "", writable: false, enumerable: false, configurable: true +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/revocable/revocation-function-not-a-constructor.js b/js/src/tests/test262/built-ins/Proxy/revocable/revocation-function-not-a-constructor.js new file mode 100644 index 0000000000..643c7e57c2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/revocable/revocation-function-not-a-constructor.js @@ -0,0 +1,30 @@ +// Copyright (C) 2015 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-proxy.revocable +description: Proxy Revocation functions are not constructors +info: | + 17 ECMAScript Standard Built-in Objects: + Built-in function objects that are not identified as constructors do not + implement the [[Construct]] internal method unless otherwise specified + in the description of a particular function. +includes: [isConstructor.js] +features: [Proxy, Reflect.construct, arrow-function] +---*/ + +var revocationFunction = Proxy.revocable({}, {}).revoke; + +assert.sameValue( + Object.prototype.hasOwnProperty.call(revocationFunction, "prototype"), + false, + 'Object.prototype.hasOwnProperty.call(revocationFunction, "prototype") must return false' +); +assert.sameValue(isConstructor(revocationFunction), false, 'isConstructor(revocationFunction) must return false'); +assert.throws(TypeError, () => { + new revocationFunction(); +}, '`new revocationFunction()` throws TypeError'); + + + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/revocable/revocation-function-property-order.js b/js/src/tests/test262/built-ins/Proxy/revocable/revocation-function-property-order.js new file mode 100644 index 0000000000..34af67cbc5 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/revocable/revocation-function-property-order.js @@ -0,0 +1,19 @@ +// Copyright (C) 2020 ExE Boss. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-createbuiltinfunction +description: Proxy revocation function property order +info: | + Set order: "length", "name" +---*/ + +var revocationFunction = Proxy.revocable({}, {}).revoke; + +var propNames = Object.getOwnPropertyNames(revocationFunction); +var lengthIndex = propNames.indexOf("length"); +var nameIndex = propNames.indexOf("name"); + +assert(lengthIndex >= 0 && nameIndex === lengthIndex + 1, + "The `length` property comes before the `name` property on built-in functions"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/revocable/revocation-function-prototype.js b/js/src/tests/test262/built-ins/Proxy/revocable/revocation-function-prototype.js new file mode 100644 index 0000000000..2f245f35d4 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/revocable/revocation-function-prototype.js @@ -0,0 +1,20 @@ +// Copyright (C) 2015 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +es6id: 26.2.2.1.1 +description: The [[Prototype]] of Proxy Revocation functions +info: | + 17 ECMAScript Standard Built-in Objects: + Unless otherwise specified every built-in function and every built-in + constructor has the Function prototype object, which is the initial + value of the expression Function.prototype (19.2.3), as the value of + its [[Prototype]] internal slot. +features: [Proxy] +---*/ + +var revocationFunction = Proxy.revocable({}, {}).revoke; + +assert.sameValue(Object.getPrototypeOf(revocationFunction), Function.prototype); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/revocable/revoke-consecutive-call-returns-undefined.js b/js/src/tests/test262/built-ins/Proxy/revocable/revoke-consecutive-call-returns-undefined.js new file mode 100644 index 0000000000..f1d043fc18 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/revocable/revoke-consecutive-call-returns-undefined.js @@ -0,0 +1,22 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 26.2.2.1.1 +description: > + Calling the revoked function again will return undefined +info: | + Proxy Revocation Functions + + ... + 1. Let p be the value of F’s [[RevocableProxy]] internal slot. + 2. If p is null, return undefined. +features: [Proxy] +---*/ + +var r = Proxy.revocable({}, {}); + +r.revoke(); + +assert.sameValue(r.revoke(), undefined); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/revocable/revoke-returns-undefined.js b/js/src/tests/test262/built-ins/Proxy/revocable/revoke-returns-undefined.js new file mode 100644 index 0000000000..b1356b5e15 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/revocable/revoke-returns-undefined.js @@ -0,0 +1,19 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 26.2.2.1.1 +description: > + Calling the revoked function returns undefined +info: | + Proxy Revocation Functions + + ... + 7. Return undefined. +features: [Proxy] +---*/ + +var r = Proxy.revocable({}, {}); + +assert.sameValue(r.revoke(), undefined); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/revocable/revoke.js b/js/src/tests/test262/built-ins/Proxy/revocable/revoke.js new file mode 100644 index 0000000000..8185c88ecc --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/revocable/revoke.js @@ -0,0 +1,18 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 26.2.2.1 +description: > + The returned object has a `revoked` property which is a function +info: | + Proxy.revocable ( target, handler ) + + 7. Perform CreateDataProperty(result, "revoke", revoker). +features: [Proxy] +---*/ + +var r = Proxy.revocable({}, {}); + +assert.sameValue(typeof r.revoke, "function"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/revocable/shell.js b/js/src/tests/test262/built-ins/Proxy/revocable/shell.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/revocable/shell.js diff --git a/js/src/tests/test262/built-ins/Proxy/revocable/target-is-revoked-function-proxy.js b/js/src/tests/test262/built-ins/Proxy/revocable/target-is-revoked-function-proxy.js new file mode 100644 index 0000000000..f4bdf1d5b8 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/revocable/target-is-revoked-function-proxy.js @@ -0,0 +1,25 @@ +// Copyright (C) 2020 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxycreate +description: > + A Proxy is created with its [[ProxyTarget]] as revoked function Proxy. +info: | + ProxyCreate ( target, handler ) + + [...] + 3. Let P be ! MakeBasicObject(« [[ProxyHandler]], [[ProxyTarget]] »). + [...] + 6. Set P.[[ProxyTarget]] to target. + [...] + 8. Return P. +features: [Proxy] +---*/ + +var revocableTarget = Proxy.revocable(function() {}, {}); +revocableTarget.revoke(); + +var revocable = Proxy.revocable(revocableTarget.proxy, {}); +assert.sameValue(typeof revocable.proxy, "function"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/revocable/target-is-revoked-proxy.js b/js/src/tests/test262/built-ins/Proxy/revocable/target-is-revoked-proxy.js new file mode 100644 index 0000000000..d83a11a0f3 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/revocable/target-is-revoked-proxy.js @@ -0,0 +1,25 @@ +// Copyright (C) 2020 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxycreate +description: > + A Proxy is created with its [[ProxyTarget]] as revoked Proxy. +info: | + ProxyCreate ( target, handler ) + + [...] + 3. Let P be ! MakeBasicObject(« [[ProxyHandler]], [[ProxyTarget]] »). + [...] + 6. Set P.[[ProxyTarget]] to target. + [...] + 8. Return P. +features: [Proxy] +---*/ + +var revocableTarget = Proxy.revocable({}, {}); +revocableTarget.revoke(); + +var revocable = Proxy.revocable(revocableTarget.proxy, {}); +assert.sameValue(typeof revocable.proxy, "object"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/revocable/tco-fn-realm-strict.js b/js/src/tests/test262/built-ins/Proxy/revocable/tco-fn-realm-strict.js new file mode 100644 index 0000000000..6714f09e63 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/revocable/tco-fn-realm-strict.js @@ -0,0 +1,27 @@ +// |reftest| skip -- tail-call-optimization is not supported +'use strict'; +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: > + Realm of the TypeError from invoking a revoked Proxy during tail-call + optimization +esid: sec-tail-position-calls +flags: [onlyStrict] +features: [Proxy, tail-call-optimization] +---*/ + +var other = $262.createRealm(); +var F = other.evalScript(` + (function() { + var { proxy, revoke } = Proxy.revocable(function() {}, {}); + revoke(); + return proxy(); + }) +`); + +assert.throws(other.global.TypeError, function() { + F(); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/set/boolean-trap-result-is-false-boolean-return-false.js b/js/src/tests/test262/built-ins/Proxy/set/boolean-trap-result-is-false-boolean-return-false.js new file mode 100644 index 0000000000..0d69437b4a --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/set/boolean-trap-result-is-false-boolean-return-false.js @@ -0,0 +1,22 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.9 +description: > + [[Set]] ( P, V, Receiver) + + 11. If booleanTrapResult is false, return false. +features: [Proxy, Reflect, Reflect.set] +---*/ + +var target = {}; +var handler = { + set: function(t, prop, value, receiver) { + return false; + } +}; +var p = new Proxy(target, handler); + +assert.sameValue(Reflect.set(p, "attr", "foo"), false); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/set/boolean-trap-result-is-false-null-return-false.js b/js/src/tests/test262/built-ins/Proxy/set/boolean-trap-result-is-false-null-return-false.js new file mode 100644 index 0000000000..f904449f7d --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/set/boolean-trap-result-is-false-null-return-false.js @@ -0,0 +1,22 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.9 +description: > + [[Set]] ( P, V, Receiver) + + 11. If booleanTrapResult is false, return false. +features: [Proxy, Reflect, Reflect.set] +---*/ + +var target = {}; +var handler = { + set: function(t, prop, value, receiver) { + return null; + } +}; +var p = new Proxy(target, handler); + +assert.sameValue(Reflect.set(p, "attr", "foo"), false); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/set/boolean-trap-result-is-false-number-return-false.js b/js/src/tests/test262/built-ins/Proxy/set/boolean-trap-result-is-false-number-return-false.js new file mode 100644 index 0000000000..edf18a07ea --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/set/boolean-trap-result-is-false-number-return-false.js @@ -0,0 +1,22 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.9 +description: > + [[Set]] ( P, V, Receiver) + + 11. If booleanTrapResult is false, return false. +features: [Proxy, Reflect, Reflect.set] +---*/ + +var target = {}; +var handler = { + set: function(t, prop, value, receiver) { + return 0; + } +}; +var p = new Proxy(target, handler); + +assert.sameValue(Reflect.set(p, "attr", "foo"), false); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/set/boolean-trap-result-is-false-string-return-false.js b/js/src/tests/test262/built-ins/Proxy/set/boolean-trap-result-is-false-string-return-false.js new file mode 100644 index 0000000000..2eab3a0c63 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/set/boolean-trap-result-is-false-string-return-false.js @@ -0,0 +1,22 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.9 +description: > + [[Set]] ( P, V, Receiver) + + 11. If booleanTrapResult is false, return false. +features: [Proxy, Reflect, Reflect.set] +---*/ + +var target = {}; +var handler = { + set: function(t, prop, value, receiver) { + return ""; + } +}; +var p = new Proxy(target, handler); + +assert.sameValue(Reflect.set(p, "attr", "foo"), false); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/set/boolean-trap-result-is-false-undefined-return-false.js b/js/src/tests/test262/built-ins/Proxy/set/boolean-trap-result-is-false-undefined-return-false.js new file mode 100644 index 0000000000..0ff8ca59a4 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/set/boolean-trap-result-is-false-undefined-return-false.js @@ -0,0 +1,22 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.9 +description: > + [[Set]] ( P, V, Receiver) + + 11. If booleanTrapResult is false, return false. +features: [Proxy, Reflect, Reflect.set] +---*/ + +var target = {}; +var handler = { + set: function(t, prop, value, receiver) { + return undefined; + } +}; +var p = new Proxy(target, handler); + +assert.sameValue(Reflect.set(p, "attr", "foo"), false); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/set/browser.js b/js/src/tests/test262/built-ins/Proxy/set/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/set/browser.js diff --git a/js/src/tests/test262/built-ins/Proxy/set/call-parameters-prototype-dunder-proto.js b/js/src/tests/test262/built-ins/Proxy/set/call-parameters-prototype-dunder-proto.js new file mode 100644 index 0000000000..8b4ec874d2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/set/call-parameters-prototype-dunder-proto.js @@ -0,0 +1,58 @@ +// Copyright (C) 2019 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-set-p-v-receiver +description: > + Ordinary [[Set]] forwards call to Proxy "set" trap with correct arguments. + Property name is "__proto__". +info: | + OrdinarySet ( O, P, V, Receiver ) + + ... + 3. Return OrdinarySetWithOwnDescriptor(O, P, V, Receiver, ownDesc). + + OrdinarySetWithOwnDescriptor ( O, P, V, Receiver, ownDesc ) + + ... + 2. If ownDesc is undefined, then + a. Let parent be ? O.[[GetPrototypeOf]](). + b. If parent is not null, then + i. Return ? parent.[[Set]](P, V, Receiver). + + [[Set]] ( P, V, Receiver ) + + ... + 8. Let booleanTrapResult be ! ToBoolean(? Call(trap, handler, « target, P, V, Receiver »)). + ... + 12. Return true. +includes: [proxyTrapsHelper.js] +features: [Proxy, __proto__] +---*/ + +var _handler, _target, _prop, _value, _receiver; +var target = {}; +var handler = allowProxyTraps({ + set: function(target, prop, value, receiver) { + _handler = this; + _target = target; + _prop = prop; + _value = value; + _receiver = receiver; + return true; + }, +}); + +var proxy = new Proxy(target, handler); +var receiver = Object.create(proxy); +var prop = '__proto__'; +var value = {}; + +receiver[prop] = value; + +assert.sameValue(_handler, handler, 'handler object is the trap context'); +assert.sameValue(_target, target, 'first argument is the target object'); +assert.sameValue(_prop, prop, 'second argument is the property name'); +assert.sameValue(_value, value, 'third argument is the new value'); +assert.sameValue(_receiver, receiver, 'fourth argument is the receiver object'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/set/call-parameters-prototype-index.js b/js/src/tests/test262/built-ins/Proxy/set/call-parameters-prototype-index.js new file mode 100644 index 0000000000..e57e40c3e0 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/set/call-parameters-prototype-index.js @@ -0,0 +1,57 @@ +// Copyright (C) 2019 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-set-p-v-receiver +description: > + Ordinary [[Set]] forwards call to Proxy "set" trap with correct arguments. + (integer index property name) +info: | + OrdinarySet ( O, P, V, Receiver ) + + ... + 3. Return OrdinarySetWithOwnDescriptor(O, P, V, Receiver, ownDesc). + + OrdinarySetWithOwnDescriptor ( O, P, V, Receiver, ownDesc ) + + ... + 2. If ownDesc is undefined, then + a. Let parent be ? O.[[GetPrototypeOf]](). + b. If parent is not null, then + i. Return ? parent.[[Set]](P, V, Receiver). + + [[Set]] ( P, V, Receiver ) + + ... + 8. Let booleanTrapResult be ! ToBoolean(? Call(trap, handler, « target, P, V, Receiver »)). + ... + 12. Return true. +includes: [proxyTrapsHelper.js] +features: [Proxy] +---*/ + +var _handler, _target, _prop, _value, _receiver; +var target = {}; +var handler = allowProxyTraps({ + set: function(target, prop, value, receiver) { + _handler = this; + _target = target; + _prop = prop; + _value = value; + _receiver = receiver; + return true; + }, +}); + +var proxy = new Proxy(target, handler); +var array = new Array(1); +Object.setPrototypeOf(array, proxy); + +array[0] = 1; + +assert.sameValue(_handler, handler, 'handler object is the trap context'); +assert.sameValue(_target, target, 'first argument is the target object'); +assert.sameValue(_prop, '0', 'second argument is the property name'); +assert.sameValue(_value, 1, 'third argument is the new value'); +assert.sameValue(_receiver, array, 'fourth argument is the receiver object'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/set/call-parameters-prototype.js b/js/src/tests/test262/built-ins/Proxy/set/call-parameters-prototype.js new file mode 100644 index 0000000000..c11f535d95 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/set/call-parameters-prototype.js @@ -0,0 +1,55 @@ +// Copyright (C) 2019 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-set-p-v-receiver +description: > + Ordinary [[Set]] forwards call to Proxy "set" trap with correct arguments. +info: | + OrdinarySet ( O, P, V, Receiver ) + + ... + 3. Return OrdinarySetWithOwnDescriptor(O, P, V, Receiver, ownDesc). + + OrdinarySetWithOwnDescriptor ( O, P, V, Receiver, ownDesc ) + + ... + 2. If ownDesc is undefined, then + a. Let parent be ? O.[[GetPrototypeOf]](). + b. If parent is not null, then + i. Return ? parent.[[Set]](P, V, Receiver). + + [[Set]] ( P, V, Receiver ) + + ... + 8. Let booleanTrapResult be ! ToBoolean(? Call(trap, handler, « target, P, V, Receiver »)). + ... + 12. Return true. +includes: [proxyTrapsHelper.js] +features: [Proxy] +---*/ + +var _handler, _target, _prop, _value, _receiver; +var target = {}; +var handler = allowProxyTraps({ + set: function(target, prop, value, receiver) { + _handler = this; + _target = target; + _prop = prop; + _value = value; + _receiver = receiver; + return true; + }, +}); + +var proxy = new Proxy(target, handler); +var receiver = Object.create(proxy); + +receiver.prop = 'value'; + +assert.sameValue(_handler, handler, 'handler object is the trap context'); +assert.sameValue(_target, target, 'first argument is the target object'); +assert.sameValue(_prop, 'prop', 'second argument is the property name'); +assert.sameValue(_value, 'value', 'third argument is the new value'); +assert.sameValue(_receiver, receiver, 'fourth argument is the receiver object'); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/set/call-parameters.js b/js/src/tests/test262/built-ins/Proxy/set/call-parameters.js new file mode 100644 index 0000000000..304fc661c9 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/set/call-parameters.js @@ -0,0 +1,39 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-set-p-v-receiver +description: > + Proxy "set" trap is called with correct arguments. +info: | + [[Set]] ( P, V, Receiver ) + + ... + 8. Let booleanTrapResult be ! ToBoolean(? Call(trap, handler, « target, P, V, Receiver »)). + ... + 12. Return true. +features: [Proxy] +---*/ + +var _target, _handler, _prop, _value, _receiver; +var target = {}; +var handler = { + set: function(t, prop, value, receiver) { + _handler = this; + _target = t; + _prop = prop; + _value = value; + _receiver = receiver; + return true; + } +}; +var p = new Proxy(target, handler); + +p.attr = "foo"; + +assert.sameValue(_handler, handler, "handler object as the trap context"); +assert.sameValue(_target, target, "first argument is the target object"); +assert.sameValue(_prop, "attr", "second argument is the property name"); +assert.sameValue(_value, "foo", "third argument is the new value"); +assert.sameValue(_receiver, p, "forth argument is the proxy object"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/set/null-handler.js b/js/src/tests/test262/built-ins/Proxy/set/null-handler.js new file mode 100644 index 0000000000..dd5c16829f --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/set/null-handler.js @@ -0,0 +1,24 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.9 +description: > + [[Set]] ( P, V, Receiver) + + 3. If handler is null, throw a TypeError exception. +features: [Proxy] +---*/ + +var p = Proxy.revocable({}, {}); + +p.revoke(); + +assert.throws(TypeError, function() { + p.proxy.attr = 1; +}); + +assert.throws(TypeError, function() { + p.proxy['attr'] = 1; +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/set/return-is-abrupt.js b/js/src/tests/test262/built-ins/Proxy/set/return-is-abrupt.js new file mode 100644 index 0000000000..4dbff93a3c --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/set/return-is-abrupt.js @@ -0,0 +1,31 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.9 +description: > + Trap returns abrupt. +info: | + [[Set]] ( P, V, Receiver) + + ... + 9. Let booleanTrapResult be ToBoolean(Call(trap, handler, «target, P, V, Receiver»)). + 10. ReturnIfAbrupt(booleanTrapResult). + ... +features: [Proxy] +---*/ + +var p = new Proxy({}, { + set: function(t, prop, value, receiver) { + throw new Test262Error(); + } +}); + +assert.throws(Test262Error, function() { + p.attr = "bar"; +}); + +assert.throws(Test262Error, function() { + p["attr"] = "bar"; +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/set/return-true-target-property-accessor-is-configurable-set-is-undefined.js b/js/src/tests/test262/built-ins/Proxy/set/return-true-target-property-accessor-is-configurable-set-is-undefined.js new file mode 100644 index 0000000000..5d9cf8144e --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/set/return-true-target-property-accessor-is-configurable-set-is-undefined.js @@ -0,0 +1,28 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.9 +description: > + [[Set]] ( P, V, Receiver) + + Returns true if trap returns true and target property accessor is + configurable and set is undefined. +features: [Proxy, Reflect, Reflect.set] +---*/ + +var target = {}; +var handler = { + set: function(t, prop, value, receiver) { + return true; + } +}; +var p = new Proxy(target, handler); + +Object.defineProperty(target, "attr", { + configurable: true, + set: undefined +}); + +assert(Reflect.set(p, "attr", "bar")); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/set/return-true-target-property-accessor-is-not-configurable.js b/js/src/tests/test262/built-ins/Proxy/set/return-true-target-property-accessor-is-not-configurable.js new file mode 100644 index 0000000000..536429bf75 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/set/return-true-target-property-accessor-is-not-configurable.js @@ -0,0 +1,30 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.9 +description: > + [[Set]] ( P, V, Receiver) + + Returns true if trap returns true and target property accessor is not + configurable and set is not undefined. +features: [Proxy, Reflect, Reflect.set] +---*/ + +var target = {}; +var handler = { + set: function(t, prop, value, receiver) { + return true; + } +}; +var p = new Proxy(target, handler); + +Object.defineProperty(target, 'attr', { + configurable: false, + set: function(value) { + return value; + } +}); + +assert(Reflect.set(p, "attr", 1)); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/set/return-true-target-property-is-not-configurable.js b/js/src/tests/test262/built-ins/Proxy/set/return-true-target-property-is-not-configurable.js new file mode 100644 index 0000000000..6d0ed0f8f1 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/set/return-true-target-property-is-not-configurable.js @@ -0,0 +1,29 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.9 +description: > + [[Set]] ( P, V, Receiver) + + Returns true if trap returns true and target property is not configurable + but writable. +features: [Proxy, Reflect, Reflect.set] +---*/ + +var target = {}; +var handler = { + set: function(t, prop, value, receiver) { + return true; + } +}; +var p = new Proxy(target, handler); + +Object.defineProperty(target, 'attr', { + configurable: false, + writable: true, + value: 'foo' +}); + +assert(Reflect.set(p, "attr", 1)); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/set/return-true-target-property-is-not-writable.js b/js/src/tests/test262/built-ins/Proxy/set/return-true-target-property-is-not-writable.js new file mode 100644 index 0000000000..04bd86bdcc --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/set/return-true-target-property-is-not-writable.js @@ -0,0 +1,29 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.9 +description: > + [[Set]] ( P, V, Receiver) + + Returns true if trap returns true and target property is configurable + but not writable. +features: [Proxy, Reflect, Reflect.set] +---*/ + +var target = {}; +var handler = { + set: function(t, prop, value, receiver) { + return true; + } +}; +var p = new Proxy(target, handler); + +Object.defineProperty(target, "attr", { + configurable: true, + writable: false, + value: "foo" +}); + +assert(Reflect.set(p, "attr", "foo")); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/set/shell.js b/js/src/tests/test262/built-ins/Proxy/set/shell.js new file mode 100644 index 0000000000..bc72493f03 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/set/shell.js @@ -0,0 +1,33 @@ +// GENERATED, DO NOT EDIT +// file: proxyTrapsHelper.js +// Copyright (C) 2016 Jordan Harband. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: | + Used to assert the correctness of object behavior in the presence + and context of Proxy objects. +defines: [allowProxyTraps] +---*/ + +function allowProxyTraps(overrides) { + function throwTest262Error(msg) { + return function () { throw new Test262Error(msg); }; + } + if (!overrides) { overrides = {}; } + return { + getPrototypeOf: overrides.getPrototypeOf || throwTest262Error('[[GetPrototypeOf]] trap called'), + setPrototypeOf: overrides.setPrototypeOf || throwTest262Error('[[SetPrototypeOf]] trap called'), + isExtensible: overrides.isExtensible || throwTest262Error('[[IsExtensible]] trap called'), + preventExtensions: overrides.preventExtensions || throwTest262Error('[[PreventExtensions]] trap called'), + getOwnPropertyDescriptor: overrides.getOwnPropertyDescriptor || throwTest262Error('[[GetOwnProperty]] trap called'), + has: overrides.has || throwTest262Error('[[HasProperty]] trap called'), + get: overrides.get || throwTest262Error('[[Get]] trap called'), + set: overrides.set || throwTest262Error('[[Set]] trap called'), + deleteProperty: overrides.deleteProperty || throwTest262Error('[[Delete]] trap called'), + defineProperty: overrides.defineProperty || throwTest262Error('[[DefineOwnProperty]] trap called'), + enumerate: throwTest262Error('[[Enumerate]] trap called: this trap has been removed'), + ownKeys: overrides.ownKeys || throwTest262Error('[[OwnPropertyKeys]] trap called'), + apply: overrides.apply || throwTest262Error('[[Call]] trap called'), + construct: overrides.construct || throwTest262Error('[[Construct]] trap called') + }; +} diff --git a/js/src/tests/test262/built-ins/Proxy/set/target-property-is-accessor-not-configurable-set-is-undefined.js b/js/src/tests/test262/built-ins/Proxy/set/target-property-is-accessor-not-configurable-set-is-undefined.js new file mode 100644 index 0000000000..da4292f791 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/set/target-property-is-accessor-not-configurable-set-is-undefined.js @@ -0,0 +1,39 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.9 +description: > + [[Set]] ( P, V, Receiver) + + Throws a TypeError when target property is an accessor not configurable and + and set is undefined. +info: | + 14. If targetDesc is not undefined, then + b. If IsAccessorDescriptor(targetDesc) and targetDesc.[[Configurable]] is false, then + i. If targetDesc.[[Set]] is undefined, throw a TypeError exception. + +features: [Proxy] +---*/ + +var target = {}; +var handler = { + set: function(t, prop, value, receiver) { + return true; + } +}; +var p = new Proxy(target, handler); + +Object.defineProperty(target, 'attr', { + configurable: false, + set: undefined +}); + +assert.throws(TypeError, function() { + p.attr = 'bar'; +}); + +assert.throws(TypeError, function() { + p['attr'] = 'bar'; +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/set/target-property-is-not-configurable-not-writable-not-equal-to-v.js b/js/src/tests/test262/built-ins/Proxy/set/target-property-is-not-configurable-not-writable-not-equal-to-v.js new file mode 100644 index 0000000000..73fd9c7ae4 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/set/target-property-is-not-configurable-not-writable-not-equal-to-v.js @@ -0,0 +1,41 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.9 +description: > + [[Set]] ( P, V, Receiver) + + Throws a TypeError when target property is not configurable neither writable + and its value is not strictly equal to V. +info: | + 14. If targetDesc is not undefined, then + a. If IsDataDescriptor(targetDesc) and targetDesc.[[Configurable]] is + false and targetDesc.[[Writable]] is false, then + i. If SameValue(V, targetDesc.[[Value]]) is false, throw a TypeError + exception. +features: [Proxy] +---*/ + +var target = {}; +var handler = { + set: function(t, prop, value, receiver) { + return true; + } +}; +var p = new Proxy(target, handler); + +Object.defineProperty(target, 'attr', { + configurable: false, + writable: false, + value: 'foo' +}); + +assert.throws(TypeError, function() { + p.attr = 'bar'; +}); + +assert.throws(TypeError, function() { + p['attr'] = 'bar'; +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/set/trap-is-missing-receiver-multiple-calls-index.js b/js/src/tests/test262/built-ins/Proxy/set/trap-is-missing-receiver-multiple-calls-index.js new file mode 100644 index 0000000000..37a7cac0e9 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/set/trap-is-missing-receiver-multiple-calls-index.js @@ -0,0 +1,81 @@ +// Copyright (C) 2020 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-set-p-v-receiver +description: > + If "set" trap is missing, the call is properly forwarded to ordinary + [[Set]] that invokes [[GetOwnProperty]] and [[DefineOwnProperty]] methods + on receiver (that is a Proxy itself) every time it is called. + (integer index property name) +info: | + [[Set]] ( P, V, Receiver ) + + [...] + 6. Let trap be ? GetMethod(handler, "set"). + 7. If trap is undefined, then + a. Return ? target.[[Set]](P, V, Receiver). + + OrdinarySetWithOwnDescriptor ( O, P, V, Receiver, ownDesc ) + + [...] + 3. If IsDataDescriptor(ownDesc) is true, then + [...] + c. Let existingDescriptor be ? Receiver.[[GetOwnProperty]](P). + d. If existingDescriptor is not undefined, then + [...] + iii. Let valueDesc be the PropertyDescriptor { [[Value]]: V }. + iv. Return ? Receiver.[[DefineOwnProperty]](P, valueDesc). + e. Else, + i. Assert: Receiver does not currently have a property P. + ii. Return ? CreateDataProperty(Receiver, P, V). + [...] + + [[DefineOwnProperty]] ( P, Desc ) + + [...] + 9. Let booleanTrapResult be ! ToBoolean(? Call(trap, handler, « target, P, descObj »)). + [...] + 17. Return true. +features: [Proxy, Reflect] +includes: [compareArray.js] +---*/ + +var getOwnPropertyKeys = []; +var definePropertyKeys = []; + +var p = new Proxy({ + "0": null, +}, { + getOwnPropertyDescriptor: function(target, key) { + getOwnPropertyKeys.push(key); + return Reflect.getOwnPropertyDescriptor(target, key); + }, + defineProperty: function(target, key, desc) { + definePropertyKeys.push(key); + return Reflect.defineProperty(target, key, desc); + }, +}); + +p[0] = true; +p[0] = true; +p["0"] = true; + +assert.compareArray(getOwnPropertyKeys, ["0", "0", "0"], + "getOwnPropertyDescriptor: key present on [[ProxyTarget]]"); +assert.compareArray(definePropertyKeys, ["0", "0", "0"], + "defineProperty: key present on [[ProxyTarget]]"); + +getOwnPropertyKeys = []; +definePropertyKeys = []; + +p[22] = false; +p["22"] = false; +p[22] = false; + +assert.compareArray(getOwnPropertyKeys, ["22", "22", "22"], + "getOwnPropertyDescriptor: key absent on [[ProxyTarget]]"); +assert.compareArray(definePropertyKeys, ["22", "22", "22"], + "defineProperty: key absent on [[ProxyTarget]]"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/set/trap-is-missing-receiver-multiple-calls.js b/js/src/tests/test262/built-ins/Proxy/set/trap-is-missing-receiver-multiple-calls.js new file mode 100644 index 0000000000..3144580a4b --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/set/trap-is-missing-receiver-multiple-calls.js @@ -0,0 +1,80 @@ +// Copyright (C) 2020 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-set-p-v-receiver +description: > + If "set" trap is missing, the call is properly forwarded to ordinary + [[Set]] that invokes [[GetOwnProperty]] and [[DefineOwnProperty]] methods + on receiver (that is a Proxy itself) every time it is called. +info: | + [[Set]] ( P, V, Receiver ) + + [...] + 6. Let trap be ? GetMethod(handler, "set"). + 7. If trap is undefined, then + a. Return ? target.[[Set]](P, V, Receiver). + + OrdinarySetWithOwnDescriptor ( O, P, V, Receiver, ownDesc ) + + [...] + 3. If IsDataDescriptor(ownDesc) is true, then + [...] + c. Let existingDescriptor be ? Receiver.[[GetOwnProperty]](P). + d. If existingDescriptor is not undefined, then + [...] + iii. Let valueDesc be the PropertyDescriptor { [[Value]]: V }. + iv. Return ? Receiver.[[DefineOwnProperty]](P, valueDesc). + e. Else, + i. Assert: Receiver does not currently have a property P. + ii. Return ? CreateDataProperty(Receiver, P, V). + [...] + + [[DefineOwnProperty]] ( P, Desc ) + + [...] + 9. Let booleanTrapResult be ! ToBoolean(? Call(trap, handler, « target, P, descObj »)). + [...] + 17. Return true. +features: [Proxy, Reflect] +includes: [compareArray.js] +---*/ + +var getOwnPropertyKeys = []; +var definePropertyKeys = []; + +var p = new Proxy({ + foo: 1, +}, { + getOwnPropertyDescriptor: function(target, key) { + getOwnPropertyKeys.push(key); + return Reflect.getOwnPropertyDescriptor(target, key); + }, + defineProperty: function(target, key, desc) { + definePropertyKeys.push(key); + return Reflect.defineProperty(target, key, desc); + }, +}); + +p["foo"] = 2; +p.foo = 2; +p.foo = 2; + +assert.compareArray(getOwnPropertyKeys, ["foo", "foo", "foo"], + "getOwnPropertyDescriptor: key present on [[ProxyTarget]]"); +assert.compareArray(definePropertyKeys, ["foo", "foo", "foo"], + "defineProperty: key present on [[ProxyTarget]]"); + +getOwnPropertyKeys = []; +definePropertyKeys = []; + +p.bar = 3; +p["bar"] = 3; +p.bar = 3; + +assert.compareArray(getOwnPropertyKeys, ["bar", "bar", "bar"], + "getOwnPropertyDescriptor: key absent on [[ProxyTarget]]"); +assert.compareArray(definePropertyKeys, ["bar", "bar", "bar"], + "defineProperty: key absent on [[ProxyTarget]]"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/set/trap-is-missing-target-is-proxy.js b/js/src/tests/test262/built-ins/Proxy/set/trap-is-missing-target-is-proxy.js new file mode 100644 index 0000000000..1ef5cd59ac --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/set/trap-is-missing-target-is-proxy.js @@ -0,0 +1,49 @@ +// Copyright (C) 2020 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-set-p-v-receiver +description: > + If "set" trap is null or undefined, [[Set]] call is properly + forwarded to [[ProxyTarget]] (which is also a Proxy object). +info: | + [[Set]] ( P, V, Receiver ) + + [...] + 5. Let target be O.[[ProxyTarget]]. + 6. Let trap be ? GetMethod(handler, "set"). + 7. If trap is undefined, then + a. Return ? target.[[Set]](P, V, Receiver). +features: [Proxy, Reflect] +---*/ + +var barValue; +var plainObject = { + get foo() {}, + set bar(value) { + barValue = value; + }, +}; + +var plainObjectTarget = new Proxy(plainObject, {}); +var plainObjectProxy = new Proxy(plainObjectTarget, {}); + +plainObjectProxy.bar = 1; +assert.sameValue(barValue, 1); + +assert.throws(TypeError, function() { + "use strict"; + plainObjectProxy.foo = 2; +}); + + +var regExp = /(?:)/g; +var regExpTarget = new Proxy(regExp, {}); +var regExpProxy = new Proxy(regExpTarget, {}); + +assert(!Reflect.set(regExpProxy, "global", true)); + +regExpProxy.lastIndex = 1; +assert.sameValue(regExp.lastIndex, 1); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/set/trap-is-not-callable-realm.js b/js/src/tests/test262/built-ins/Proxy/set/trap-is-not-callable-realm.js new file mode 100644 index 0000000000..07e710b1ee --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/set/trap-is-not-callable-realm.js @@ -0,0 +1,33 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-set-p-v-receiver +description: > + Throws if trap is not callable (honoring the Realm of the current execution + context) +info: | + [[Set]] ( P, V, Receiver) + + 6. Let trap be GetMethod(handler, "set"). + ... + + 7.3.9 GetMethod (O, P) + + 5. If IsCallable(func) is false, throw a TypeError exception. +features: [cross-realm, Proxy] +---*/ + +var OProxy = $262.createRealm().global.Proxy; +var p = new OProxy({}, { + set: {} +}); + +assert.throws(TypeError, function() { + p.attr = 1; +}); + +assert.throws(TypeError, function() { + p["attr"] = 1; +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/set/trap-is-not-callable.js b/js/src/tests/test262/built-ins/Proxy/set/trap-is-not-callable.js new file mode 100644 index 0000000000..60ca4a96d0 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/set/trap-is-not-callable.js @@ -0,0 +1,31 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.9 +description: > + Trap is not callable. +info: | + [[Set]] ( P, V, Receiver) + + 6. Let trap be GetMethod(handler, "set"). + ... + + 7.3.9 GetMethod (O, P) + + 5. If IsCallable(func) is false, throw a TypeError exception. +features: [Proxy] +---*/ + +var p = new Proxy({}, { + set: {} +}); + +assert.throws(TypeError, function() { + p.attr = 1; +}); + +assert.throws(TypeError, function() { + p["attr"] = 1; +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/set/trap-is-null-receiver.js b/js/src/tests/test262/built-ins/Proxy/set/trap-is-null-receiver.js new file mode 100644 index 0000000000..ae93a63b62 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/set/trap-is-null-receiver.js @@ -0,0 +1,32 @@ +// Copyright (C) 2016 Aleksey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-set-p-v-receiver +description: > + Pass to target's [[Set]] correct receiver if trap is missing +info: | + [[Set]] (P, V, Receiver) + + 7. If trap is undefined, then + a. Return ? target.[[Set]](P, V, Receiver). +features: [Proxy] +---*/ + +var context; +var target = { + set attr(val) { + context = this; + } +}; + +var p = new Proxy(target, { + set: null +}); +p.attr = 1; +assert.sameValue(context, p); + +var pParent = Object.create(new Proxy(target, {})); +pParent.attr = 3; +assert.sameValue(context, pParent); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/set/trap-is-null-target-is-proxy.js b/js/src/tests/test262/built-ins/Proxy/set/trap-is-null-target-is-proxy.js new file mode 100644 index 0000000000..4687576ddd --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/set/trap-is-null-target-is-proxy.js @@ -0,0 +1,51 @@ +// Copyright (C) 2020 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-set-p-v-receiver +description: > + If "set" trap is null or undefined, [[Set]] call is properly + forwarded to [[ProxyTarget]] (which is also a Proxy object). +info: | + [[Set]] ( P, V, Receiver ) + + [...] + 5. Let target be O.[[ProxyTarget]]. + 6. Let trap be ? GetMethod(handler, "set"). + 7. If trap is undefined, then + a. Return ? target.[[Set]](P, V, Receiver). +features: [Proxy, Reflect] +includes: [compareArray.js] +---*/ + +var array = [1, 2, 3]; +var arrayTarget = new Proxy(array, {}); +var arrayProxy = new Proxy(arrayTarget, { + set: null, +}); + +arrayProxy.length = 0; +assert.compareArray(array, []); + +Object.preventExtensions(array); + +assert(!Reflect.set(arrayProxy, "foo", 2)); +assert.throws(TypeError, function() { + "use strict"; + arrayProxy[0] = 3; +}); + + +var string = new String("str"); +var stringTarget = new Proxy(string, {}); +var stringProxy = new Proxy(stringTarget, { + set: null, +}); + +stringProxy[4] = 1; +assert.sameValue(string[4], 1); + +assert(!Reflect.set(stringProxy, "0", "s")); +assert(!Reflect.set(stringProxy, "length", 3)); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/set/trap-is-undefined-no-property.js b/js/src/tests/test262/built-ins/Proxy/set/trap-is-undefined-no-property.js new file mode 100644 index 0000000000..8929897575 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/set/trap-is-undefined-no-property.js @@ -0,0 +1,22 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.9 +description: > + [[Set]] ( P, V, Receiver) + + 8. If trap is undefined, then return target.[[Set]](P, V, Receiver). + +features: [Proxy] +---*/ + +var target = { + attr: 1 +}; +var p = new Proxy(target, {}); + +p.attr = 2; + +assert.sameValue(target.attr, 2); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/set/trap-is-undefined-target-is-proxy.js b/js/src/tests/test262/built-ins/Proxy/set/trap-is-undefined-target-is-proxy.js new file mode 100644 index 0000000000..ac2f7a8497 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/set/trap-is-undefined-target-is-proxy.js @@ -0,0 +1,54 @@ +// Copyright (C) 2020 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-set-p-v-receiver +description: > + If "set" trap is null or undefined, [[Set]] call is properly + forwarded to [[ProxyTarget]] (which is also a Proxy object). +info: | + [[Set]] ( P, V, Receiver ) + + [...] + 5. Let target be O.[[ProxyTarget]]. + 6. Let trap be ? GetMethod(handler, "set"). + 7. If trap is undefined, then + a. Return ? target.[[Set]](P, V, Receiver). +features: [Proxy, Reflect] +---*/ + +var func = function() {}; +var funcTarget = new Proxy(func, {}); +var funcProxy = new Proxy(funcTarget, { + set: undefined, +}); + +assert(Reflect.set(funcProxy, "prototype", null)); +assert.sameValue(func.prototype, null); + +assert(!Reflect.set(funcProxy, "length", 2)); +assert.throws(TypeError, function() { + "use strict"; + funcProxy.name = "foo"; +}); + + +var trapCalls = 0; +var target = new Proxy({}, { + set: function(_target, key) { + trapCalls++; + return key === "foo"; + }, +}); + +var proxy = new Proxy(target, { + set: undefined, +}); + +assert(Reflect.set(Object.create(proxy), "foo", 1)); +assert.sameValue(trapCalls, 1); + +assert(!Reflect.set(proxy, "bar", 2)); +assert.sameValue(trapCalls, 2); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/set/trap-is-undefined.js b/js/src/tests/test262/built-ins/Proxy/set/trap-is-undefined.js new file mode 100644 index 0000000000..3bc6d09e01 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/set/trap-is-undefined.js @@ -0,0 +1,25 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-set-p-v-receiver +description: > + [[Set]] ( P, V, Receiver) + + 7. If trap is undefined, then + a. Return ? target.[[Set]](P, V, Receiver) + +features: [Proxy] +---*/ + +var target = { + attr: 1 +}; +var p = new Proxy(target, { + set: undefined +}); + +p.attr = 2; + +assert.sameValue(target.attr, 2); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/browser.js b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/browser.js diff --git a/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/call-parameters.js b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/call-parameters.js new file mode 100644 index 0000000000..bc5ac03d57 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/call-parameters.js @@ -0,0 +1,41 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.2 +description: > + Trap is called with handler on its context, first parameter is target and + second parameter is the given value. +info: | + [[SetPrototypeOf]] (V) + + ... + 9. Let booleanTrapResult be ToBoolean(Call(trap, handler, «target, V»)). + ... +features: [Proxy] +---*/ + +var _handler, _target, _value; +var target = {}; +var val = { + foo: 1 +}; +var handler = { + setPrototypeOf: function(t, v) { + _handler = this; + _target = t; + _value = v; + + Object.setPrototypeOf(t, v); + + return true; + } +}; +var p = new Proxy(target, handler); + +Object.setPrototypeOf(p, val); + +assert.sameValue(_handler, handler); +assert.sameValue(_target, target); +assert.sameValue(_value, val); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/internals-call-order.js b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/internals-call-order.js new file mode 100644 index 0000000000..e6f3e20551 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/internals-call-order.js @@ -0,0 +1,50 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-setprototypeof-v +description: > + Calls target.[[GetPrototypeOf]] after trap result as false and not extensible + target +info: | + [[SetPrototypeOf]] (V) + + 8. Let booleanTrapResult be ToBoolean(? Call(trap, handler, « target, V »)). + 9. If booleanTrapResult is false, return false. + 10. Let extensibleTarget be ? IsExtensible(target). + 11. If extensibleTarget is true, return true. + 12. Let targetProto be ? target.[[GetPrototypeOf]](). +features: [Proxy, Reflect, Reflect.setPrototypeOf] +---*/ + +var calls = []; +var proto = {}; + +var target = new Proxy(Object.create(proto), { + isExtensible: function() { + calls.push("target.[[IsExtensible]]"); + return false; + }, + getPrototypeOf: function() { + calls.push("target.[[GetPrototypeOf]]"); + return proto; + } +}); + +// Proxy must report same extensiblitity as target +Object.preventExtensions(target); + +var proxy = new Proxy(target, { + setPrototypeOf: function() { + calls.push("proxy.[[setPrototypeOf]]"); + return true; + } +}); + +assert.sameValue(Reflect.setPrototypeOf(proxy, proto), true); +assert.sameValue(calls.length, 3); +assert.sameValue(calls[0], "proxy.[[setPrototypeOf]]"); +assert.sameValue(calls[1], "target.[[IsExtensible]]"); +assert.sameValue(calls[2], "target.[[GetPrototypeOf]]"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/not-extensible-target-not-same-target-prototype.js b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/not-extensible-target-not-same-target-prototype.js new file mode 100644 index 0000000000..3c59f9a50e --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/not-extensible-target-not-same-target-prototype.js @@ -0,0 +1,55 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.2 +description: > + Throws a TypeError exception if boolean trap result is true, target is + not extensible, and the given parameter is not the same object as the target + prototype. +info: | + [[SetPrototypeOf]] (V) + + ... + 2. Let handler be the value of the [[ProxyHandler]] internal slot of O. + ... + 5. Let target be the value of the [[ProxyTarget]] internal slot of O. + 6. Let trap be GetMethod(handler, "setPrototypeOf"). + ... + 9. Let booleanTrapResult be ToBoolean(Call(trap, handler, «target, V»)). + 14. Let targetProto be target.[[GetPrototypeOf]](). + 15. ReturnIfAbrupt(targetProto). + 16. If booleanTrapResult is true and SameValue(V, targetProto) is false, + throw a TypeError exception. + ... +features: [Proxy, Reflect, Reflect.setPrototypeOf] +---*/ + +var target, proxy; +target = {}; +proxy = new Proxy(target, { + setPrototypeOf: function() { + return true; + } +}); + +Object.preventExtensions(target); + +assert.throws(TypeError, function() { + Reflect.setPrototypeOf(proxy, {}); +}, "target prototype is different"); + +var proto = {}; +target = Object.setPrototypeOf({}, proto); +proxy = new Proxy(target, { + setPrototypeOf: function() { + Object.setPrototypeOf(target, {}); + Object.preventExtensions(target); + return true; + } +}); + +assert.throws(TypeError, function() { + Reflect.setPrototypeOf(proxy, proto); +}, "target prototype is changed inside trap handler"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/not-extensible-target-same-target-prototype.js b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/not-extensible-target-same-target-prototype.js new file mode 100644 index 0000000000..8910a2ddcd --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/not-extensible-target-same-target-prototype.js @@ -0,0 +1,56 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-setprototypeof-v +description: > + Handler can only return true for non-extensible targets if the given prototype + is the same as target's prototype +info: | + [[SetPrototypeOf]] (V) + + 12. Let targetProto be ? target.[[GetPrototypeOf]](). + 13. If SameValue(V, targetProto) is false, throw a TypeError exception. + 14. Return true. +features: [Proxy, Reflect, Reflect.setPrototypeOf] +---*/ + +var proto = {}; +var target = Object.setPrototypeOf({}, proto); + +Object.preventExtensions(target); + +var proxy; + +proxy = new Proxy(target, { + setPrototypeOf: function() { + return true; + } +}); + +assert.sameValue( + Reflect.setPrototypeOf(proxy, proto), + true, + "prototype arg is the same in target" +); + +var outro = {}; +proxy = new Proxy(outro, { + setPrototypeOf: function(t, p) { + Object.setPrototypeOf(t, p); + Object.preventExtensions(t); + return true; + } +}); + +assert.sameValue( + Reflect.setPrototypeOf(proxy, proto), + true, + "prototype is set to target inside handler trap" +); +assert.sameValue( + Object.getPrototypeOf(outro), + proto, + "target has the custom set prototype" +); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/null-handler.js b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/null-handler.js new file mode 100644 index 0000000000..71aa84b3ad --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/null-handler.js @@ -0,0 +1,18 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.2 +description: > + Throws a TypeError exception if handler is null +features: [Proxy] +---*/ + +var p = Proxy.revocable({}, {}); + +p.revoke(); + +assert.throws(TypeError, function() { + Object.setPrototypeOf(p.proxy, {}); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/return-abrupt-from-get-trap.js b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/return-abrupt-from-get-trap.js new file mode 100644 index 0000000000..aa525697bc --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/return-abrupt-from-get-trap.js @@ -0,0 +1,26 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-call-thisargument-argumentslist +description: > + Return abrupt getting handler trap +info: | + [[SetPrototypeOf]] (V) + + 6. Let trap be ? GetMethod(handler, "setPrototypeOf"). +features: [Proxy] +---*/ + +var handler = Object.defineProperty({}, "setPrototypeOf", { + get: function() { + throw new Test262Error(); + } +}); + +var proxy = new Proxy({}, handler); + +assert.throws(Test262Error, function() { + Object.setPrototypeOf(proxy, {}); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/return-abrupt-from-isextensible-target.js b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/return-abrupt-from-isextensible-target.js new file mode 100644 index 0000000000..1ff2cb555c --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/return-abrupt-from-isextensible-target.js @@ -0,0 +1,31 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-setprototypeof-v +description: > + Return abrupt from IsExtensible(target) +info: | + [[SetPrototypeOf]] (V) + + 10. Let extensibleTarget be ? IsExtensible(target). +features: [Proxy] +---*/ + +var target = new Proxy({}, { + isExtensible: function() { + throw new Test262Error(); + } +}); + +var proxy = new Proxy(target, { + setPrototypeOf: function() { + return true; + } +}); + +assert.throws(Test262Error, function() { + Object.setPrototypeOf(proxy, {}); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/return-abrupt-from-target-getprototypeof.js b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/return-abrupt-from-target-getprototypeof.js new file mode 100644 index 0000000000..49173d7f77 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/return-abrupt-from-target-getprototypeof.js @@ -0,0 +1,33 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-setprototypeof-v +description: > + Return abrupt from target.[[GetPrototypeOf]]() +info: | + [[SetPrototypeOf]] (V) + + 12. Let targetProto be ? target.[[GetPrototypeOf]](). +features: [Proxy] +---*/ + +var target = new Proxy({}, { + getPrototypeOf: function() { + throw new Test262Error(); + } +}); + +Object.preventExtensions(target); + +var proxy = new Proxy(target, { + setPrototypeOf: function() { + return true; + } +}); + +assert.throws(Test262Error, function() { + Object.setPrototypeOf(proxy, {}); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/return-abrupt-from-trap.js b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/return-abrupt-from-trap.js new file mode 100644 index 0000000000..b5d0c90d17 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/return-abrupt-from-trap.js @@ -0,0 +1,27 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.2 +description: > + Trap returns abrupt. +info: | + [[SetPrototypeOf]] (V) + + 9. Let booleanTrapResult be ToBoolean(Call(trap, handler, «target, V»)). + 10. ReturnIfAbrupt(booleanTrapResult). +features: [Proxy] +---*/ + +var p = new Proxy({}, { + setPrototypeOf: function() { + throw new Test262Error(); + } +}); + +assert.throws(Test262Error, function() { + Object.setPrototypeOf(p, { + value: 1 + }); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/shell.js b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/shell.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/shell.js diff --git a/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/toboolean-trap-result-false.js b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/toboolean-trap-result-false.js new file mode 100644 index 0000000000..8720cffbc7 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/toboolean-trap-result-false.js @@ -0,0 +1,77 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-setprototypeof-v +description: > + Return false if ToBoolean(trap result) is false, without checking + target.[[IsExtensible]] +info: | + [[SetPrototypeOf]] (V) + + 8. Let booleanTrapResult be ToBoolean(? Call(trap, handler, « target, V »)). + 9. If booleanTrapResult is false, return false. + 10. Let extensibleTarget be ? IsExtensible(target). + 11. If extensibleTarget is true, return true. +features: [Proxy, Reflect, Reflect.setPrototypeOf] +---*/ + +var called = 0; + +var target = new Proxy({}, { + isExtensible: function() { + called += 1; + } +}); + +var p = new Proxy(target, { + setPrototypeOf: function(t, v) { + return v.attr; + } +}); + +var result; + +result = Reflect.setPrototypeOf(p, { + attr: false +}); +assert.sameValue(result, false, "false"); +assert.sameValue(called, 0, "false - isExtensible is not called"); + +result = Reflect.setPrototypeOf(p, { + attr: "" +}); +assert.sameValue(result, false, "the empty string"); +assert.sameValue(called, 0, "the empty string - isExtensible is not called"); + +result = Reflect.setPrototypeOf(p, { + attr: 0 +}); +assert.sameValue(result, false, "0"); +assert.sameValue(called, 0, "0 - isExtensible is not called"); + +result = Reflect.setPrototypeOf(p, { + attr: -0 +}); +assert.sameValue(result, false, "-0"); +assert.sameValue(called, 0, "-0 - isExtensible is not called"); + +result = Reflect.setPrototypeOf(p, { + attr: null +}); +assert.sameValue(result, false, "null"); +assert.sameValue(called, 0, "null - isExtensible is not called"); + +result = Reflect.setPrototypeOf(p, { + attr: undefined +}); +assert.sameValue(result, false, "undefined"); +assert.sameValue(called, 0, "undefined - isExtensible is not called"); + +result = Reflect.setPrototypeOf(p, { + attr: NaN +}); +assert.sameValue(result, false, "NaN"); +assert.sameValue(called, 0, "NaN - isExtensible is not called"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/toboolean-trap-result-true-target-is-extensible.js b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/toboolean-trap-result-true-target-is-extensible.js new file mode 100644 index 0000000000..6da14809f0 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/toboolean-trap-result-true-target-is-extensible.js @@ -0,0 +1,80 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-setprototypeof-v +description: > + Return true if ToBoolean(trap result) is true, and target.[[IsExtensible]] is + true +info: | + [[SetPrototypeOf]] (V) + + 8. Let booleanTrapResult be ToBoolean(? Call(trap, handler, « target, V »)). + 9. If booleanTrapResult is false, return false. + 10. Let extensibleTarget be ? IsExtensible(target). + 11. If extensibleTarget is true, return true. +features: [Proxy, Reflect, Reflect.setPrototypeOf, Symbol] +---*/ + +var called; +var target = new Proxy({}, { + isExtensible: function() { + called += 1; + return true; + }, + getPrototypeOf: function() { + throw new Test262Error("target.[[GetPrototypeOf]] is not called"); + } +}); + +var p = new Proxy(target, { + setPrototypeOf: function(t, v) { + return v.attr; + } +}); + +var result; + +called = 0; +result = Reflect.setPrototypeOf(p, { + attr: true +}); +assert.sameValue(result, true, "true"); +assert.sameValue(called, 1, "true - isExtensible is called"); + +called = 0; +result = Reflect.setPrototypeOf(p, { + attr: "false" +}); +assert.sameValue(result, true, "string"); +assert.sameValue(called, 1, "string - isExtensible is called"); + +called = 0; +result = Reflect.setPrototypeOf(p, { + attr: 42 +}); +assert.sameValue(result, true, "42"); +assert.sameValue(called, 1, "number - isExtensible is called"); + +called = 0; +result = Reflect.setPrototypeOf(p, { + attr: p +}); +assert.sameValue(result, true, "p"); +assert.sameValue(called, 1, "object - isExtensible is called"); + +called = 0; +result = Reflect.setPrototypeOf(p, { + attr: [] +}); +assert.sameValue(result, true, "[]"); +assert.sameValue(called, 1, "[] - isExtensible is called"); + +called = 0; +result = Reflect.setPrototypeOf(p, { + attr: Symbol(1) +}); +assert.sameValue(result, true, "symbol"); +assert.sameValue(called, 1, "symbol - isExtensible is called"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/trap-is-missing-target-is-proxy.js b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/trap-is-missing-target-is-proxy.js new file mode 100644 index 0000000000..8a3f56b5cb --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/trap-is-missing-target-is-proxy.js @@ -0,0 +1,38 @@ +// Copyright (C) 2020 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-setprototypeof-v +description: > + If "setPrototypeOf" trap is null or undefined, [[SetPrototypeOf]] call + is properly forwarded to [[ProxyTarget]] (which is also a Proxy object). +info: | + [[SetPrototypeOf]] ( V ) + + [...] + 5. Let target be O.[[ProxyTarget]]. + 6. Let trap be ? GetMethod(handler, "setPrototypeOf"). + 7. If trap is undefined, then + a. Return ? target.[[SetPrototypeOf]](V). + + [[SetPrototypeOf]] ( V ) + + [...] + 8. Let booleanTrapResult be ! ToBoolean(? Call(trap, handler, « target, V »)). + 9. If booleanTrapResult is false, return false. +features: [Proxy] +---*/ + +var target = new Proxy({}, { + setPrototypeOf: function(_target, _value) { + return false; + }, +}); + +var proxy = new Proxy(target, {}); + +assert.throws(TypeError, function() { + Object.setPrototypeOf(proxy, null); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/trap-is-not-callable-realm.js b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/trap-is-not-callable-realm.js new file mode 100644 index 0000000000..6bcdbf6d11 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/trap-is-not-callable-realm.js @@ -0,0 +1,36 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-setprototypeof-v +description: > + Throws if trap is not callable (honoring the Realm of the current execution + context) +info: | + [[SetPrototypeOf]] (V) + + ... + 2. Let handler be the value of the [[ProxyHandler]] internal slot of O. + ... + 5. Let target be the value of the [[ProxyTarget]] internal slot of O. + 6. Let trap be GetMethod(handler, "setPrototypeOf"). + ... + 7.3.9 GetMethod (O, P) + ... + 2. Let func be GetV(O, P). + 5. If IsCallable(func) is false, throw a TypeError exception. + ... +features: [cross-realm, Proxy] +---*/ + +var OProxy = $262.createRealm().global.Proxy; +var p = new OProxy({}, { + setPrototypeOf: {} +}); + +assert.throws(TypeError, function() { + Object.setPrototypeOf(p, { + value: 1 + }); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/trap-is-not-callable.js b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/trap-is-not-callable.js new file mode 100644 index 0000000000..358588e831 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/trap-is-not-callable.js @@ -0,0 +1,35 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 9.5.2 +description: > + Throws a TypeError exception if trap is not callable. +info: | + [[SetPrototypeOf]] (V) + + ... + 2. Let handler be the value of the [[ProxyHandler]] internal slot of O. + ... + 5. Let target be the value of the [[ProxyTarget]] internal slot of O. + 6. Let trap be GetMethod(handler, "setPrototypeOf"). + ... + 7.3.9 GetMethod (O, P) + ... + 2. Let func be GetV(O, P). + 5. If IsCallable(func) is false, throw a TypeError exception. + ... +features: [Proxy, Reflect, Reflect.setPrototypeOf] +---*/ + +var target = {}; +var p = new Proxy(target, { + setPrototypeOf: {} +}); + +assert.throws(TypeError, function() { + Reflect.setPrototypeOf(p, { + value: 1 + }); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/trap-is-null-target-is-proxy.js b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/trap-is-null-target-is-proxy.js new file mode 100644 index 0000000000..c9857e94aa --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/trap-is-null-target-is-proxy.js @@ -0,0 +1,42 @@ +// Copyright (C) 2020 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-setprototypeof-v +description: > + If "setPrototypeOf" trap is null or undefined, [[SetPrototypeOf]] call + is properly forwarded to [[ProxyTarget]] (which is also a Proxy object). +info: | + [[SetPrototypeOf]] ( V ) + + [...] + 5. Let target be O.[[ProxyTarget]]. + 6. Let trap be ? GetMethod(handler, "setPrototypeOf"). + 7. If trap is undefined, then + a. Return ? target.[[SetPrototypeOf]](V). + + OrdinarySetPrototypeOf ( O, V ) + + [...] + 8. Repeat, while done is false, + a. If p is null, set done to true. + b. Else if SameValue(p, O) is true, return false. + [...] +features: [Proxy] +---*/ + +var plainObject = {}; +var plainObjectTarget = new Proxy(plainObject, {}); +var plainObjectProxy = new Proxy(plainObjectTarget, { + setPrototypeOf: null, +}); + +Object.setPrototypeOf(plainObjectProxy, null); +assert.sameValue(Object.getPrototypeOf(plainObject), null); + +var cyclicPrototype = Object.create(plainObject); +assert.throws(TypeError, function() { + Object.setPrototypeOf(plainObjectProxy, cyclicPrototype); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/trap-is-undefined-or-null.js b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/trap-is-undefined-or-null.js new file mode 100644 index 0000000000..84fa1c2d77 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/trap-is-undefined-or-null.js @@ -0,0 +1,47 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-setprototypeof-v +description: > + Return target.[[SetPrototypeOf]] (V) if trap is undefined or null. +info: | + [[SetPrototypeOf]] (V) + + 6. Let trap be ? GetMethod(handler, "setPrototypeOf"). + 7. If trap is undefined, then + a. Return ? target.[[SetPrototypeOf]](V). + + GetMethod (V, P) + + 2. Let func be ? GetV(V, P). + 3. If func is either undefined or null, return undefined. +features: [Proxy] +---*/ + +var proxy, called, value; +var target = new Proxy({}, { + setPrototypeOf: function(t, v) { + called += 1; + value = v; + return true; + } +}); +var proto = {}; + +proxy = new Proxy(target, {}); +called = 0; +value = false; +Object.setPrototypeOf(proxy, proto); +assert.sameValue(called, 1, "undefined, target.[[SetPrototypeOf]] is called"); +assert.sameValue(value, proto, "undefined, called with V"); + +proxy = new Proxy(target, { + setPrototypeOf: null +}); +called = 0; +value = false; +Object.setPrototypeOf(proxy, proto); +assert.sameValue(called, 1, "null, target.[[SetPrototypeOf]] is called"); +assert.sameValue(value, proto, "null, called with V"); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/trap-is-undefined-target-is-proxy.js b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/trap-is-undefined-target-is-proxy.js new file mode 100644 index 0000000000..091fe8abb4 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/setPrototypeOf/trap-is-undefined-target-is-proxy.js @@ -0,0 +1,40 @@ +// Copyright (C) 2020 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-proxy-object-internal-methods-and-internal-slots-setprototypeof-v +description: > + If "setPrototypeOf" trap is null or undefined, [[SetPrototypeOf]] call + is properly forwarded to [[ProxyTarget]] (which is also a Proxy object). +info: | + [[SetPrototypeOf]] ( V ) + + [...] + 5. Let target be O.[[ProxyTarget]]. + 6. Let trap be ? GetMethod(handler, "setPrototypeOf"). + 7. If trap is undefined, then + a. Return ? target.[[SetPrototypeOf]](V). + + OrdinarySetPrototypeOf ( O, V ) + + [...] + 4. Let extensible be O.[[Extensible]]. + 5. If extensible is false, return false. +features: [Proxy] +---*/ + +var array = []; +var arrayTarget = new Proxy(array, {}); +var arrayProxy = new Proxy(arrayTarget, { + setPrototypeOf: undefined, +}); + +Object.setPrototypeOf(arrayProxy, Number.prototype); +assert.sameValue(Object.getPrototypeOf(array), Number.prototype); + +Object.preventExtensions(array); +assert.throws(TypeError, function() { + Object.setPrototypeOf(arrayProxy, null); +}); + +reportCompare(0, 0); diff --git a/js/src/tests/test262/built-ins/Proxy/shell.js b/js/src/tests/test262/built-ins/Proxy/shell.js new file mode 100644 index 0000000000..eda1477282 --- /dev/null +++ b/js/src/tests/test262/built-ins/Proxy/shell.js @@ -0,0 +1,24 @@ +// GENERATED, DO NOT EDIT +// file: isConstructor.js +// Copyright (C) 2017 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: | + Test if a given function is a constructor function. +defines: [isConstructor] +features: [Reflect.construct] +---*/ + +function isConstructor(f) { + if (typeof f !== "function") { + throw new Test262Error("isConstructor invoked with a non-function value"); + } + + try { + Reflect.construct(function(){}, [], f); + } catch (e) { + return false; + } + return true; +} |