From dcccc418b33e1e980d4c3a630e36b1e74aab44bd Mon Sep 17 00:00:00 2001 From: Alexey Shvayka Date: Sat, 10 Apr 2021 02:46:11 +0300 Subject: [PATCH] Test Symbol wrapper object --- ...ned-symbol-wrapper-ordinary-toprimitive.js | 31 +++++++ ...ved-symbol-wrapper-ordinary-toprimitive.js | 83 +++++++++++++++++++ 2 files changed, 114 insertions(+) create mode 100644 test/built-ins/Symbol/prototype/Symbol.toPrimitive/redefined-symbol-wrapper-ordinary-toprimitive.js create mode 100644 test/built-ins/Symbol/prototype/Symbol.toPrimitive/removed-symbol-wrapper-ordinary-toprimitive.js diff --git a/test/built-ins/Symbol/prototype/Symbol.toPrimitive/redefined-symbol-wrapper-ordinary-toprimitive.js b/test/built-ins/Symbol/prototype/Symbol.toPrimitive/redefined-symbol-wrapper-ordinary-toprimitive.js new file mode 100644 index 0000000000..d9ac4ef515 --- /dev/null +++ b/test/built-ins/Symbol/prototype/Symbol.toPrimitive/redefined-symbol-wrapper-ordinary-toprimitive.js @@ -0,0 +1,31 @@ +// Copyright (C) 2021 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-symbol.prototype-@@toprimitive +description: > + If redefined to nullish value, Symbol wrapper object is converted to primitive + via OrdinaryToPrimitive. +info: | + ToPrimitive ( input [ , preferredType ] ) + + [...] + 2. If Type(input) is Object, then + a. Let exoticToPrim be ? GetMethod(input, @@toPrimitive). + b. If exoticToPrim is not undefined, then + [...] + c. If preferredType is not present, let preferredType be number. + d. Return ? OrdinaryToPrimitive(input, preferredType). +features: [Symbol.toPrimitive] +---*/ + +Object.defineProperty(Symbol.prototype, Symbol.toPrimitive, { value: null }); + +assert.sameValue(Object(Symbol()) == "Symbol()", false, "hint: default"); +assert.throws(TypeError, () => { +Object(Symbol()); }, "hint: number"); +assert.sameValue(`${Object(Symbol())}`, "Symbol()", "hint: string"); + +Object.defineProperty(Symbol.prototype, Symbol.toPrimitive, { value: undefined }); + +assert(Object(Symbol.iterator) == Symbol.iterator, "hint: default"); +assert.throws(TypeError, () => { Object(Symbol()) <= ""; }, "hint: number"); +assert.sameValue({ "Symbol()": 1 }[Object(Symbol())], 1, "hint: string"); diff --git a/test/built-ins/Symbol/prototype/Symbol.toPrimitive/removed-symbol-wrapper-ordinary-toprimitive.js b/test/built-ins/Symbol/prototype/Symbol.toPrimitive/removed-symbol-wrapper-ordinary-toprimitive.js new file mode 100644 index 0000000000..27638c85a3 --- /dev/null +++ b/test/built-ins/Symbol/prototype/Symbol.toPrimitive/removed-symbol-wrapper-ordinary-toprimitive.js @@ -0,0 +1,83 @@ +// Copyright (C) 2021 Alexey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-symbol.prototype-@@toprimitive +description: > + If deleted, Symbol wrapper objects is converted to primitive via OrdinaryToPrimitive. +info: | + ToPrimitive ( input [ , preferredType ] ) + + [...] + 2. If Type(input) is Object, then + a. Let exoticToPrim be ? GetMethod(input, @@toPrimitive). + b. If exoticToPrim is not undefined, then + [...] + c. If preferredType is not present, let preferredType be number. + d. Return ? OrdinaryToPrimitive(input, preferredType). +features: [Symbol.toPrimitive] +---*/ + +assert(delete Symbol.prototype[Symbol.toPrimitive]); + +let valueOfGets = 0; +let valueOfCalls = 0; +let valueOfFunction = () => { ++valueOfCalls; return 123; }; +Object.defineProperty(Symbol.prototype, "valueOf", { + get: () => { ++valueOfGets; return valueOfFunction; }, +}); + +assert(Object(Symbol()) == 123, "hint: default"); +assert.sameValue(Object(Symbol()) - 0, 123, "hint: number"); +assert.sameValue("".concat(Object(Symbol())), "Symbol()", "hint: string"); + +assert.sameValue(valueOfGets, 2); +assert.sameValue(valueOfCalls, 2); + +let toStringGets = 0; +let toStringCalls = 0; +let toStringFunction = () => { ++toStringCalls; return "foo"; }; +Object.defineProperty(Symbol.prototype, "toString", { + get: () => { ++toStringGets; return toStringFunction; }, +}); + +assert.sameValue("" + Object(Symbol()), "123", "hint: default"); +assert.sameValue(Object(Symbol()) * 1, 123, "hint: number"); +assert.sameValue({ "123": 1, "Symbol()": 2, "foo": 3 }[Object(Symbol())], 3, "hint: string"); + +assert.sameValue(valueOfGets, 4); +assert.sameValue(valueOfCalls, 4); +assert.sameValue(toStringGets, 1); +assert.sameValue(toStringCalls, 1); + +valueOfFunction = null; + +assert.sameValue(new Date(Object(Symbol())).getTime(), NaN, "hint: default"); +assert.sameValue(+Object(Symbol()), NaN, "hint: number"); +assert.sameValue(`${Object(Symbol())}`, "foo", "hint: string"); + +assert.sameValue(valueOfGets, 6); +assert.sameValue(valueOfCalls, 4); +assert.sameValue(toStringGets, 4); +assert.sameValue(toStringCalls, 4); + +toStringFunction = function() { throw new Test262Error(); }; + +assert.throws(Test262Error, () => { Object(Symbol()) != 123; }, "hint: default"); +assert.throws(Test262Error, () => { Object(Symbol()) / 0; }, "hint: number"); +assert.throws(Test262Error, () => { "".concat(Object(Symbol())); }, "hint: string"); + +assert.sameValue(valueOfGets, 8); +assert.sameValue(valueOfCalls, 4); +assert.sameValue(toStringGets, 7); +assert.sameValue(toStringCalls, 4); + +toStringFunction = undefined; + +assert.throws(TypeError, () => { 1 + Object(Symbol()); }, "hint: default"); +assert.throws(TypeError, () => { Number(Object(Symbol())); }, "hint: number"); +assert.throws(TypeError, () => { String(Object(Symbol())); }, "hint: string"); + +assert.sameValue(valueOfGets, 11); +assert.sameValue(valueOfCalls, 4); +assert.sameValue(toStringGets, 10); +assert.sameValue(toStringCalls, 4);