/* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/licenses/publicdomain/ */ // ES6 19.1.3.6 Object.prototype.toString ( ) function testToString() { var tests = [ [undefined, "[object Undefined]"], [null, "[object Null]"], [[], "[object Array]"], [new String("abc"), "[object String]"], [(function () {return arguments;})(), "[object Arguments]"], [(function () {"use strict"; return arguments;})(), "[object Arguments]"], [function() {}, "[object Function]"], [new Error("abc"), "[object Error]"], [true, "[object Boolean]"], [5, "[object Number]"], [new Date(), "[object Date]"], [/regexp/, "[object RegExp]"], [{[Symbol.toStringTag]: "abc"}, "[object abc]"], [Object.create(JSON), "[object JSON]"], [Object.create(new Number), "[object Object]"], [Object.create(new Number, {[Symbol.toStringTag]: {value: "abc"}}), "[object abc]"], [(function() { var x = new Number(); x[Symbol.toStringTag] = "abc"; return x; })(), "[object abc]"], [[], "[object Array]"] ]; // Testing if the values are obtained the right way. for (let [value, expected] of tests) { let result = Object.prototype.toString.call(value); assertEq(result, expected); } } testToString(); function testProxy() { var count = 0; var metaHandler = new Proxy({}, { get(target, property, receiver) { assertEq(property, "get"); return function(target, property, receiver) { assertEq(property, Symbol.toStringTag); count++; return undefined; } } }); assertEq(Object.prototype.toString.call(new Proxy({}, metaHandler)), "[object Object]") assertEq(Object.prototype.toString.call(new Proxy(new Date, metaHandler)), "[object Object]") assertEq(Object.prototype.toString.call(new Proxy([], metaHandler)), "[object Array]") assertEq(Object.prototype.toString.call(new Proxy(function() {}, metaHandler)), "[object Function]") var {proxy, revoke} = Proxy.revocable({}, metaHandler); revoke(); assertThrowsInstanceOf(() => Object.prototype.toString.call(proxy), TypeError); assertEq(count, 4); } testProxy(); // Tests the passed objects toStringTag values and ensures it's // desc is writable: false, enumerable: false, configurable: true function testDefault(object, expected) { let desc = Object.getOwnPropertyDescriptor(object, Symbol.toStringTag); assertEq(desc.value, expected); assertEq(desc.writable, false); assertEq(desc.enumerable, false); assertEq(desc.configurable, true); } // ES6 19.4.3.5 Symbol.prototype [ @@toStringTag ] testDefault(Symbol.prototype, "Symbol"); // ES6 20.2.1.9 Math [ @@toStringTag ] testDefault(Math, "Math"); // ES6 21.1.5.2.2 %StringIteratorPrototype% [ @@toStringTag ] testDefault(""[Symbol.iterator]().__proto__, "String Iterator") // ES6 22.1.5.2.2 %ArrayIteratorPrototype% [ @@toStringTag ] testDefault([][Symbol.iterator]().__proto__, "Array Iterator") // ES6 22.2.3.31 get %TypedArray%.prototype [ @@toStringTag ] function testTypedArray() { let ta = (new Uint8Array(0)).__proto__.__proto__; let desc = Object.getOwnPropertyDescriptor(ta, Symbol.toStringTag); assertEq(desc.enumerable, false); assertEq(desc.configurable, true); assertEq(desc.set, undefined); let get = desc.get; assertEq(get.name, "get [Symbol.toStringTag]"); assertEq(get.call(3.14), undefined); assertEq(get.call({}), undefined); assertEq(get.call(ta), undefined); let types = [ Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, Float32Array, Float64Array ]; for (let type of types) { let array = new type(0); assertEq(get.call(array), type.name); assertEq(Object.prototype.toString.call(array), `[object ${type.name}]`); } } testTypedArray(); // ES6 23.1.3.13 Map.prototype [ @@toStringTag ] testDefault(Map.prototype, "Map"); // ES6 23.1.5.2.2 %MapIteratorPrototype% [ @@toStringTag ] testDefault(new Map()[Symbol.iterator]().__proto__, "Map Iterator") // ES6 23.2.3.12 Set.prototype [ @@toStringTag ] testDefault(Set.prototype, "Set"); // ES6 23.2.5.2.2 %SetIteratorPrototype% [ @@toStringTag ] testDefault(new Set()[Symbol.iterator]().__proto__, "Set Iterator") // ES6 23.3.3.6 WeakMap.prototype [ @@toStringTag ] testDefault(WeakMap.prototype, "WeakMap"); // ES6 23.4.3.5 WeakSet.prototype [ @@toStringTag ] testDefault(WeakSet.prototype, "WeakSet"); // ES6 24.1.4.4 ArrayBuffer.prototype [ @@toStringTag ] testDefault(ArrayBuffer.prototype, "ArrayBuffer"); // ES6 24.2.4.21 DataView.prototype[ @@toStringTag ] testDefault(DataView.prototype, "DataView"); // ES6 24.3.3 JSON [ @@toStringTag ] testDefault(JSON, "JSON"); // ES6 25.2.3.3 GeneratorFunction.prototype [ @@toStringTag ] testDefault(function* () {}.constructor.prototype, "GeneratorFunction"); // ES6 25.3.1.5 Generator.prototype [ @@toStringTag ] testDefault(function* () {}().__proto__.__proto__, "Generator"); // ES6 25.4.5.4 Promise.prototype [ @@toStringTag ] testDefault(Promise.prototype, "Promise"); // AsyncFunction.prototype [ @@toStringTag ] testDefault(async function() {}.constructor.prototype, "AsyncFunction"); reportCompare(true, true);