summaryrefslogtreecommitdiffstats
path: root/js/src/tests/ecma_6/Symbol
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/tests/ecma_6/Symbol')
-rw-r--r--js/src/tests/ecma_6/Symbol/as-base-value.js87
-rw-r--r--js/src/tests/ecma_6/Symbol/browser.js0
-rw-r--r--js/src/tests/ecma_6/Symbol/comparisons.js34
-rw-r--r--js/src/tests/ecma_6/Symbol/constructor.js35
-rw-r--r--js/src/tests/ecma_6/Symbol/conversions.js89
-rw-r--r--js/src/tests/ecma_6/Symbol/enumeration-order.js40
-rw-r--r--js/src/tests/ecma_6/Symbol/enumeration.js52
-rw-r--r--js/src/tests/ecma_6/Symbol/equality.js30
-rw-r--r--js/src/tests/ecma_6/Symbol/errors.js17
-rw-r--r--js/src/tests/ecma_6/Symbol/for-in-order.js33
-rw-r--r--js/src/tests/ecma_6/Symbol/for.js31
-rw-r--r--js/src/tests/ecma_6/Symbol/json-stringify-keys.js19
-rw-r--r--js/src/tests/ecma_6/Symbol/json-stringify-values.js33
-rw-r--r--js/src/tests/ecma_6/Symbol/keyFor.js15
-rw-r--r--js/src/tests/ecma_6/Symbol/property-accessor.js39
-rw-r--r--js/src/tests/ecma_6/Symbol/property-basics.js44
-rw-r--r--js/src/tests/ecma_6/Symbol/property-inheritance.js50
-rw-r--r--js/src/tests/ecma_6/Symbol/property-nonwritable.js31
-rw-r--r--js/src/tests/ecma_6/Symbol/property-reflection.js136
-rw-r--r--js/src/tests/ecma_6/Symbol/realms.js36
-rw-r--r--js/src/tests/ecma_6/Symbol/shell.js0
-rw-r--r--js/src/tests/ecma_6/Symbol/species.js30
-rw-r--r--js/src/tests/ecma_6/Symbol/surfaces.js34
-rw-r--r--js/src/tests/ecma_6/Symbol/toPrimitive.js39
-rw-r--r--js/src/tests/ecma_6/Symbol/toString.js27
-rw-r--r--js/src/tests/ecma_6/Symbol/toStringTag.js155
-rw-r--r--js/src/tests/ecma_6/Symbol/typed-arrays.js17
-rw-r--r--js/src/tests/ecma_6/Symbol/typeof.js11
-rw-r--r--js/src/tests/ecma_6/Symbol/valueOf.js22
-rw-r--r--js/src/tests/ecma_6/Symbol/well-known.js41
30 files changed, 1227 insertions, 0 deletions
diff --git a/js/src/tests/ecma_6/Symbol/as-base-value.js b/js/src/tests/ecma_6/Symbol/as-base-value.js
new file mode 100644
index 000000000..f0e8400a2
--- /dev/null
+++ b/js/src/tests/ecma_6/Symbol/as-base-value.js
@@ -0,0 +1,87 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/ */
+
+// Like other primitives, symbols can be treated as objects, using object-like
+// syntax: `symbol.prop` or `symbol[key]`.
+//
+// In ECMAScript spec jargon, this creates a Reference whose base value is a
+// primitive Symbol value.
+
+var symbols = [
+ Symbol(),
+ Symbol("ponies"),
+ Symbol.for("sym"),
+ Symbol.iterator
+];
+
+// Test accessor property, used below.
+var gets, sets;
+Object.defineProperty(Symbol.prototype, "prop", {
+ get: function () {
+ "use strict";
+ gets++;
+ assertEq(typeof this, "symbol");
+ assertEq(this, sym);
+ return "got";
+ },
+ set: function (v) {
+ "use strict";
+ sets++;
+ assertEq(typeof this, "symbol");
+ assertEq(this, sym);
+ assertEq(v, "newvalue");
+ }
+});
+
+for (var sym of symbols) {
+ assertEq(sym.constructor, Symbol);
+
+ // method on Object.prototype
+ assertEq(sym.hasOwnProperty("constructor"), false);
+ assertEq(sym.toLocaleString(), sym.toString()); // once .toString() exists
+
+ // custom method monkeypatched onto Symbol.prototype
+ Symbol.prototype.nonStrictMethod = function (arg) {
+ assertEq(arg, "ok");
+ assertEq(this instanceof Symbol, true);
+ assertEq(this.valueOf(), sym);
+ return 13;
+ };
+ assertEq(sym.nonStrictMethod("ok"), 13);
+
+ // the same, but strict mode
+ Symbol.prototype.strictMethod = function (arg) {
+ "use strict";
+ assertEq(arg, "ok2");
+ assertEq(this, sym);
+ return 14;
+ };
+ assertEq(sym.strictMethod("ok2"), 14);
+
+ // getter/setter on Symbol.prototype
+ gets = 0;
+ sets = 0;
+ var propname = "prop";
+
+ assertEq(sym.prop, "got");
+ assertEq(gets, 1);
+ assertEq(sym[propname], "got");
+ assertEq(gets, 2);
+
+ assertEq(sym.prop = "newvalue", "newvalue");
+ assertEq(sets, 1);
+ assertEq(sym[propname] = "newvalue", "newvalue");
+ assertEq(sets, 2);
+
+ // non-existent property
+ assertEq(sym.noSuchProp, undefined);
+ var noSuchPropName = "nonesuch";
+ assertEq(sym[noSuchPropName], undefined);
+
+ // non-existent method
+ assertThrowsInstanceOf(() => sym.noSuchProp(), TypeError);
+ assertThrowsInstanceOf(() => sym[noSuchPropName](), TypeError);
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(0, 0);
diff --git a/js/src/tests/ecma_6/Symbol/browser.js b/js/src/tests/ecma_6/Symbol/browser.js
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/js/src/tests/ecma_6/Symbol/browser.js
diff --git a/js/src/tests/ecma_6/Symbol/comparisons.js b/js/src/tests/ecma_6/Symbol/comparisons.js
new file mode 100644
index 000000000..d2105c8a1
--- /dev/null
+++ b/js/src/tests/ecma_6/Symbol/comparisons.js
@@ -0,0 +1,34 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/ */
+
+var symbols = [
+ Symbol(),
+ Symbol("0"),
+ Symbol.for("snowman"),
+ Symbol.iterator
+];
+
+var values = [
+ undefined, null, 0, 3.14, -0, NaN, "", "alphabet", Symbol("0"),
+ {}, []
+];
+
+for (var comparator of ["==", "!=", "===", "!=="]) {
+ var f = Function("a, b", "return a " + comparator + " b;");
+ var expected = (comparator[0] == '!');
+ for (var a of symbols) {
+ for (var b of values)
+ assertEq(f(a, b), expected);
+ }
+}
+
+for (var comparator of ["<", "<=", ">", ">="]) {
+ var f = Function("a, b", "return a " + comparator + " b;");
+ for (var a of symbols) {
+ for (var b of values)
+ assertThrowsInstanceOf(() => f(a, b), TypeError);
+ }
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(0, 0);
diff --git a/js/src/tests/ecma_6/Symbol/constructor.js b/js/src/tests/ecma_6/Symbol/constructor.js
new file mode 100644
index 000000000..5143b02a9
--- /dev/null
+++ b/js/src/tests/ecma_6/Symbol/constructor.js
@@ -0,0 +1,35 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/ */
+
+// Symbol(symbol) throws a TypeError.
+var sym = Symbol();
+assertThrowsInstanceOf(() => Symbol(sym), TypeError);
+
+// Symbol(undefined) is equivalent to Symbol().
+assertEq(Symbol(undefined).toString(), "Symbol()");
+
+// Otherwise, Symbol(v) means Symbol(ToString(v)).
+assertEq(Symbol(7).toString(), "Symbol(7)");
+assertEq(Symbol(true).toString(), "Symbol(true)");
+assertEq(Symbol(null).toString(), "Symbol(null)");
+assertEq(Symbol([1, 2]).toString(), "Symbol(1,2)");
+var symobj = Object(sym);
+assertThrowsInstanceOf(() => Symbol(symobj), TypeError);
+
+var hits = 0;
+var obj = {
+ toString: function () {
+ hits++;
+ return "ponies";
+ }
+};
+assertEq(Symbol(obj).toString(), "Symbol(ponies)");
+assertEq(hits, 1);
+
+assertEq(Object.getPrototypeOf(Symbol.prototype), Object.prototype);
+
+// Symbol.prototype is not itself a Symbol object.
+assertThrowsInstanceOf(() => Symbol.prototype.valueOf(), TypeError);
+
+if (typeof reportCompare === "function")
+ reportCompare(0, 0);
diff --git a/js/src/tests/ecma_6/Symbol/conversions.js b/js/src/tests/ecma_6/Symbol/conversions.js
new file mode 100644
index 000000000..e6265f09c
--- /dev/null
+++ b/js/src/tests/ecma_6/Symbol/conversions.js
@@ -0,0 +1,89 @@
+// Section numbers cite ES6 rev 24 (2014 April 27).
+
+var symbols = [
+ Symbol(),
+ Symbol("one"),
+ Symbol.for("two"),
+ Symbol.iterator
+];
+
+function testSymbolConversions(sym) {
+ // 7.1.2 ToBoolean
+ assertEq(Boolean(sym), true);
+ assertEq(!sym, false);
+ assertEq(sym || 13, sym);
+ assertEq(sym && 13, 13);
+
+ // 7.1.3 ToNumber
+ assertThrowsInstanceOf(() => +sym, TypeError);
+ assertThrowsInstanceOf(() => sym | 0, TypeError);
+
+ // 7.1.12 ToString
+ assertThrowsInstanceOf(() => "" + sym, TypeError);
+ assertThrowsInstanceOf(() => sym + "", TypeError);
+ assertThrowsInstanceOf(() => "" + [1, 2, sym], TypeError);
+ assertThrowsInstanceOf(() => ["simple", "thimble", sym].join(), TypeError);
+
+ // 21.1.1.1 String()
+ assertEq(String(sym), sym.toString());
+
+ // 21.1.1.2 new String()
+ assertThrowsInstanceOf(() => new String(sym), TypeError);
+
+ // 7.1.13 ToObject
+ var obj = Object(sym);
+ assertEq(typeof obj, "object");
+ assertEq(Object.prototype.toString.call(obj), "[object Symbol]");
+ assertEq(Object.getPrototypeOf(obj), Symbol.prototype);
+ assertEq(Object.getOwnPropertyNames(obj).length, 0);
+ assertEq(Object(sym) === Object(sym), false); // new object each time
+ var f = function () { return this; };
+ assertEq(f.call(sym) === f.call(sym), false); // new object each time
+}
+
+
+for (var sym of symbols) {
+ testSymbolConversions(sym);
+
+ // 7.1.1 ToPrimitive
+ var symobj = Object(sym);
+ assertThrowsInstanceOf(() => Number(symobj), TypeError);
+ assertThrowsInstanceOf(() => String(symobj), TypeError);
+ assertThrowsInstanceOf(() => symobj < 0, TypeError);
+ assertThrowsInstanceOf(() => 0 < symobj, TypeError);
+ assertThrowsInstanceOf(() => symobj + 1, TypeError);
+ assertThrowsInstanceOf(() => "" + symobj, TypeError);
+ assertEq(sym == symobj, true);
+ assertEq(sym === symobj, false);
+ assertEq(symobj == 0, false);
+ assertEq(0 != symobj, true);
+
+ // 7.1.12 ToString
+ assertThrowsInstanceOf(() => String(Object(sym)), TypeError);
+}
+
+// Deleting Symbol.prototype[@@toPrimitive] does not change the behavior of
+// conversions from a symbol to other types.
+delete Symbol.prototype[Symbol.toPrimitive];
+assertEq(Symbol.toPrimitive in Symbol.prototype, false);
+testSymbolConversions(symbols[0]);
+
+// It does change the behavior of ToPrimitive on Symbol objects, though.
+// It causes the default algorithm (OrdinaryToPrimitive) to be used.
+var VALUEOF_CALLED = 117.25;
+Symbol.prototype.valueOf = function () { return VALUEOF_CALLED; };
+Symbol.prototype.toString = function () { return "toString called"; };
+for (var sym of symbols) {
+ var symobj = Object(sym);
+ assertEq(Number(symobj), VALUEOF_CALLED);
+ assertEq(String(symobj), "toString called");
+ assertEq(symobj < 0, VALUEOF_CALLED < 0);
+ assertEq(0 < symobj, 0 < VALUEOF_CALLED);
+ assertEq(symobj + 1, VALUEOF_CALLED + 1);
+ assertEq("" + symobj, "" + VALUEOF_CALLED);
+ assertEq(symobj == 0, false);
+ assertEq(0 != symobj, true);
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(0, 0);
diff --git a/js/src/tests/ecma_6/Symbol/enumeration-order.js b/js/src/tests/ecma_6/Symbol/enumeration-order.js
new file mode 100644
index 000000000..8bcd1f02f
--- /dev/null
+++ b/js/src/tests/ecma_6/Symbol/enumeration-order.js
@@ -0,0 +1,40 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/ */
+
+// Symbols follow all other property keys in the result list.
+var log;
+function LoggingProxy() {
+ return new Proxy({}, {
+ defineProperty: (t, key, desc) => {
+ log.push(key);
+ return true;
+ }
+ });
+}
+
+var keys = [
+ "before",
+ Symbol(),
+ "during",
+ Symbol.for("during"),
+ Symbol.iterator,
+ "after"
+];
+var descs = {};
+for (var k of keys)
+ descs[k] = {configurable: true, value: 0};
+
+function test(descsObj) {
+ log = [];
+ Object.defineProperties(LoggingProxy(), descs);
+ assertEq(log.length, keys.length);
+ assertDeepEq(log.map(k => typeof k), ["string", "string", "string", "symbol", "symbol", "symbol"]);
+ for (var key of keys)
+ assertEq(log.indexOf(key) !== -1, true);
+}
+
+test(descs);
+test(new Proxy(descs, {}));
+
+if (typeof reportCompare === "function")
+ reportCompare(0, 0);
diff --git a/js/src/tests/ecma_6/Symbol/enumeration.js b/js/src/tests/ecma_6/Symbol/enumeration.js
new file mode 100644
index 000000000..e7ca426e6
--- /dev/null
+++ b/js/src/tests/ecma_6/Symbol/enumeration.js
@@ -0,0 +1,52 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/ */
+
+// for-in loops skip properties with symbol keys, even enumerable properties.
+var obj = {};
+obj[Symbol.for("moon")] = "sun";
+obj[Symbol("asleep")] = "awake";
+obj[Symbol.iterator] = "List";
+for (var x in obj)
+ throw "FAIL: " + uneval(x);
+
+// This includes inherited properties.
+var obj2 = Object.create(obj);
+for (var x in obj2)
+ throw "FAIL: " + uneval(x);
+
+// The same goes for proxies.
+var p = new Proxy(obj, {});
+for (var x in p)
+ throw "FAIL: " + uneval(x);
+var p2 = new Proxy(obj2, {});
+for (var x in p2)
+ throw "FAIL: " + uneval(x);
+
+// Object.keys() and .getOwnPropertyNames() also skip symbols.
+assertEq(Object.keys(obj).length, 0);
+assertEq(Object.keys(p).length, 0);
+assertEq(Object.keys(obj2).length, 0);
+assertEq(Object.keys(p2).length, 0);
+assertEq(Object.getOwnPropertyNames(obj).length, 0);
+assertEq(Object.getOwnPropertyNames(p).length, 0);
+assertEq(Object.getOwnPropertyNames(obj2).length, 0);
+assertEq(Object.getOwnPropertyNames(p2).length, 0);
+
+// Test interaction of Object.keys(), proxies, and symbol property keys.
+var log = [];
+var h = {
+ ownKeys: (t) => {
+ log.push("ownKeys");
+ return ["a", "0", Symbol.for("moon"), Symbol("asleep"), Symbol.iterator];
+ },
+ getOwnPropertyDescriptor: (t, key) => {
+ log.push("gopd", key);
+ return {configurable: true, enumerable: true, value: 0, writable: true};
+ }
+};
+p = new Proxy({}, h);
+assertDeepEq(Object.keys(p), ["a", "0"]);
+assertDeepEq(log, ["ownKeys", "gopd", "a", "gopd", "0"]);
+
+if (typeof reportCompare === "function")
+ reportCompare(0, 0);
diff --git a/js/src/tests/ecma_6/Symbol/equality.js b/js/src/tests/ecma_6/Symbol/equality.js
new file mode 100644
index 000000000..eaa091ba4
--- /dev/null
+++ b/js/src/tests/ecma_6/Symbol/equality.js
@@ -0,0 +1,30 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/ */
+
+// Symbol.for returns the same symbol whenever the same argument is passed.
+assertEq(Symbol.for("q") === Symbol.for("q"), true);
+
+// Several distinct Symbol values.
+var symbols = [
+ Symbol(),
+ Symbol("Symbol.iterator"),
+ Symbol("Symbol.iterator"), // distinct new symbol with the same description
+ Symbol.for("Symbol.iterator"),
+ Symbol.iterator
+];
+
+// Distinct symbols are never equal to each other, even if they have the same
+// description.
+for (var i = 0; i < symbols.length; i++) {
+ for (var j = i; j < symbols.length; j++) {
+ var expected = (i === j);
+ assertEq(symbols[i] == symbols[j], expected);
+ assertEq(symbols[i] != symbols[j], !expected);
+ assertEq(symbols[i] === symbols[j], expected);
+ assertEq(symbols[i] !== symbols[j], !expected);
+ assertEq(Object.is(symbols[i], symbols[j]), expected);
+ }
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(0, 0);
diff --git a/js/src/tests/ecma_6/Symbol/errors.js b/js/src/tests/ecma_6/Symbol/errors.js
new file mode 100644
index 000000000..d6eb37abc
--- /dev/null
+++ b/js/src/tests/ecma_6/Symbol/errors.js
@@ -0,0 +1,17 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/ */
+
+// Section numbers cite ES6 rev 24 (2014 April 27).
+
+var sym = Symbol();
+
+// 7.2.2 IsCallable
+assertThrowsInstanceOf(() => sym(), TypeError);
+assertThrowsInstanceOf(() => Function.prototype.call.call(sym), TypeError);
+
+// 7.2.5 IsConstructor
+assertThrowsInstanceOf(() => new sym(), TypeError);
+assertThrowsInstanceOf(() => new Symbol(), TypeError);
+
+if (typeof reportCompare === "function")
+ reportCompare(0, 0);
diff --git a/js/src/tests/ecma_6/Symbol/for-in-order.js b/js/src/tests/ecma_6/Symbol/for-in-order.js
new file mode 100644
index 000000000..7d1f23430
--- /dev/null
+++ b/js/src/tests/ecma_6/Symbol/for-in-order.js
@@ -0,0 +1,33 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/ */
+
+// ES6 does not specify enumeration order, but implementations mostly retain
+// property insertion order -- and must, for web compatibility. This test checks
+// that symbol-keyed properties do not interfere with that order.
+
+var obj = {};
+obj[Symbol("moon")] = 0;
+obj.x = 1;
+obj[Symbol.for("y")] = 2
+obj.y = 3;
+obj[Symbol.iterator] = function* () { yield 4; };
+obj.z = 5;
+Object.prototype[Symbol.for("comet")] = 6;
+
+var keys = [];
+for (var k in obj)
+ keys.push(k);
+assertDeepEq(keys, ["x", "y", "z"]);
+assertDeepEq(Object.keys(obj), ["x", "y", "z"]);
+
+// Test with more properties.
+for (var i = 0; i < 1000; i++)
+ obj[Symbol(i)] = i;
+obj.w = 1000;
+keys = []
+for (var k in obj)
+ keys.push(k);
+assertDeepEq(keys, ["x", "y", "z", "w"]);
+
+if (typeof reportCompare === "function")
+ reportCompare(0, 0);
diff --git a/js/src/tests/ecma_6/Symbol/for.js b/js/src/tests/ecma_6/Symbol/for.js
new file mode 100644
index 000000000..43e285511
--- /dev/null
+++ b/js/src/tests/ecma_6/Symbol/for.js
@@ -0,0 +1,31 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/ */
+
+// Symbol.for called twice with the same argument returns the same symbol.
+assertEq(Symbol.for("ponies"), Symbol.for("ponies"));
+
+// Called twice with equal strings: still the same result.
+var one = Array(64+1).join("x");
+var two = Array(8+1).join(Array(8+1).join("x"));
+assertEq(Symbol.for(one), Symbol.for(two));
+
+// Symbols created by calling Symbol() are not in the symbol registry.
+var sym = Symbol("123");
+assertEq(Symbol.for("123") !== sym, true);
+
+// Empty string is fine.
+assertEq(typeof Symbol.for(""), "symbol");
+
+// Primitive arguments.
+assertEq(Symbol.for(3), Symbol.for("3"));
+assertEq(Symbol.for(null), Symbol.for("null"));
+assertEq(Symbol.for(undefined), Symbol.for("undefined"));
+assertEq(Symbol.for(), Symbol.for("undefined"));
+
+// Symbol.for ignores the 'this' value.
+var foo = Symbol.for("foo")
+assertEq(Symbol.for.call(String, "foo"), foo);
+assertEq(Symbol.for.call(3.14, "foo"), foo);
+
+if (typeof reportCompare === "function")
+ reportCompare(0, 0);
diff --git a/js/src/tests/ecma_6/Symbol/json-stringify-keys.js b/js/src/tests/ecma_6/Symbol/json-stringify-keys.js
new file mode 100644
index 000000000..3818cbb33
--- /dev/null
+++ b/js/src/tests/ecma_6/Symbol/json-stringify-keys.js
@@ -0,0 +1,19 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/ */
+
+// JSON.stringify ignores symbol-keyed properties, even enumerable ones.
+
+var obj = {a: 1};
+obj[Symbol.for("ponies")] = {toJSON: function () { throw "fit"; }};
+obj[Symbol.iterator] = {toJSON: function () { throw "fit"; }};
+assertEq(JSON.stringify(obj), '{"a":1}');
+
+var replacer = function (k, v) {
+ if (typeof k === "symbol")
+ throw "fit";
+ return v;
+};
+assertEq(JSON.stringify(obj, replacer), '{"a":1}');
+
+if (typeof reportCompare === 'function')
+ reportCompare(0, 0, 'ok');
diff --git a/js/src/tests/ecma_6/Symbol/json-stringify-values.js b/js/src/tests/ecma_6/Symbol/json-stringify-values.js
new file mode 100644
index 000000000..0fe32eee5
--- /dev/null
+++ b/js/src/tests/ecma_6/Symbol/json-stringify-values.js
@@ -0,0 +1,33 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/ */
+
+// To JSON.stringify, symbols are the same as undefined.
+
+var symbols = [
+ Symbol(),
+ Symbol.for("ponies"),
+ Symbol.iterator
+];
+
+for (var sym of symbols) {
+ assertEq(JSON.stringify(sym), undefined);
+ assertEq(JSON.stringify([sym]), "[null]");
+
+ // JSON.stringify skips symbol-valued properties!
+ assertEq(JSON.stringify({x: sym}), '{}');
+
+ // However such properties are passed to the replacerFunction if any.
+ var replacer = function (key, val) {
+ assertEq(typeof this, "object");
+ if (typeof val === "symbol") {
+ assertEq(val, sym);
+ return "ding";
+ }
+ return val;
+ };
+ assertEq(JSON.stringify(sym, replacer), '"ding"');
+ assertEq(JSON.stringify({x: sym}, replacer), '{"x":"ding"}');
+}
+
+if (typeof reportCompare === 'function')
+ reportCompare(0, 0, 'ok');
diff --git a/js/src/tests/ecma_6/Symbol/keyFor.js b/js/src/tests/ecma_6/Symbol/keyFor.js
new file mode 100644
index 000000000..868c3bda7
--- /dev/null
+++ b/js/src/tests/ecma_6/Symbol/keyFor.js
@@ -0,0 +1,15 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/ */
+
+assertEq(Symbol.keyFor(Symbol.for("moon")), "moon");
+assertEq(Symbol.keyFor(Symbol.for("")), "");
+assertEq(Symbol.keyFor(Symbol("moon")), undefined);
+assertEq(Symbol.keyFor(Symbol.iterator), undefined);
+
+assertThrowsInstanceOf(() => Symbol.keyFor(), TypeError);
+assertThrowsInstanceOf(() => Symbol.keyFor(Object(Symbol("moon"))), TypeError);
+
+assertEq(Symbol.keyFor.length, 1);
+
+if (typeof reportCompare === "function")
+ reportCompare(0, 0);
diff --git a/js/src/tests/ecma_6/Symbol/property-accessor.js b/js/src/tests/ecma_6/Symbol/property-accessor.js
new file mode 100644
index 000000000..7a2c149a1
--- /dev/null
+++ b/js/src/tests/ecma_6/Symbol/property-accessor.js
@@ -0,0 +1,39 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/ */
+
+var obj = {};
+var sym = Symbol();
+
+var gets = 0;
+var sets = [];
+Object.defineProperty(obj, sym, {
+ get: function () { return ++gets; },
+ set: function (v) { sets.push(v); }
+});
+
+// getter
+for (var i = 1; i < 9; i++)
+ assertEq(obj[sym], i);
+
+// setter
+var expected = [];
+for (var i = 0; i < 9; i++) {
+ assertEq(obj[sym] = i, i);
+ expected.push(i);
+}
+assertDeepEq(sets, expected);
+
+// increment operator
+gets = 0;
+sets = [];
+assertEq(obj[sym]++, 1);
+assertDeepEq(sets, [2]);
+
+// assignment
+gets = 0;
+sets = [];
+assertEq(obj[sym] *= 12, 12);
+assertDeepEq(sets, [12]);
+
+if (typeof reportCompare === "function")
+ reportCompare(0, 0);
diff --git a/js/src/tests/ecma_6/Symbol/property-basics.js b/js/src/tests/ecma_6/Symbol/property-basics.js
new file mode 100644
index 000000000..63bcb3867
--- /dev/null
+++ b/js/src/tests/ecma_6/Symbol/property-basics.js
@@ -0,0 +1,44 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/ */
+
+var symbols = [
+ Symbol(),
+ Symbol("one"),
+ Symbol.for("two"),
+ Symbol.iterator,
+ Object(Symbol())
+];
+
+for (var sym of symbols) {
+ var obj = {};
+
+ // access a nonexistent property
+ assertEq(sym in obj, false);
+ assertEq(obj.hasOwnProperty(sym), false);
+ assertEq(obj[sym], undefined);
+ assertEq(typeof obj[sym], "undefined");
+ assertEq(Object.getOwnPropertyDescriptor(obj, sym), undefined);
+
+ // assign, then try accessing again
+ obj[sym] = "ok";
+ assertEq(sym in obj, true);
+ assertEq(obj.hasOwnProperty(sym), true);
+ assertEq(obj[sym], "ok");
+ assertDeepEq(Object.getOwnPropertyDescriptor(obj, sym), {
+ value: "ok",
+ writable: true,
+ enumerable: true,
+ configurable: true
+ });
+
+ // assign again, observe value is overwritten
+ obj[sym] = 12;
+ assertEq(obj[sym], 12);
+
+ // increment
+ assertEq(obj[sym]++, 12);
+ assertEq(obj[sym], 13);
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(0, 0);
diff --git a/js/src/tests/ecma_6/Symbol/property-inheritance.js b/js/src/tests/ecma_6/Symbol/property-inheritance.js
new file mode 100644
index 000000000..2fe618968
--- /dev/null
+++ b/js/src/tests/ecma_6/Symbol/property-inheritance.js
@@ -0,0 +1,50 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/ */
+
+var sym = Symbol.for("hello");
+function F() {}
+var f = new F();
+
+// inherited data property
+F.prototype[sym] = "world";
+assertEq(sym in f, true);
+assertEq(f.hasOwnProperty(sym), false);
+assertEq(f[sym], "world");
+
+// shadowing assignment
+f[sym] = "kitty";
+assertEq(f[sym], "kitty");
+assertEq(F.prototype[sym], "world");
+
+// deletion, revealing previously shadowed property
+assertEq(delete f[sym], true);
+assertEq(f.hasOwnProperty(sym), false);
+assertEq(f[sym], "world");
+
+// inherited accessor property
+var value = undefined;
+Object.defineProperty(F.prototype, sym, {
+ configurable: true,
+ get: function () { return 23; },
+ set: function (v) { value = v; }
+});
+assertEq(sym in f, true);
+assertEq(f.hasOwnProperty(sym), false);
+assertEq(f[sym], 23);
+f[sym] = "gravity";
+assertEq(value, "gravity");
+
+// inherited accessor property with no setter
+Object.defineProperty(F.prototype, sym, {
+ set: undefined
+});
+assertThrowsInstanceOf(function () { "use strict"; f[sym] = 0; }, TypeError);
+
+// deeply inherited accessor property
+var g = Object.create(f);
+for (var i = 0; i < 100; i++)
+ g = Object.create(g);
+assertEq(g[sym], 23);
+
+if (typeof reportCompare === "function")
+ reportCompare(0, 0);
diff --git a/js/src/tests/ecma_6/Symbol/property-nonwritable.js b/js/src/tests/ecma_6/Symbol/property-nonwritable.js
new file mode 100644
index 000000000..3e58383c7
--- /dev/null
+++ b/js/src/tests/ecma_6/Symbol/property-nonwritable.js
@@ -0,0 +1,31 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/ */
+
+var sym = Symbol.for("moon");
+function checkNotWritable(obj) {
+ // In sloppy mode, assigning to a nonwritable property silently fails.
+ obj[sym] = "portals";
+ assertEq(obj[sym], "cheese");
+
+ // In strict mode code, it throws.
+ assertThrowsInstanceOf(function () { "use strict"; obj[sym] = "robots"; }, TypeError);
+ assertEq(obj[sym], "cheese");
+}
+
+var x = {};
+Object.defineProperty(x, sym, {
+ configurable: true,
+ enumerable: true,
+ value: "cheese",
+ writable: false
+});
+
+checkNotWritable(x);
+
+// Assignment can't shadow inherited nonwritable properties either.
+var y = Object.create(x);
+checkNotWritable(y);
+checkNotWritable(Object.create(y));
+
+if (typeof reportCompare === "function")
+ reportCompare(0, 0);
diff --git a/js/src/tests/ecma_6/Symbol/property-reflection.js b/js/src/tests/ecma_6/Symbol/property-reflection.js
new file mode 100644
index 000000000..5bdecf663
--- /dev/null
+++ b/js/src/tests/ecma_6/Symbol/property-reflection.js
@@ -0,0 +1,136 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/ */
+
+// Basic tests for standard Object APIs interacting with symbols.
+
+// Object.defineProperty
+function F() {}
+var f = new F;
+Object.defineProperty(f, Symbol.for("name"), {
+ configurable: true,
+ value: "eff"
+});
+assertEq("name" in f, false);
+assertEq("Symbol(name)" in f, false);
+assertEq(Symbol.for("name") in f, true);
+assertEq(f[Symbol.for("name")], "eff");
+
+// Object.defineProperties
+function D() {}
+var descs = new D;
+var s1 = Symbol("s1");
+var hits = 0;
+descs[s1] = {
+ get: () => hits++,
+ set: undefined,
+ enumerable: true,
+ configurable: true
+};
+var s2 = Symbol("s2");
+descs[s2] = {
+ value: {},
+ writable: true,
+ enumerable: false,
+ configurable: true
+};
+var s3 = Symbol("s3");
+D.prototype[s3] = {value: "FAIL"};
+assertEq(Object.defineProperties(f, descs), f);
+assertEq(s1 in f, true);
+assertEq(f[s1], 0);
+assertEq(hits, 1);
+assertEq(s2 in f, true);
+assertEq(f[s2], descs[s2].value);
+assertEq(s3 in f, false);
+
+// Object.create
+var n = Object.create({}, descs);
+assertEq(s1 in n, true);
+assertEq(n[s1], 1);
+assertEq(hits, 2);
+assertEq(s2 in n, true);
+assertEq(n[s2], descs[s2].value);
+assertEq(s3 in n, false);
+
+// Object.getOwnPropertyDescriptor
+var desc = Object.getOwnPropertyDescriptor(n, s1);
+assertDeepEq(desc, descs[s1]);
+assertEq(desc.get, descs[s1].get);
+desc = Object.getOwnPropertyDescriptor(n, s2);
+assertDeepEq(desc, descs[s2]);
+assertEq(desc.value, descs[s2].value);
+
+// Object.prototype.hasOwnProperty
+assertEq(descs.hasOwnProperty(s1), true);
+assertEq(descs.hasOwnProperty(s2), true);
+assertEq(descs.hasOwnProperty(s3), false);
+assertEq([].hasOwnProperty(Symbol.iterator), false);
+assertEq(Array.prototype.hasOwnProperty(Symbol.iterator), true);
+
+// Object.prototype.propertyIsEnumerable
+assertEq(n.propertyIsEnumerable(s1), true);
+assertEq(n.propertyIsEnumerable(s2), false);
+assertEq(n.propertyIsEnumerable(s3), false); // no such property
+assertEq(D.prototype.propertyIsEnumerable(s3), true);
+assertEq(descs.propertyIsEnumerable(s3), false); // inherited properties are not considered
+
+// Object.preventExtensions
+var obj = {};
+obj[s1] = 1;
+assertEq(Object.preventExtensions(obj), obj);
+assertThrowsInstanceOf(function () { "use strict"; obj[s2] = 2; }, TypeError);
+obj[s2] = 2; // still no effect
+assertEq(s2 in obj, false);
+
+// Object.isSealed, Object.isFrozen
+assertEq(Object.isSealed(obj), false);
+assertEq(Object.isFrozen(obj), false);
+assertEq(delete obj[s1], true);
+assertEq(Object.isSealed(obj), true);
+assertEq(Object.isFrozen(obj), true);
+
+obj = {};
+obj[s1] = 1;
+Object.preventExtensions(obj);
+Object.defineProperty(obj, s1, {configurable: false}); // still writable
+assertEq(Object.isSealed(obj), true);
+assertEq(Object.isFrozen(obj), false);
+obj[s1] = 2;
+assertEq(obj[s1], 2);
+Object.defineProperty(obj, s1, {writable: false});
+assertEq(Object.isFrozen(obj), true);
+
+// Object.seal, Object.freeze
+var obj = {};
+obj[s1] = 1;
+Object.seal(obj);
+desc = Object.getOwnPropertyDescriptor(obj, s1);
+assertEq(desc.configurable, false);
+assertEq(desc.writable, true);
+Object.freeze(obj);
+assertEq(Object.getOwnPropertyDescriptor(obj, s1).writable, false);
+
+// Object.setPrototypeOf purges caches for symbol-keyed properties.
+var proto = {};
+proto[s1] = 1;
+Object.defineProperty(proto, s2, {
+ get: () => 2,
+ set: v => undefined
+});
+var obj = Object.create(proto);
+var last1, last2;
+var N = 9;
+for (var i = 0; i < N; i++) {
+ last1 = obj[s1];
+ last2 = obj[s2];
+ obj[s2] = "marker";
+ if (i === N - 2)
+ Object.setPrototypeOf(obj, {});
+}
+assertEq(last1, undefined);
+assertEq(last2, undefined);
+assertEq(obj.hasOwnProperty(s2), true);
+assertEq(obj[s2], "marker");
+
+if (typeof reportCompare === "function")
+ reportCompare(0, 0);
diff --git a/js/src/tests/ecma_6/Symbol/realms.js b/js/src/tests/ecma_6/Symbol/realms.js
new file mode 100644
index 000000000..98a1284ee
--- /dev/null
+++ b/js/src/tests/ecma_6/Symbol/realms.js
@@ -0,0 +1,36 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/ */
+
+// Symbols can be shared across realms.
+
+if (typeof Reflect !== "undefined" && typeof Reflect.Realm === "function") {
+ throw new Error("Congratulations on implementing Reflect.Realm! " +
+ "Please update this test to use it.");
+}
+if (typeof newGlobal === "function") {
+ var g = newGlobal();
+ var gj = g.eval("jones = Symbol('jones')");
+ assertEq(typeof gj, "symbol");
+ assertEq(g.jones, g.jones);
+ assertEq(gj, g.jones);
+ assertEq(gj !== Symbol("jones"), true);
+
+ // A symbol can be round-tripped to another realm and back;
+ // the result is the original symbol.
+ var smith = Symbol("smith");
+ g.smith = smith; // put smith into the realm
+ assertEq(g.smith, smith); // pull it back out
+
+ // Spot-check that non-generic methods can be applied to symbols and Symbol
+ // objects from other realms.
+ assertEq(Symbol.prototype.toString.call(gj), "Symbol(jones)");
+ assertEq(Symbol.prototype.toString.call(g.eval("Object(Symbol('brown'))")),
+ "Symbol(brown)");
+
+ // Symbol.for functions share a symbol registry across all realms.
+ assertEq(g.Symbol.for("ponies"), Symbol.for("ponies"));
+ assertEq(g.eval("Symbol.for('rainbows')"), Symbol.for("rainbows"));
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(0, 0);
diff --git a/js/src/tests/ecma_6/Symbol/shell.js b/js/src/tests/ecma_6/Symbol/shell.js
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/js/src/tests/ecma_6/Symbol/shell.js
diff --git a/js/src/tests/ecma_6/Symbol/species.js b/js/src/tests/ecma_6/Symbol/species.js
new file mode 100644
index 000000000..ba45066e1
--- /dev/null
+++ b/js/src/tests/ecma_6/Symbol/species.js
@@ -0,0 +1,30 @@
+var BUGNUMBER = 1131043;
+var summary = "Implement @@species getter for builtin types";
+
+print(BUGNUMBER + ": " + summary);
+
+var TypedArray = Object.getPrototypeOf(Int8Array);
+
+for (var C of [Array, Map, Set, RegExp,
+ Int8Array, Uint8Array, Uint8ClampedArray,
+ Int16Array, Uint16Array, Int32Array, Uint32Array,
+ Float32Array, Float64Array,
+ ArrayBuffer]) {
+ assertEq(C[Symbol.species], C);
+}
+
+for (C of [Array, Map, Set, RegExp,
+ TypedArray,
+ ArrayBuffer]) {
+ var desc = Object.getOwnPropertyDescriptor(C, Symbol.species);
+ assertDeepEq(Object.keys(desc).sort(), ["configurable", "enumerable", "get", "set"]);
+ assertEq(desc.set, undefined);
+ assertEq(desc.enumerable, false);
+ assertEq(desc.configurable, true);
+ assertEq(desc.get.apply(null), null);
+ assertEq(desc.get.apply(undefined), undefined);
+ assertEq(desc.get.apply(42), 42);
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(0, 0);
diff --git a/js/src/tests/ecma_6/Symbol/surfaces.js b/js/src/tests/ecma_6/Symbol/surfaces.js
new file mode 100644
index 000000000..7b3ef9f9b
--- /dev/null
+++ b/js/src/tests/ecma_6/Symbol/surfaces.js
@@ -0,0 +1,34 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/ */
+
+// Test superficial properties of the Symbol constructor and prototype.
+
+var desc = Object.getOwnPropertyDescriptor(this, "Symbol");
+assertEq(desc.configurable, true);
+assertEq(desc.enumerable, false);
+assertEq(desc.writable, true);
+assertEq(typeof Symbol, "function");
+assertEq(Symbol.length, 0);
+
+desc = Object.getOwnPropertyDescriptor(Symbol, "prototype");
+assertEq(desc.configurable, false);
+assertEq(desc.enumerable, false);
+assertEq(desc.writable, false);
+
+assertEq(Symbol.prototype.constructor, Symbol);
+desc = Object.getOwnPropertyDescriptor(Symbol.prototype, "constructor");
+assertEq(desc.configurable, true);
+assertEq(desc.enumerable, false);
+assertEq(desc.writable, true);
+
+desc = Object.getOwnPropertyDescriptor(Symbol, "iterator");
+assertEq(desc.configurable, false);
+assertEq(desc.enumerable, false);
+assertEq(desc.writable, false);
+
+assertEq(Symbol.for.length, 1);
+assertEq(Symbol.prototype.toString.length, 0);
+assertEq(Symbol.prototype.valueOf.length, 0);
+
+if (typeof reportCompare === "function")
+ reportCompare(0, 0);
diff --git a/js/src/tests/ecma_6/Symbol/toPrimitive.js b/js/src/tests/ecma_6/Symbol/toPrimitive.js
new file mode 100644
index 000000000..06262f99c
--- /dev/null
+++ b/js/src/tests/ecma_6/Symbol/toPrimitive.js
@@ -0,0 +1,39 @@
+// ES6 19.4.3.4 Symbol.prototype[@@toPrimitive](hint)
+
+// This method gets the primitive symbol from a Symbol wrapper object.
+var sym = Symbol.for("truth")
+var obj = Object(sym);
+assertEq(obj[Symbol.toPrimitive]("default"), sym);
+
+// The hint argument is ignored.
+assertEq(obj[Symbol.toPrimitive]("number"), sym);
+assertEq(obj[Symbol.toPrimitive]("string"), sym);
+assertEq(obj[Symbol.toPrimitive](), sym);
+assertEq(obj[Symbol.toPrimitive](Math.atan2), sym);
+
+// The this value can also be a primitive symbol.
+assertEq(sym[Symbol.toPrimitive](), sym);
+
+// Or a wrapper to a Symbol object in another compartment.
+var obj2 = newGlobal().Object(sym);
+assertEq(obj2[Symbol.toPrimitive]("default"), sym);
+
+// Otherwise a TypeError is thrown.
+var symbolToPrimitive = Symbol.prototype[Symbol.toPrimitive];
+var nonSymbols = [
+ undefined, null, true, 13, NaN, "justice", {}, [sym],
+ symbolToPrimitive,
+ new Proxy(obj, {})
+];
+for (var value of nonSymbols) {
+ assertThrowsInstanceOf(() => symbolToPrimitive.call(value, "string"), TypeError);
+}
+
+// Surface features:
+assertEq(symbolToPrimitive.name, "[Symbol.toPrimitive]");
+var desc = Object.getOwnPropertyDescriptor(Symbol.prototype, Symbol.toPrimitive);
+assertEq(desc.configurable, true);
+assertEq(desc.enumerable, false);
+assertEq(desc.writable, false);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/ecma_6/Symbol/toString.js b/js/src/tests/ecma_6/Symbol/toString.js
new file mode 100644
index 000000000..b7bbda876
--- /dev/null
+++ b/js/src/tests/ecma_6/Symbol/toString.js
@@ -0,0 +1,27 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/ */
+
+var cases = [
+ {sym: Symbol(), str: "Symbol()"},
+ {sym: Symbol("ok"), str: "Symbol(ok)"},
+ {sym: Symbol("\0"), str: "Symbol(\0)"},
+ {sym: Symbol.iterator, str: "Symbol(Symbol.iterator)"},
+ {sym: Symbol.for("dummies"), str: "Symbol(dummies)"}
+];
+
+// Symbol.prototype.toString works on both primitive symbols and Symbol
+// objects.
+for (var test of cases) {
+ assertEq(test.sym.toString(), test.str);
+ assertEq(Object(test.sym).toString(), test.str);
+}
+
+// Any other value throws.
+var nonsymbols = [
+ undefined, null, "not-ok", new String("still-not-ok"), {}, []
+];
+for (var nonsym of nonsymbols)
+ assertThrowsInstanceOf(() => Symbol.prototype.toString.call(nonsym), TypeError);
+
+if (typeof reportCompare === "function")
+ reportCompare(0, 0);
diff --git a/js/src/tests/ecma_6/Symbol/toStringTag.js b/js/src/tests/ecma_6/Symbol/toStringTag.js
new file mode 100644
index 000000000..20aac2c42
--- /dev/null
+++ b/js/src/tests/ecma_6/Symbol/toStringTag.js
@@ -0,0 +1,155 @@
+/* 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);
diff --git a/js/src/tests/ecma_6/Symbol/typed-arrays.js b/js/src/tests/ecma_6/Symbol/typed-arrays.js
new file mode 100644
index 000000000..a07cf396b
--- /dev/null
+++ b/js/src/tests/ecma_6/Symbol/typed-arrays.js
@@ -0,0 +1,17 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/ */
+
+// Symbol-to-number type conversions involving typed arrays.
+
+for (var T of [Uint8Array, Uint8ClampedArray, Int16Array, Float32Array]) {
+ // Typed array constructors convert symbols using ToNumber(), which throws.
+ assertThrowsInstanceOf(() => new T([Symbol("a")]), TypeError);
+
+ // Assignment does the same.
+ var arr = new T([1]);
+ assertThrowsInstanceOf(() => { arr[0] = Symbol.iterator; }, TypeError);
+ assertEq(arr[0], 1);
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(0, 0);
diff --git a/js/src/tests/ecma_6/Symbol/typeof.js b/js/src/tests/ecma_6/Symbol/typeof.js
new file mode 100644
index 000000000..104ae66df
--- /dev/null
+++ b/js/src/tests/ecma_6/Symbol/typeof.js
@@ -0,0 +1,11 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/ */
+
+assertEq(typeof Symbol(), "symbol");
+assertEq(typeof Symbol("ponies"), "symbol");
+assertEq(typeof Symbol.for("ponies"), "symbol");
+
+assertEq(typeof Object(Symbol()), "object");
+
+if (typeof reportCompare === "function")
+ reportCompare(0, 0);
diff --git a/js/src/tests/ecma_6/Symbol/valueOf.js b/js/src/tests/ecma_6/Symbol/valueOf.js
new file mode 100644
index 000000000..a3823c3ff
--- /dev/null
+++ b/js/src/tests/ecma_6/Symbol/valueOf.js
@@ -0,0 +1,22 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/ */
+
+var symbols = [
+ Symbol(),
+ Symbol("ok"),
+ Symbol.for("dummies"),
+ Symbol.iterator
+];
+
+for (var sym of symbols) {
+ assertEq(sym.valueOf(), sym);
+ assertEq(Object(sym).valueOf(), sym);
+}
+
+// Any other value throws.
+var nonsymbols = [undefined, null, NaN, {}, Symbol.prototype];
+for (var nonsym of nonsymbols)
+ assertThrowsInstanceOf(() => Symbol.prototype.valueOf.call(nonsym), TypeError);
+
+if (typeof reportCompare === "function")
+ reportCompare(0, 0);
diff --git a/js/src/tests/ecma_6/Symbol/well-known.js b/js/src/tests/ecma_6/Symbol/well-known.js
new file mode 100644
index 000000000..8c5de1279
--- /dev/null
+++ b/js/src/tests/ecma_6/Symbol/well-known.js
@@ -0,0 +1,41 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/ */
+
+var names = [
+ "isConcatSpreadable",
+ "iterator",
+ "match",
+ "replace",
+ "search",
+ "species",
+ "hasInstance",
+ "split",
+ "toPrimitive",
+ "unscopables"
+];
+
+for (var name of names) {
+ // Well-known symbols exist.
+ assertEq(typeof Symbol[name], "symbol");
+
+ // They are never in the registry.
+ assertEq(Symbol[name] !== Symbol.for("Symbol." + name), true);
+
+ // They are shared across realms.
+ if (typeof Realm === 'function')
+ throw new Error("please update this test to use Realms");
+ if (typeof newGlobal === 'function') {
+ var g = newGlobal();
+ assertEq(Symbol[name], g.Symbol[name]);
+ }
+
+ // Descriptor is all false.
+ var desc = Object.getOwnPropertyDescriptor(Symbol, name);
+ assertEq(typeof desc.value, "symbol");
+ assertEq(desc.writable, false);
+ assertEq(desc.enumerable, false);
+ assertEq(desc.configurable, false);
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(0, 0);