From b5c9e7122e00f666eb6b175ed01ac7ca42f4d90b Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Mon, 10 Feb 2025 20:25:56 +0530 Subject: [PATCH] Add tests for SuppressedError --- .../message-method-prop-cast.js | 69 +++++++++++++++++++ .../SuppressedError/message-method-prop.js | 33 +++++++++ .../message-tostring-abrupt-symbol.js | 39 +++++++++++ .../message-tostring-abrupt.js | 59 ++++++++++++++++ .../SuppressedError/newtarget-is-undefined.js | 19 +++++ .../SuppressedError/newtarget-proto-custom.js | 47 +++++++++++++ .../newtarget-proto-fallback.js | 58 ++++++++++++++++ .../SuppressedError/newtarget-proto.js | 35 ++++++++++ .../order-of-args-evaluation.js | 37 ++++++++++ .../prototype/errors-absent-on-prototype.js | 20 ++++++ 10 files changed, 416 insertions(+) create mode 100644 test/built-ins/NativeErrors/SuppressedError/message-method-prop-cast.js create mode 100644 test/built-ins/NativeErrors/SuppressedError/message-method-prop.js create mode 100644 test/built-ins/NativeErrors/SuppressedError/message-tostring-abrupt-symbol.js create mode 100644 test/built-ins/NativeErrors/SuppressedError/message-tostring-abrupt.js create mode 100644 test/built-ins/NativeErrors/SuppressedError/newtarget-is-undefined.js create mode 100644 test/built-ins/NativeErrors/SuppressedError/newtarget-proto-custom.js create mode 100644 test/built-ins/NativeErrors/SuppressedError/newtarget-proto-fallback.js create mode 100644 test/built-ins/NativeErrors/SuppressedError/newtarget-proto.js create mode 100644 test/built-ins/NativeErrors/SuppressedError/order-of-args-evaluation.js create mode 100644 test/built-ins/NativeErrors/SuppressedError/prototype/errors-absent-on-prototype.js diff --git a/test/built-ins/NativeErrors/SuppressedError/message-method-prop-cast.js b/test/built-ins/NativeErrors/SuppressedError/message-method-prop-cast.js new file mode 100644 index 00000000000..1b9e730bfe7 --- /dev/null +++ b/test/built-ins/NativeErrors/SuppressedError/message-method-prop-cast.js @@ -0,0 +1,69 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-suppressederror-constructor +description: > + Cast ToString values of message in the created method property +info: | + SuppressedError ( error, suppressed, message ) + + ... + 5. If message is not undefined, then + a. Let msg be ? ToString(message). + b. Perform ! CreateMethodProperty(O, "message", msg). + 6. Return O. + + CreateMethodProperty ( O, P, V ) + + ... + 3. Let newDesc be the PropertyDescriptor { [[Value]]: V, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }. + 4. Return ? O.[[DefineOwnProperty]](P, newDesc). +features: [explicit-resource-management] +includes: [propertyHelper.js] +---*/ + +var case1 = new SuppressedError(undefined, undefined, 42); + +verifyProperty(case1, 'message', { + value: '42', + writable: true, + enumerable: false, + configurable: true, +}); + +var case2 = new SuppressedError(undefined, undefined, false); + +verifyProperty(case2, 'message', { + value: 'false', + writable: true, + enumerable: false, + configurable: true, +}); + +var case3 = new SuppressedError(undefined, undefined, true); + +verifyProperty(case3, 'message', { + value: 'true', + writable: true, + enumerable: false, + configurable: true, +}); + +var case4 = new SuppressedError(undefined, undefined, { toString() { return 'string'; }}); + +verifyProperty(case4, 'message', { + value: 'string', + writable: true, + enumerable: false, + configurable: true, +}); + +var case5 = new SuppressedError(undefined, undefined, null); + +verifyProperty(case5, 'message', { + value: 'null', + writable: true, + enumerable: false, + configurable: true, +}); diff --git a/test/built-ins/NativeErrors/SuppressedError/message-method-prop.js b/test/built-ins/NativeErrors/SuppressedError/message-method-prop.js new file mode 100644 index 00000000000..f4fd4201e13 --- /dev/null +++ b/test/built-ins/NativeErrors/SuppressedError/message-method-prop.js @@ -0,0 +1,33 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-suppressederror-constructor +description: > + Creates a method property for message +info: | + SuppressedError ( error, suppressed, message ) + + ... + 5. If message is not undefined, then + a. Let msg be ? ToString(message). + b. Perform ! CreateMethodProperty(O, "message", msg). + 6. Return O. + + CreateMethodProperty ( O, P, V ) + + ... + 3. Let newDesc be the PropertyDescriptor { [[Value]]: V, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }. + 4. Return ? O.[[DefineOwnProperty]](P, newDesc). +features: [explicit-resource-management] +includes: [propertyHelper.js] +---*/ + +var obj = new SuppressedError(undefined, undefined, '42'); + +verifyProperty(obj, 'message', { + value: '42', + writable: true, + enumerable: false, + configurable: true, +}); diff --git a/test/built-ins/NativeErrors/SuppressedError/message-tostring-abrupt-symbol.js b/test/built-ins/NativeErrors/SuppressedError/message-tostring-abrupt-symbol.js new file mode 100644 index 00000000000..826208a8024 --- /dev/null +++ b/test/built-ins/NativeErrors/SuppressedError/message-tostring-abrupt-symbol.js @@ -0,0 +1,39 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-suppressederror-constructor +description: > + Abrupt completions of ToString(Symbol message) +info: | + SuppressedError ( error, suppressed, message ) + + ... + 5. If message is not undefined, then + a. Let msg be ? ToString(message). + b. Perform ! CreateMethodProperty(O, "message", msg). + 6. Return O. +features: [explicit-resource-management, Symbol, Symbol.toPrimitive] +---*/ + +var case1 = Symbol(); + +assert.throws(TypeError, () => { + new SuppressedError(undefined, undefined, case1); +}, 'toPrimitive'); + +var case2 = { + [Symbol.toPrimitive]() { + return Symbol(); + }, + toString() { + throw new Test262Error(); + }, + valueOf() { + throw new Test262Error(); + } +}; + +assert.throws(TypeError, () => { + new SuppressedError(undefined, undefined, case2); +}, 'from ToPrimitive'); diff --git a/test/built-ins/NativeErrors/SuppressedError/message-tostring-abrupt.js b/test/built-ins/NativeErrors/SuppressedError/message-tostring-abrupt.js new file mode 100644 index 00000000000..0d1b86e122e --- /dev/null +++ b/test/built-ins/NativeErrors/SuppressedError/message-tostring-abrupt.js @@ -0,0 +1,59 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-suppressederror-constructor +description: > + Abrupt completions of ToString(message) +info: | + SuppressedError ( error, suppressed, message ) + + ... + 5. If message is not undefined, then + a. Let msg be ? ToString(message). + b. Perform ! CreateMethodProperty(O, "message", msg). + 6. Return O. +features: [explicit-resource-management, Symbol.toPrimitive] +---*/ + +var case1 = { + [Symbol.toPrimitive]() { + throw new Test262Error(); + }, + toString() { + throw 'toString called'; + }, + valueOf() { + throw 'valueOf called'; + } +}; + +assert.throws(Test262Error, () => { + new SuppressedError(undefined, undefined, case1); +}, 'toPrimitive'); + +var case2 = { + [Symbol.toPrimitive]: undefined, + toString() { + throw new Test262Error(); + }, + valueOf() { + throw 'valueOf called'; + } +}; + +assert.throws(Test262Error, () => { + new SuppressedError(undefined, undefined, case2); +}, 'toString'); + +var case3 = { + [Symbol.toPrimitive]: undefined, + toString: undefined, + valueOf() { + throw new Test262Error(); + } +}; + +assert.throws(Test262Error, () => { + new SuppressedError(undefined, undefined, case3); +}, 'valueOf'); diff --git a/test/built-ins/NativeErrors/SuppressedError/newtarget-is-undefined.js b/test/built-ins/NativeErrors/SuppressedError/newtarget-is-undefined.js new file mode 100644 index 00000000000..f5e8cb827a8 --- /dev/null +++ b/test/built-ins/NativeErrors/SuppressedError/newtarget-is-undefined.js @@ -0,0 +1,19 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-suppressederror-constructor +description: > + NewTarget is undefined +info: | + SuppressedError ( error, suppressed, message ) + + 1. If NewTarget is undefined, let newTarget be the active function object, else let newTarget be NewTarget. + +features: [explicit-resource-management] +---*/ + +var obj = SuppressedError(); + +assert.sameValue(Object.getPrototypeOf(obj), SuppressedError.prototype); +assert(obj instanceof SuppressedError); diff --git a/test/built-ins/NativeErrors/SuppressedError/newtarget-proto-custom.js b/test/built-ins/NativeErrors/SuppressedError/newtarget-proto-custom.js new file mode 100644 index 00000000000..98e14d233d6 --- /dev/null +++ b/test/built-ins/NativeErrors/SuppressedError/newtarget-proto-custom.js @@ -0,0 +1,47 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-suppressederror-constructor +description: > + Use a custom NewTarget prototype +info: | + SuppressedError ( error, suppressed, message ) + + 1. If NewTarget is undefined, let newTarget be the active function object, else let newTarget be NewTarget. + 2. Let O be ? OrdinaryCreateFromConstructor(newTarget, "%SuppressedError.prototype%", « [[ErrorData]], [[AggregateErrors]] »). + ... + 6. Return O. + + 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. + Return proto. +features: [explicit-resource-management, Reflect.construct] +---*/ + +var custom = { x: 42 }; +var newt = new Proxy(function() {}, { + get(t, p) { + if (p === 'prototype') { + return custom; + } + + return t[p]; + } +}); + +var obj = Reflect.construct(SuppressedError, [], newt); + +assert.sameValue(Object.getPrototypeOf(obj), custom); +assert.sameValue(obj.x, 42); diff --git a/test/built-ins/NativeErrors/SuppressedError/newtarget-proto-fallback.js b/test/built-ins/NativeErrors/SuppressedError/newtarget-proto-fallback.js new file mode 100644 index 00000000000..42b6fe5872c --- /dev/null +++ b/test/built-ins/NativeErrors/SuppressedError/newtarget-proto-fallback.js @@ -0,0 +1,58 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-suppressederror-constructor +description: > + Fallback to the NewTarget's [[Prototype]] if the prototype property is not an object +info: | + SuppressedError ( error, suppressed, message ) + + 1. If NewTarget is undefined, let newTarget be the active function object, else let newTarget be NewTarget. + 2. Let O be ? OrdinaryCreateFromConstructor(newTarget, "%SuppressedError.prototype%", « [[ErrorData]], [[AggregateErrors]] »). + ... + 6. Return O. + + 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. + Return proto. +features: [explicit-resource-management, Symbol] +---*/ + +const values = [ + undefined, + null, + 42, + false, + true, + Symbol(), + 'string', + SuppressedError.prototype, +]; + +const NewTarget = new Function(); + +for (const value of values) { + const NewTargetProxy = new Proxy(NewTarget, { + get(t, p) { + if (p === 'prototype') { + return value; + } + return t[p]; + } + }); + + const error = Reflect.construct(SuppressedError, [], NewTargetProxy); + assert.sameValue(Object.getPrototypeOf(error), SuppressedError.prototype); +} diff --git a/test/built-ins/NativeErrors/SuppressedError/newtarget-proto.js b/test/built-ins/NativeErrors/SuppressedError/newtarget-proto.js new file mode 100644 index 00000000000..c4f11010d09 --- /dev/null +++ b/test/built-ins/NativeErrors/SuppressedError/newtarget-proto.js @@ -0,0 +1,35 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-suppressederror-constructor +description: > + Default prototype is the %SuppressedError.prototype%" +info: | + SuppressedError ( error, suppressed, message ) + + 1. If NewTarget is undefined, let newTarget be the active function object, else let newTarget be NewTarget. + 2. Let O be ? OrdinaryCreateFromConstructor(newTarget, "%SuppressedError.prototype%", « [[ErrorData]], [[AggregateErrors]] »). + ... + 6. Return O. + + 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. + Return proto. +features: [explicit-resource-management] +---*/ + +var obj = new SuppressedError(); + +assert.sameValue(Object.getPrototypeOf(obj), SuppressedError.prototype); diff --git a/test/built-ins/NativeErrors/SuppressedError/order-of-args-evaluation.js b/test/built-ins/NativeErrors/SuppressedError/order-of-args-evaluation.js new file mode 100644 index 00000000000..292d7578fc9 --- /dev/null +++ b/test/built-ins/NativeErrors/SuppressedError/order-of-args-evaluation.js @@ -0,0 +1,37 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-suppressederror-constructor +description: > + Process arguments in superclass-then-subclass order +info: | + SuppressedError ( error, suppressed, message ) + + 3. If message is not undefined, then + a. Let messageString be ? ToString(message). + b. Perform CreateNonEnumerableDataPropertyOrThrow(O, "message", messageString). + 4. Perform CreateNonEnumerableDataPropertyOrThrow(O, "error", error). + 5. Perform CreateNonEnumerableDataPropertyOrThrow(O, "suppressed", suppressed). + +features: [explicit-resource-management, Symbol.iterator] +---*/ + +let messageStringified = false; +const message = { + toString() { + messageStringified = true; + return ''; + } +}; +const error = {}; +const suppressed = {}; + +const e = new SuppressedError(error, suppressed, message); + +assert.sameValue(messageStringified, true); +const keys = Object.getOwnPropertyNames(e); +assert(keys.indexOf("message") === 0, "Expected 'message' to be defined first"); +assert(keys.indexOf("error") === 1, "Expected 'error' to be defined second"); +assert(keys.indexOf("suppressed") === 2, "Expected 'suppressed' to be defined third"); + diff --git a/test/built-ins/NativeErrors/SuppressedError/prototype/errors-absent-on-prototype.js b/test/built-ins/NativeErrors/SuppressedError/prototype/errors-absent-on-prototype.js new file mode 100644 index 00000000000..4dbfdd3955d --- /dev/null +++ b/test/built-ins/NativeErrors/SuppressedError/prototype/errors-absent-on-prototype.js @@ -0,0 +1,20 @@ +// Copyright (C) 2023 Ron Buckton. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-properties-of-the-suppressederror-prototype-objects +description: > + The SuppressedError prototype object isn't an SuppressedError instance. +info: | + Properties of the SuppressedError Prototype Object + + The SuppressedError prototype object: + ... + - is not an Error instance or an SuppressedError instance and does not have an + [[ErrorData]] internal slot. + ... +features: [explicit-resource-management] +---*/ + +assert.sameValue(SuppressedError.prototype.hasOwnProperty("error"), false); +assert.sameValue(SuppressedError.prototype.hasOwnProperty("suppressed"), false);