| const assert = require('assert'); |
| |
| exports.test_has_instance = function(sym) { |
| class Array1 { |
| static [sym](instance) { |
| return Array.isArray(instance); |
| } |
| } |
| |
| assert.equal(typeof sym, "symbol"); |
| assert.ok([] instanceof Array1); |
| }; |
| |
| exports.test_is_concat_spreadable = function(sym) { |
| const alpha = ['a', 'b', 'c']; |
| const numeric = [1, 2, 3]; |
| let alphaNumeric = alpha.concat(numeric); |
| |
| assert.deepEqual(alphaNumeric, ["a", "b", "c", 1, 2, 3]); |
| |
| numeric[sym] = false; |
| alphaNumeric = alpha.concat(numeric); |
| |
| assert.deepEqual(alphaNumeric, ["a", "b", "c", numeric]); |
| }; |
| |
| exports.test_iterator = function(sym) { |
| const iterable1 = new Object(); |
| |
| iterable1[sym] = function* () { |
| yield 1; |
| yield 2; |
| yield 3; |
| }; |
| |
| assert.deepEqual([...iterable1], [1, 2, 3]); |
| }; |
| |
| exports.test_async_iterator = async function(sym) { |
| const iterable1 = new Object(); |
| |
| iterable1[sym] = function () { |
| let done = false; |
| |
| return { |
| next() { |
| if (done) { |
| return Promise.resolve({ |
| done: true, |
| value: 1 |
| }); |
| |
| } else { |
| done = true; |
| |
| return Promise.resolve({ |
| done: false, |
| value: 0 |
| }); |
| } |
| } |
| }; |
| }; |
| |
| const values = []; |
| |
| for await (let value of iterable1) { |
| values.push(value); |
| } |
| |
| assert.deepEqual(values, [0]); |
| }; |
| |
| exports.test_match = function(sym) { |
| const regexp1 = /foo/; |
| assert.throws(() => '/foo/'.startsWith(regexp1)); |
| |
| regexp1[sym] = false; |
| |
| assert.ok('/foo/'.startsWith(regexp1)); |
| |
| assert.equal('/baz/'.endsWith(regexp1), false); |
| }; |
| |
| exports.test_replace = function(sym) { |
| class Replace1 { |
| constructor(value) { |
| this.value = value; |
| } |
| [sym](string) { |
| return `s/${string}/${this.value}/g`; |
| } |
| } |
| |
| assert.equal('foo'.replace(new Replace1('bar')), 's/foo/bar/g'); |
| }; |
| |
| exports.test_search = function(sym) { |
| class Search1 { |
| constructor(value) { |
| this.value = value; |
| } |
| |
| [sym](string) { |
| return string.indexOf(this.value); |
| } |
| } |
| |
| assert.equal('foobar'.search(new Search1('bar')), 3); |
| }; |
| |
| exports.test_species = function(sym) { |
| class Array1 extends Array { |
| static get [sym]() { return Array; } |
| } |
| |
| const a = new Array1(1, 2, 3); |
| const mapped = a.map(x => x * x); |
| |
| assert.equal(mapped instanceof Array1, false); |
| |
| assert.ok(mapped instanceof Array); |
| }; |
| |
| exports.test_split = function(sym) { |
| class Split1 { |
| constructor(value) { |
| this.value = value; |
| } |
| |
| [sym](string) { |
| var index = string.indexOf(this.value); |
| return this.value + string.substr(0, index) + "/" |
| + string.substr(index + this.value.length); |
| } |
| } |
| |
| assert.equal('foobar'.split(new Split1('foo')), 'foo/bar'); |
| }; |
| |
| exports.test_to_primitive = function(sym) { |
| const object1 = { |
| [sym](hint) { |
| if (hint == 'number') { |
| return 42; |
| } |
| return null; |
| } |
| }; |
| |
| assert.equal(+object1, 42); |
| }; |
| |
| exports.test_to_string_tag = function(sym) { |
| class ValidatorClass { |
| get [sym]() { |
| return 'Validator'; |
| } |
| } |
| |
| assert.equal(Object.prototype.toString.call(new ValidatorClass()), '[object Validator]'); |
| }; |