diff --git a/harness/compareIterator.js b/harness/compareIterator.js new file mode 100644 index 00000000000..69b9246e1b7 --- /dev/null +++ b/harness/compareIterator.js @@ -0,0 +1,34 @@ +// Copyright (C) 2018 Peter Wong. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +description: Compare the values of an iterator with an array of expected values +---*/ + +// Example: +// +// function* numbers() { +// yield 1; +// yield 2; +// yield 3; +// } +// +// compareIterator(numbers(), [ +// v => assert.sameValue(v, 1), +// v => assert.sameValue(v, 2), +// v => assert.sameValue(v, 3), +// ]); +// +assert.compareIterator = function(iter, validators, message) { + message = message || ''; + + var i, result; + for (i = 0; i < validators.length; i++) { + result = iter.next(); + assert(!result.done, 'Expected ' + i + ' values(s). Instead iterator only produced ' + (i - 1) + ' value(s). ' + message); + validators[i](result.value); + } + + result = iter.next(); + assert(result.done, 'Expected only ' + i + ' values(s). Instead iterator produced more. ' + message); + assert.sameValue(result.value, undefined, 'Expected value of `undefined` when iterator completes. ' + message); +} diff --git a/harness/regExpUtils.js b/harness/regExpUtils.js index bdb956427ac..4dd7ddf13b0 100644 --- a/harness/regExpUtils.js +++ b/harness/regExpUtils.js @@ -37,3 +37,18 @@ function testPropertyEscapes(regex, string, expression) { } } } + +// Returns a function that will validate RegExp match result +// +// Example: +// +// var validate = matchValidator(['b'], 1, 'abc'); +// validate(/b/.exec('abc')); +// +function matchValidator(expectedEntries, expectedIndex, expectedInput) { + return function(match) { + assert.compareArray(match, expectedEntries, 'Match entries'); + assert.sameValue(match.index, expectedIndex, 'Match index'); + assert.sameValue(match.input, expectedInput, 'Match input'); + } +} diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/get-species-constructor-err.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/get-species-constructor-err.js deleted file mode 100644 index 64028836ee8..00000000000 --- a/test/built-ins/RegExp/prototype/Symbol.matchAll/get-species-constructor-err.js +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (C) 2015 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -description: > - Behavior when error is thrown during retrieval of `Symbol.species` property -info: | - 3. Let C be ? SpeciesConstructor(R, %RegExp%). -features: [Symbol.match, Symbol.matchAll, Symbol.species] ----*/ - -var obj = {}; -Object.defineProperty(obj, Symbol.species, { - get: function () { - throw new Test262Error(); - } -}); -obj[Symbol.match] = true; - -assert.throws(Test262Error, function() { - RegExp.prototype[Symbol.matchAll].call(obj); -}); diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/internal-regexp-lastindex-not-zero.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/internal-regexp-lastindex-not-zero.js new file mode 100644 index 00000000000..944ef30989e --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/internal-regexp-lastindex-not-zero.js @@ -0,0 +1,33 @@ +// Copyright (C) 2018 Peter Wong. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: | + Throws TypeError when internally created RegExp's lastIndex is not 0 +info: | + RegExp.prototype [ @@matchAll ] ( string ) + [...] + 3. Return ? MatchAllIterator(R, string). + + MatchAllIterator ( R, O ) + [...] + 2. If ? IsRegExp(R) is true, then + [...] + 3. Else, + a. Let matcher be RegExpCreate(R, "g"). + b. If ? IsRegExp(matcher) is not true, throw a TypeError exception. + [...] + 3. If Get(matcher, "lastIndex") is not 0, throw a TypeError exception. +features: [Symbol.match, Symbol.matchAll] +---*/ + +Object.defineProperty(RegExp.prototype, Symbol.match, { + get() { + this.lastIndex = 1; + return true; + } +}); + +assert.throws(TypeError, function() { + RegExp.prototype[Symbol.matchAll].call({}, ''); +}); diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/isregexp-internal-regexp-is-false.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/isregexp-internal-regexp-is-false.js new file mode 100644 index 00000000000..214e9b7efd2 --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/isregexp-internal-regexp-is-false.js @@ -0,0 +1,29 @@ +// Copyright (C) 2018 Peter Wong. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: Throws TypeError when internally created RegExp's @@match is false +info: | + RegExp.prototype [ @@matchAll ] ( string ) + [...] + 3. Return ? MatchAllIterator(R, string). + + MatchAllIterator ( R, O ) + [...] + 2. If ? IsRegExp(R) is true, then + [...] + 3. Else, + a. Let matcher be RegExpCreate(R, "g"). + b. If ? IsRegExp(matcher) is not true, throw a TypeError exception. +features: [Symbol.match, Symbol.matchAll] +---*/ + +Object.defineProperty(RegExp.prototype, Symbol.match, { + get() { + return false; + } +}); + +assert.throws(TypeError, function() { + RegExp.prototype[Symbol.matchAll].call({}, ''); +}); diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/isregexp-internal-regexp-throws.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/isregexp-internal-regexp-throws.js new file mode 100644 index 00000000000..70b62da39f5 --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/isregexp-internal-regexp-throws.js @@ -0,0 +1,29 @@ +// Copyright (C) 2018 Peter Wong. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: Re-throws errors thrown while accessing @@match property +info: | + RegExp.prototype [ @@matchAll ] ( string ) + [...] + 3. Return ? MatchAllIterator(R, string). + + MatchAllIterator ( R, O ) + [...] + 2. If ? IsRegExp(R) is true, then + [...] + 3. Else, + a. Let matcher be RegExpCreate(R, "g"). + b. If ? IsRegExp(matcher) is not true, throw a TypeError exception. +features: [Symbol.match, Symbol.matchAll] +---*/ + +Object.defineProperty(RegExp.prototype, Symbol.match, { + get() { + throw new Test262Error(); + } +}); + +assert.throws(Test262Error, function() { + RegExp.prototype[Symbol.matchAll].call({}, ''); +}); diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/isregexp-this-throws.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/isregexp-this-throws.js new file mode 100644 index 00000000000..ce31f3392fb --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/isregexp-this-throws.js @@ -0,0 +1,26 @@ +// Copyright (C) 2018 Peter Wong. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: Re-throws errors thrown while accessing RegExp's @@match property +info: | + RegExp.prototype [ @@matchAll ] ( string ) + [...] + 3. Return ? MatchAllIterator(R, string). + + MatchAllIterator ( R, O ) + [...] + 2. If ? IsRegExp(R) is true, then + [...] +features: [Symbol.match, Symbol.matchAll] +---*/ + +var obj = { + get [Symbol.match]() { + throw new Test262Error(); + } +}; + +assert.throws(Test262Error, function() { + RegExp.prototype[Symbol.matchAll].call(obj, ''); +}); diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/length.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/length.js index 241d3d40ce9..7aee38c0cb7 100644 --- a/test/built-ins/RegExp/prototype/Symbol.matchAll/length.js +++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/length.js @@ -1,17 +1,22 @@ // Copyright (C) 2018 Jordan Harband. All rights reserved. // This code is governed by the BSD license found in the LICENSE file. /*--- +esid: pending description: RegExp.prototype[Symbol.matchAll] `length` property info: | - ES6 Section 17: - Every built-in Function object, including constructors, has a length - property whose value is an integer. Unless otherwise specified, this value - is equal to the largest number of named arguments shown in the subclause - headings for the function description, including optional parameters. + 17 ECMAScript Standard Built-in Objects: [...] - Unless otherwise specified, the length property of a built-in Function + Every built-in function object, including constructors, has a length + property whose value is an integer. Unless otherwise specified, this + value is equal to the largest number of named arguments shown in the + subclause headings for the function description. Optional parameters + (which are indicated with brackets: [ ]) or rest parameters (which + are shown using the form «...name») are not included in the default + argument count. + + Unless otherwise specified, the length property of a built-in function object has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }. includes: [propertyHelper.js] diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/name.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/name.js index a755118e007..b6030216425 100644 --- a/test/built-ins/RegExp/prototype/Symbol.matchAll/name.js +++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/name.js @@ -1,15 +1,20 @@ // Copyright (C) 2018 Jordan Harband. All rights reserved. // This code is governed by the BSD license found in the LICENSE file. /*--- +esid: pending description: RegExp.prototype[Symbol.matchAll] `name` property info: | - The value of the name property of this function is "[Symbol.matchAll]". + 17 ECMAScript Standard Built-in Objects: - ES6 Section 17: + [...] + + Every built-in function object, including constructors, that is not + identified as an anonymous function has a name property whose value + is a String. [...] - Unless otherwise specified, the name property of a built-in Function + Unless otherwise specified, the name property of a built-in function object, if it exists, has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }. includes: [propertyHelper.js] diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/prop-desc.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/prop-desc.js index df4f7955db7..63d27c57b78 100644 --- a/test/built-ins/RegExp/prototype/Symbol.matchAll/prop-desc.js +++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/prop-desc.js @@ -1,10 +1,12 @@ // Copyright (C) 2018 Jordan Harband. All rights reserved. // This code is governed by the BSD license found in the LICENSE file. - /*--- +esid: pending description: RegExp.prototype[Symbol.matchAll] property descriptor info: | - ES6 Section 17 + 17 ECMAScript Standard Built-in Objects: + + [...] Every other data property described in clauses 18 through 26 and in Annex B.2 has the attributes { [[Writable]]: true, [[Enumerable]]: false, @@ -14,6 +16,7 @@ features: [Symbol.matchAll] ---*/ assert.sameValue(typeof RegExp.prototype[Symbol.matchAll], 'function'); + verifyNotEnumerable(RegExp.prototype, Symbol.matchAll); verifyWritable(RegExp.prototype, Symbol.matchAll); verifyConfigurable(RegExp.prototype, Symbol.matchAll); diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/regexpcreate-this-throws.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/regexpcreate-this-throws.js new file mode 100644 index 00000000000..d34b563c282 --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/regexpcreate-this-throws.js @@ -0,0 +1,29 @@ +// Copyright (C) 2018 Peter Wong. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: Re-throws errors while creating an internal RegExp +info: | + RegExp.prototype [ @@matchAll ] ( string ) + [...] + 3. Return ? MatchAllIterator(R, string). + + MatchAllIterator ( R, O ) + [...] + 2. If ? IsRegExp(R) is true, then + [...] + 3. Else, + a. Let R be RegExpCreate(R, "g"). +features: [Symbol.matchAll] +---*/ + +var obj = { + toString() { + throw new Test262Error(); + } +}; + +assert.throws(Test262Error, function() { + RegExp.prototype[Symbol.matchAll].call(obj, ''); +}); + diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor-get-constructor-throws.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor-get-constructor-throws.js new file mode 100644 index 00000000000..2c255853ee3 --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor-get-constructor-throws.js @@ -0,0 +1,32 @@ +// Copyright (C) 2018 Peter Wong. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: | + Re-throws errors thrown while accessing RegExp's constructor property +info: | + RegExp.prototype [ @@matchAll ] ( string ) + [...] + 3. Return ? MatchAllIterator(R, string). + + MatchAllIterator ( R, O ) + [...] + 2. If ? IsRegExp(R) is true, then + a. Let C be ? SpeciesConstructor(R, RegExp). + + SpeciesConstructor ( O, defaultConstructor ) + [...] + 2. Let C be ? Get(O, "constructor"). +features: [Symbol.matchAll] +---*/ + +var regexp = /./; +Object.defineProperty(regexp, 'constructor', { + get(){ + throw new Test262Error(); + } +}); + +assert.throws(Test262Error, function() { + regexp[Symbol.matchAll](''); +}); diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor-get-species-throws.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor-get-species-throws.js new file mode 100644 index 00000000000..3e429a88dc7 --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor-get-species-throws.js @@ -0,0 +1,31 @@ +// Copyright (C) 2018 Peter Wong. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: Re-throws errors thrown while accessing of @@species property +info: | + RegExp.prototype [ @@matchAll ] ( string ) + [...] + 3. Return ? MatchAllIterator(R, string). + + MatchAllIterator ( R, O ) + [...] + 2. If ? IsRegExp(R) is true, then + a. Let C be ? SpeciesConstructor(R, RegExp). + + SpeciesConstructor ( O, defaultConstructor ) + [...] + 2. Let C be ? Get(O, "constructor"). +features: [Symbol.matchAll, Symbol.species] +---*/ + +var regexp = /./; +regexp.constructor = { + get [Symbol.species]() { + throw new Test262Error(); + } +}; + +assert.throws(Test262Error, function() { + regexp[Symbol.matchAll](''); +}); diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor-is-not-object-throws.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor-is-not-object-throws.js new file mode 100644 index 00000000000..d26752a9415 --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor-is-not-object-throws.js @@ -0,0 +1,41 @@ +// Copyright (C) 2018 Peter Wong. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: Throws TypeError if `constructor` property is not an object +info: | + RegExp.prototype [ @@matchAll ] ( string ) + [...] + 3. Return ? MatchAllIterator(R, string). + + MatchAllIterator ( R, O ) + [...] + 2. If ? IsRegExp(R) is true, then + a. Let C be ? SpeciesConstructor(R, RegExp). + + SpeciesConstructor ( O, defaultConstructor ) + [...] + 2. Let C be ? Get(O, "constructor"). + 3. If C is undefined, return defaultConstructor. + 4. If Type(C) is not Object, throw a TypeError exception. +features: [Symbol.matchAll] +---*/ + +var regexp = /./; + +function callMatchAll() { regexp[Symbol.matchAll](''); } + +regexp.constructor = null; +assert.throws(TypeError, callMatchAll, "`constructor` value is null"); + +regexp.constructor = true; +assert.throws(TypeError, callMatchAll, "`constructor` value is Boolean"); + +regexp.constructor = ""; +assert.throws(TypeError, callMatchAll, "`constructor` value is String"); + +regexp.constructor = Symbol(); +assert.throws(TypeError, callMatchAll, "`constructor` value is Symbol"); + +regexp.constructor = 1; +assert.throws(TypeError, callMatchAll, "`constructor` value is Number"); diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor-is-undefined.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor-is-undefined.js new file mode 100644 index 00000000000..792bb1e7f8c --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor-is-undefined.js @@ -0,0 +1,31 @@ +// Copyright (C) 2018 Peter Wong. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: Throws TypeError if `constructor` property is not an object +info: | + RegExp.prototype [ @@matchAll ] ( string ) + [...] + 3. Return ? MatchAllIterator(R, string). + + MatchAllIterator ( R, O ) + [...] + 2. If ? IsRegExp(R) is true, then + a. Let C be ? SpeciesConstructor(R, RegExp). + + SpeciesConstructor ( O, defaultConstructor ) + [...] + 2. Let C be ? Get(O, "constructor"). + 3. If C is undefined, return defaultConstructor. +features: [Symbol.matchAll] +includes: [compareArray.js, compareIterator.js, regExpUtils.js] +---*/ + +var regexp = /\w/g; +regexp.constructor = undefined; +var str = 'a*b'; + +assert.compareIterator(regexp[Symbol.matchAll](str), [ + matchValidator(['a'], 0, str), + matchValidator(['b'], 2, str) +]); diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor-species-is-not-constructor.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor-species-is-not-constructor.js new file mode 100644 index 00000000000..b47402d7d69 --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor-species-is-not-constructor.js @@ -0,0 +1,45 @@ +// Copyright (C) 2018 Peter Wong. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: TypeError is thrown when species constructor is not a constructor +info: | + RegExp.prototype [ @@matchAll ] ( string ) + [...] + 2. Return ? [MatchAllIterator](#matchalliterator)(R, string). + + MatchAllIterator ( R, O ) + [...] + 3. Let C be ? [SpeciesConstructor][species-constructor](R, RegExp). + + SpeciesConstructor ( O, defaultConstructor ) + [...] + 2. Let C be ? Get(O, "constructor"). + 3. If C is undefined, return defaultConstructor. + 4. If Type(C) is not Object, throw a TypeError exception. + 5. Let S be ? Get(C, @@species). + 6. If S is either undefined or null, return defaultConstructor. + 7. If IsConstructor(S) is true, return S. + 8. Throw a TypeError exception. +features: [Symbol.matchAll, Symbol.species] +---*/ + +var regexp = /./; +var speciesConstructor = {}; +regexp.constructor = speciesConstructor; + +var callMatchAll = function() { + regexp[Symbol.matchAll](''); +} + +speciesConstructor[Symbol.species] = true; +assert.throws(TypeError, callMatchAll, "`constructor[Symbol.species]` value is Boolean"); + +speciesConstructor[Symbol.species] = 1; +assert.throws(TypeError, callMatchAll, "`constructor[Symbol.species]` value is Number"); + +speciesConstructor[Symbol.species] = Symbol(); +assert.throws(TypeError, callMatchAll, "`constructor[Symbol.species]` value is Symbol"); + +speciesConstructor[Symbol.species] = true; +assert.throws(TypeError, callMatchAll, "`constructor[Symbol.species]` value is Boolean"); diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor-species-is-null-or-undefined.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor-species-is-null-or-undefined.js new file mode 100644 index 00000000000..564d8bb58b9 --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor-species-is-null-or-undefined.js @@ -0,0 +1,41 @@ +// Copyright (C) 2018 Peter Wong. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: | + Default constructor is used when species constructor is null or undefined +info: | + RegExp.prototype [ @@matchAll ] ( string ) + [...] + 2. Return ? [MatchAllIterator](#matchalliterator)(R, string). + + MatchAllIterator ( R, O ) + [...] + 3. Let C be ? [SpeciesConstructor][species-constructor](R, RegExp). + + SpeciesConstructor ( O, defaultConstructor ) + [...] + 2. Let C be ? Get(O, "constructor"). + 3. If C is undefined, return defaultConstructor. + 4. If Type(C) is not Object, throw a TypeError exception. + 5. Let S be ? Get(C, @@species). + 6. If S is either undefined or null, return defaultConstructor. +features: [Symbol.matchAll, Symbol.species] +includes: [compareArray.js, compareIterator.js, regExpUtils.js] +---*/ + +function TestWithConstructor(ctor) { + var regexp = /\w/g; + regexp.constructor = { + [Symbol.species]: ctor + }; + var str = 'a*b'; + + assert.compareIterator(regexp[Symbol.matchAll](str), [ + matchValidator(['a'], 0, str), + matchValidator(['b'], 2, str) + ]); +} + +TestWithConstructor(undefined); +TestWithConstructor(null); diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor-species-throws.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor-species-throws.js new file mode 100644 index 00000000000..70a6683f488 --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor-species-throws.js @@ -0,0 +1,29 @@ +// Copyright (C) 2018 Peter Wong. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: Re-throws errors when calling constructor's @@species +info: | + RegExp.prototype [ @@matchAll ] ( string ) + [...] + 3. Return ? MatchAllIterator(R, string). + + MatchAllIterator ( R, O ) + [...] + 2. If ? IsRegExp(R) is true, then + a. Let C be ? SpeciesConstructor(R, RegExp). + b. Let flags be ? ToString(? Get(R, "flags")) + c. Let matcher be ? Construct(C, R, flags). +features: [Symbol.matchAll, Symbol.species] +---*/ + +var regexp = /./; +regexp.constructor = { + [Symbol.species]: function() { + throw new Test262Error(); + } +}; + +assert.throws(Test262Error, function() { + regexp[Symbol.matchAll](''); +}); diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor.js new file mode 100644 index 00000000000..cb9e9bf03c2 --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor.js @@ -0,0 +1,42 @@ +// Copyright (C) 2018 Peter Wong. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: Custom species constructor is called when creating internal RegExp +info: | + RegExp.prototype [ @@matchAll ] ( string ) + [...] + 3. Return ? MatchAllIterator(R, string). + + MatchAllIterator ( R, O ) + [...] + 2. If ? IsRegExp(R) is true, then + a. Let C be ? SpeciesConstructor(R, RegExp). + b. Let flags be ? ToString(? Get(R, "flags")) + c. Let matcher be ? Construct(C, R, flags). +features: [Symbol.matchAll, Symbol.species] +includes: [compareArray.js, compareIterator.js, regExpUtils.js] +---*/ + +var callCount = 0; +var callArgs; +var regexp = /\d/u; +regexp.constructor = { + [Symbol.species]: function(){ + callCount++; + callArgs = arguments; + return /\w/g; + } +}; +var str = 'a*b'; +var iter = regexp[Symbol.matchAll](str); + +assert.sameValue(callCount, 1); +assert.sameValue(callArgs.length, 2); +assert.sameValue(callArgs[0], regexp); +assert.sameValue(callArgs[1], 'u'); + +assert.compareIterator(iter, [ + matchValidator(['a'], 0, str), + matchValidator(['b'], 2, str) +]); diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/species-regexp-get-global-throws.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/species-regexp-get-global-throws.js new file mode 100644 index 00000000000..46304cc84a0 --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/species-regexp-get-global-throws.js @@ -0,0 +1,34 @@ +// Copyright (C) 2018 Peter Wong. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: | + Re-throws errors thrown while accessing species constructed RegExp's + global property +info: | + RegExp.prototype [ @@matchAll ] ( string ) + [...] + 3. Return ? MatchAllIterator(R, string). + + MatchAllIterator ( R, O ) + [...] + 2. If ? IsRegExp(R) is true, then + [...] + d. Let global be ? ToBoolean(? Get(matcher, "global")). +features: [Symbol.matchAll, Symbol.species] +---*/ + +var regexp = /./; +regexp.constructor = { + [Symbol.species]: function() { + return Object.defineProperty(/./, 'global', { + get() { + throw new Test262Error(); + } + }); + } +}; + +assert.throws(Test262Error, function() { + regexp[Symbol.matchAll](''); +}); diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/species-regexp-get-unicode-throws.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/species-regexp-get-unicode-throws.js new file mode 100644 index 00000000000..931b0289956 --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/species-regexp-get-unicode-throws.js @@ -0,0 +1,34 @@ +// Copyright (C) 2018 Peter Wong. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: | + Re-throws errors thrown while accessing species constructed RegExp's + unicode property +info: | + RegExp.prototype [ @@matchAll ] ( string ) + [...] + 3. Return ? MatchAllIterator(R, string). + + MatchAllIterator ( R, O ) + [...] + 2. If ? IsRegExp(R) is true, then + [...] + e. Let fullUnicode be ? ToBoolean(? Get(matcher, "unicode")). +features: [Symbol.matchAll, Symbol.species] +---*/ + +var regexp = /./; +regexp.constructor = { + [Symbol.species]: function() { + return Object.defineProperty(/./, 'unicode', { + get() { + throw new Test262Error(); + } + }); + } +}; + +assert.throws(Test262Error, function() { + regexp[Symbol.matchAll](''); +}); diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/coerce-arg.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/string-tostring-throws.js similarity index 59% rename from test/built-ins/RegExp/prototype/Symbol.matchAll/coerce-arg.js rename to test/built-ins/RegExp/prototype/Symbol.matchAll/string-tostring-throws.js index b2557aae99d..672ba5792c9 100644 --- a/test/built-ins/RegExp/prototype/Symbol.matchAll/coerce-arg.js +++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/string-tostring-throws.js @@ -1,27 +1,27 @@ // Copyright (C) 2018 Jordan Harband. All rights reserved. // This code is governed by the BSD license found in the LICENSE file. - /*--- +esid: pending description: String coercion of string parameter info: | - RegExp.prototype [ @@matchAll ] ( string ) - + RegExp.prototype [ @@matchAll ] ( string ) [...] - 2. Let S be ? ToString(O). - [...] -features: [Symbol.match, Symbol.matchAll] + 3. Return ? MatchAllIterator(R, string). + + MatchAllIterator ( R, O ) + 1. Let S be ? ToString(O). +features: [Symbol.matchAll] ---*/ var obj = { - valueOf: function() { + valueOf() { $ERROR('This method should not be invoked.'); }, - toString: function() { + toString() { throw new Test262Error('toString invoked'); } }; -obj[Symbol.match] = true; -assert.throws(Test262Error, function () { +assert.throws(Test262Error, function() { /toString value/[Symbol.matchAll](obj); }); diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/string-tostring.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/string-tostring.js new file mode 100644 index 00000000000..bafeb125b65 --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/string-tostring.js @@ -0,0 +1,29 @@ +// Copyright (C) 2018 Peter Wong. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: String coercion of `string` argument +info: | + RegExp.prototype [ @@matchAll ] ( string ) + [...] + 3. Return ? MatchAllIterator(R, string). + + MatchAllIterator ( R, O ) + 1. Let S be ? ToString(O). +features: [Symbol.matchAll] +includes: [compareArray.js, compareIterator.js, regExpUtils.js] +---*/ + +var str = 'a*b'; +var obj = { + toString() { + return str; + } +}; +var regexp = /\w/g; + +assert.compareIterator(regexp[Symbol.matchAll](obj), [ + matchValidator(['a'], 0, str), + matchValidator(['b'], 2, str) +]); + diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/this-get-flags-throws.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/this-get-flags-throws.js new file mode 100644 index 00000000000..0f21590b74d --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/this-get-flags-throws.js @@ -0,0 +1,28 @@ +// Copyright (C) 2018 Peter Wong. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: Re-throws errors thrown while accessing RegExp's flags property +info: | + RegExp.prototype [ @@matchAll ] ( string ) + [...] + 3. Return ? MatchAllIterator(R, string). + + MatchAllIterator ( R, O ) + [...] + 2. If ? IsRegExp(R) is true, then + [...] + b. Let flags be ? ToString(? Get(R, "flags")) +features: [Symbol.matchAll] +---*/ + +var regexp = /./; +Object.defineProperty(regexp, 'flags', { + get() { + throw new Test262Error(); + } +}); + +assert.throws(Test262Error, function() { + regexp[Symbol.matchAll](''); +}); diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/this-get-flags.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/this-get-flags.js new file mode 100644 index 00000000000..eca4ffa4d4b --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/this-get-flags.js @@ -0,0 +1,29 @@ +// Copyright (C) 2018 Peter Wong. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: Regexp's flags +info: | + RegExp.prototype [ @@matchAll ] ( string ) + [...] + 3. Return ? MatchAllIterator(R, string). + + MatchAllIterator ( R, O ) + [...] + 2. If ? IsRegExp(R) is true, then + [...] + b. Let flags be ? ToString(? Get(R, "flags")) +features: [Symbol.matchAll] +includes: [compareArray.js, compareIterator.js, regExpUtils.js] +---*/ + +var regexp = /\w/; +Object.defineProperty(regexp, 'flags', { + value: 'g' +}); +var str = 'a*b'; + +assert.compareIterator(regexp[Symbol.matchAll](str), [ + matchValidator(['a'], 0, str), + matchValidator(['b'], 2, str) +]); diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/this-lastindex-cached.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/this-lastindex-cached.js new file mode 100644 index 00000000000..ebefdb4e388 --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/this-lastindex-cached.js @@ -0,0 +1,36 @@ +// Copyright (C) 2018 Peter Wong. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: Verify regexp's lastIndex is cached +info: | + RegExp.prototype [ @@matchAll ] ( string ) + [...] + 3. Return ? MatchAllIterator(R, string). + + MatchAllIterator ( R, O ) + [...] + 2. If ? IsRegExp(R) is true, then + [...] + f. Let lastIndex be ? ToLength(? Get(R, "lastIndex")). + g. Perform ? Set(matcher, "lastIndex", lastIndex, true). +features: [Symbol.matchAll] +includes: [compareArray.js, compareIterator.js, regExpUtils.js] +---*/ + +var regexp = /./g; +regexp.lastIndex = { + valueOf() { + return 2; + } +}; +var str = 'abcd'; +var iter = regexp[Symbol.matchAll](str); + +// Verify lastIndex is cached at the time of calling @@matchAll +regexp.lastIndex = 0; + +assert.compareIterator(iter, [ + matchValidator(['c'], 2, str), + matchValidator(['d'], 3, str) +]); diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/this-not-object-throws.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/this-not-object-throws.js new file mode 100644 index 00000000000..b8f350d05f6 --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/this-not-object-throws.js @@ -0,0 +1,31 @@ +// Copyright (C) 2018 Jordan Harband. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: Throws TypeError when `this` is not an Object +info: | + RegExp.prototype [ @@matchAll ] ( string ) + 1. Let R be the this value. + 2. If Type(R) is not Object, throw a TypeError exception. +features: [Symbol.matchAll] +---*/ + +var thisValue; +var callMatchAll = function() { + RegExp.prototype[Symbol.matchAll].call(thisValue, ''); +}; + +thisValue = null; +assert.throws(TypeError, callMatchAll, 'this value is null'); + +thisValue = true; +assert.throws(TypeError, callMatchAll, 'this value is Boolean'); + +thisValue = ''; +assert.throws(TypeError, callMatchAll, 'this value is String'); + +thisValue = Symbol(); +assert.throws(TypeError, callMatchAll, 'this value is Symbol'); + +thisValue = 1; +assert.throws(TypeError, callMatchAll, 'this value is Number'); diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/this-tolength-lastindex-throws.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/this-tolength-lastindex-throws.js new file mode 100644 index 00000000000..fcaefdaf415 --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/this-tolength-lastindex-throws.js @@ -0,0 +1,28 @@ +// Copyright (C) 2018 Peter Wong. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: Re-throws errors while coercing RegExp's lastIndex +info: | + RegExp.prototype [ @@matchAll ] ( string ) + [...] + 3. Return ? MatchAllIterator(R, string). + + MatchAllIterator ( R, O ) + [...] + 2. If ? IsRegExp(R) is true, then + [...] + f. Let lastIndex be ? ToLength(? Get(R, "lastIndex")). +features: [Symbol.matchAll] +---*/ + +var regexp = /./; +regexp.lastIndex = { + valueOf() { + throw new Test262Error(); + } +}; + +assert.throws(Test262Error, function() { + regexp[Symbol.matchAll](''); +}); diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/this-tostring-flags-throws.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/this-tostring-flags-throws.js new file mode 100644 index 00000000000..206cc65d100 --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/this-tostring-flags-throws.js @@ -0,0 +1,33 @@ +// Copyright (C) 2018 Peter Wong. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: Re-throws errors while coercing RegExp's flags to a string +info: | + RegExp.prototype [ @@matchAll ] ( string ) + [...] + 3. Return ? MatchAllIterator(R, string). + + MatchAllIterator ( R, O ) + [...] + 2. If ? IsRegExp(R) is true, then + [...] + b. Let flags be ? ToString(? Get(R, "flags")) +features: [Symbol.matchAll] +---*/ + +var regexp = /\w/; +Object.defineProperty(regexp, 'flags', { + value: { + valueOf() { + ERROR('valueOf Should not be called'); + }, + toString() { + throw new Test262Error(); + } + } +}); + +assert.throws(Test262Error, function() { + regexp[Symbol.matchAll](''); +}); diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/this-tostring-flags.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/this-tostring-flags.js new file mode 100644 index 00000000000..5c7f9cb8159 --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/this-tostring-flags.js @@ -0,0 +1,33 @@ +// Copyright (C) 2018 Peter Wong. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: Corercing regexp's flags +info: | + RegExp.prototype [ @@matchAll ] ( string ) + [...] + 3. Return ? MatchAllIterator(R, string). + + MatchAllIterator ( R, O ) + [...] + 2. If ? IsRegExp(R) is true, then + [...] + b. Let flags be ? ToString(? Get(R, "flags")) +features: [Symbol.matchAll] +includes: [compareArray.js, compareIterator.js, regExpUtils.js] +---*/ + +var regexp = /\w/; +Object.defineProperty(regexp, 'flags', { + value: { + toString() { + return 'g'; + } + } +}); +var str = 'a*b'; + +assert.compareIterator(regexp[Symbol.matchAll](str), [ + matchValidator(['a'], 0, str), + matchValidator(['b'], 2, str) +]); diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/this-val-non-obj.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/this-val-non-obj.js deleted file mode 100644 index b4469f2ac76..00000000000 --- a/test/built-ins/RegExp/prototype/Symbol.matchAll/this-val-non-obj.js +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (C) 2018 Jordan Harband. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -description: The `this` value must be an object -info: | - 1. Let R be the this value. - 2. Return ? MatchAllIterator(R, string). - [...] - 1. If ? IsRegExp(R) is not true, throw a TypeError exception. -features: [Symbol.matchAll] ----*/ - -assert.throws(TypeError, function() { - RegExp.prototype[Symbol.matchAll].call(undefined); -}); - -assert.throws(TypeError, function() { - RegExp.prototype[Symbol.matchAll].call(null); -}); - -assert.throws(TypeError, function() { - RegExp.prototype[Symbol.matchAll].call(true); -}); - -assert.throws(TypeError, function() { - RegExp.prototype[Symbol.matchAll].call('string'); -}); - -assert.throws(TypeError, function() { - RegExp.prototype[Symbol.matchAll].call(Symbol.matchAll); -}); - -assert.throws(TypeError, function() { - RegExp.prototype[Symbol.matchAll].call(86); -}); diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/this-val-non-regexp.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/this-val-non-regexp.js deleted file mode 100644 index 76a57831cb1..00000000000 --- a/test/built-ins/RegExp/prototype/Symbol.matchAll/this-val-non-regexp.js +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (C) 2018 Jordan Harband. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -description: The `this` value must be a regular expression (has Symbol.match) -info: | - 1. Let R be the this value. - 2. Return ? MatchAllIterator(R, string). - [...] - 1. If ? IsRegExp(R) is not true, throw a TypeError exception. -features: [Symbol.match, Symbol.matchAll] ----*/ - -var regexObj = {}; -regexObj[Symbol.match] = true; -var obj = {}; - -RegExp.prototype[Symbol.matchAll].call(regexObj); - -assert.throws(TypeError, function() { - RegExp.prototype[Symbol.matchAll].call(obj); -}); diff --git a/test/built-ins/RegExpStringIteratorPrototype/Symbol.toStringTag.js b/test/built-ins/RegExpStringIteratorPrototype/Symbol.toStringTag.js new file mode 100644 index 00000000000..557cf18509f --- /dev/null +++ b/test/built-ins/RegExpStringIteratorPrototype/Symbol.toStringTag.js @@ -0,0 +1,22 @@ +// Copyright (C) 2018 Peter Wong. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: `Symbol.toStringTag` property descriptor +info: | + The initial value of the @@toStringTag property is the string value "String + Iterator". + + This property has the attributes { [[Writable]]: false, [[Enumerable]]: + false, [[Configurable]]: true }. +features: [Symbol.matchAll, Symbol.toStringTag] +includes: [propertyHelper.js] +---*/ + +var RegExpStringIteratorProto = Object.getPrototypeOf(/./[Symbol.matchAll]('')); + +assert.sameValue(RegExpStringIteratorProto[Symbol.toStringTag], 'RegExp String Iterator'); + +verifyNotEnumerable(RegExpStringIteratorProto, Symbol.toStringTag); +verifyNotWritable(RegExpStringIteratorProto, Symbol.toStringTag); +verifyConfigurable(RegExpStringIteratorProto, Symbol.toStringTag); diff --git a/test/built-ins/RegExpStringIteratorPrototype/ancestry.js b/test/built-ins/RegExpStringIteratorPrototype/ancestry.js new file mode 100644 index 00000000000..f7a6e7b6cbc --- /dev/null +++ b/test/built-ins/RegExpStringIteratorPrototype/ancestry.js @@ -0,0 +1,16 @@ +// Copyright (C) 2018 Peter Wong. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: | + The [[Prototype]] internal slot ofthe %RegExpStringIteratorPrototype% is the + %IteratorPrototype% intrinsic object (25.1.2). +features: [Symbol.iterator, Symbol.matchAll] +---*/ + +var RegExpStringIteratorProto = Object.getPrototypeOf(/./[Symbol.matchAll]('a')); +var ArrayIteratorProto = Object.getPrototypeOf( + Object.getPrototypeOf([][Symbol.iterator]()) +); + +assert.sameValue(Object.getPrototypeOf(RegExpStringIteratorProto), ArrayIteratorProto); diff --git a/test/built-ins/RegExpStringIteratorPrototype/next/custom-regexpexec-call-throws.js b/test/built-ins/RegExpStringIteratorPrototype/next/custom-regexpexec-call-throws.js new file mode 100644 index 00000000000..74df2c83d10 --- /dev/null +++ b/test/built-ins/RegExpStringIteratorPrototype/next/custom-regexpexec-call-throws.js @@ -0,0 +1,28 @@ +// Copyright (C) 2018 Peter Wong. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: Re-throws errors when calling exec +info: | + %RegExpStringIteratorPrototype%.next ( ) + [...] + 9. Let match be ? RegExpExec(R, S). + + Runtime Semantics: RegExpExec ( R, S ) + 1. Assert: Type(R) is Object. + 2. Assert: Type(S) is String. + 3. Let exec be ? Get(R, "exec"). + 4. If IsCallable(exec) is true, then + a. Let result be ? Call(exec, R, « S »). +features: [Symbol.matchAll] +---*/ + +var iter = /./[Symbol.matchAll](''); + +RegExp.prototype.exec = function() { + throw new Test262Error(); +}; + +assert.throws(Test262Error, function() { + iter.next(); +}); diff --git a/test/built-ins/RegExpStringIteratorPrototype/next/custom-regexpexec-get-throws.js b/test/built-ins/RegExpStringIteratorPrototype/next/custom-regexpexec-get-throws.js new file mode 100644 index 00000000000..808b142a219 --- /dev/null +++ b/test/built-ins/RegExpStringIteratorPrototype/next/custom-regexpexec-get-throws.js @@ -0,0 +1,28 @@ +// Copyright (C) 2018 Peter Wong. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: Re-throws errors thrown while accessing RegExp's exec property +info: | + %RegExpStringIteratorPrototype%.next ( ) + [...] + 9. Let match be ? RegExpExec(R, S). + + Runtime Semantics: RegExpExec ( R, S ) + 1. Assert: Type(R) is Object. + 2. Assert: Type(S) is String. + 3. Let exec be ? Get(R, "exec"). +features: [Symbol.matchAll] +---*/ + +var iter = /./[Symbol.matchAll](''); + +Object.defineProperty(RegExp.prototype, 'exec', { + get() { + throw new Test262Error(); + } +}); + +assert.throws(Test262Error, function() { + iter.next(); +}); diff --git a/test/built-ins/RegExpStringIteratorPrototype/next/custom-regexpexec-match-get-0-throws.js b/test/built-ins/RegExpStringIteratorPrototype/next/custom-regexpexec-match-get-0-throws.js new file mode 100644 index 00000000000..7dc986da924 --- /dev/null +++ b/test/built-ins/RegExpStringIteratorPrototype/next/custom-regexpexec-match-get-0-throws.js @@ -0,0 +1,30 @@ +// Copyright (C) 2018 Peter Wong. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: Re-throws errors thrown while accessing the first match +info: | + %RegExpStringIteratorPrototype%.next ( ) + [...] + 9. Let match be ? RegExpExec(R, S). + 10. If match is null, then + [...] + 11. Else, + a. If global is true, + i. Let matchStr be ? ToString(? Get(match, "0")). +features: [Symbol.matchAll] +---*/ + +var iter = /./g[Symbol.matchAll](''); + +RegExp.prototype.exec = function() { + return { + get '0'() { + throw new Test262Error(); + } + }; +}; + +assert.throws(Test262Error, function() { + iter.next(); +}); diff --git a/test/built-ins/RegExpStringIteratorPrototype/next/custom-regexpexec-match-get-0-tostring-throws.js b/test/built-ins/RegExpStringIteratorPrototype/next/custom-regexpexec-match-get-0-tostring-throws.js new file mode 100644 index 00000000000..e84b3c4fc03 --- /dev/null +++ b/test/built-ins/RegExpStringIteratorPrototype/next/custom-regexpexec-match-get-0-tostring-throws.js @@ -0,0 +1,31 @@ +// Copyright (C) 2018 Peter Wong. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: Re-throws errors thrown from coercing first match to a string +info: | + %RegExpStringIteratorPrototype%.next ( ) + [...] + 9. Let match be ? RegExpExec(R, S). + 10. If match is null, then + [...] + 11. Else, + a. If global is true, + i. Let matchStr be ? ToString(? Get(match, "0")). +features: [Symbol.matchAll] +---*/ + +var iter = /./g[Symbol.matchAll](''); + +RegExp.prototype.exec = function() { + return [{ + toString: function() { + throw new Test262Error(); + } + }]; +}; + +assert.throws(Test262Error, function() { + iter.next(); +}); + diff --git a/test/built-ins/RegExpStringIteratorPrototype/next/custom-regexpexec-match-get-0-tostring.js b/test/built-ins/RegExpStringIteratorPrototype/next/custom-regexpexec-match-get-0-tostring.js new file mode 100644 index 00000000000..33ac742ca2d --- /dev/null +++ b/test/built-ins/RegExpStringIteratorPrototype/next/custom-regexpexec-match-get-0-tostring.js @@ -0,0 +1,48 @@ +// Copyright (C) 2018 Peter Wong. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: Behavior when first match is coerced to a empty string +info: | + %RegExpStringIteratorPrototype%.next ( ) + [...] + 9. Let match be ? RegExpExec(R, S). + 10. If match is null, then + [...] + 11. Else, + a. If global is true, + i. Let matchStr be ? ToString(? Get(match, "0")). + ii. If matchStr is the empty string, + 1. Let thisIndex be ? ToLength(? Get(R, "lastIndex"). + 2. Let nextIndex be ! AdvanceStringIndex(S, thisIndex, fullUnicode). + 3. Perform ? Set(R, "lastIndex", nextIndex, true). + iii. Return ! CreateIterResultObject(match, false). +features: [Symbol.matchAll] +---*/ + +var iter = /./g[Symbol.matchAll](''); + +var execResult = { + get '0'() { + return { + toString() { return ''; } + }; + } +}; + +var internalRegExp; +RegExp.prototype.exec = function () { + internalRegExp = this; + return execResult; +}; + +var result = iter.next(); +assert.sameValue(internalRegExp.lastIndex, 1); +assert.sameValue(result.value, execResult); +assert(!result.done); + + +result = iter.next(); +assert.sameValue(internalRegExp.lastIndex, 2); +assert.sameValue(result.value, execResult); +assert(!result.done); diff --git a/test/built-ins/RegExpStringIteratorPrototype/next/custom-regexpexec-not-callable.js b/test/built-ins/RegExpStringIteratorPrototype/next/custom-regexpexec-not-callable.js new file mode 100644 index 00000000000..d659cd28d44 --- /dev/null +++ b/test/built-ins/RegExpStringIteratorPrototype/next/custom-regexpexec-not-callable.js @@ -0,0 +1,40 @@ +// Copyright (C) 2018 Peter Wong. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: Behavior with a custom RegExp exec +info: | + %RegExpStringIteratorPrototype%.next ( ) + [...] + 9. Let match be ? RegExpExec(R, S). + + Runtime Semantics: RegExpExec ( R, S ) + 1. Assert: Type(R) is Object. + 2. Assert: Type(S) is String. + 3. Let exec be ? Get(R, "exec"). + 4. If IsCallable(exec) is true, then + [...] + 5. If R does not have a [[RegExpMatcher]] internal slot, throw a + TypeError exception. + 6. Return ? RegExpBuiltinExec(R, S). +features: [Symbol.matchAll] +includes: [compareArray.js, compareIterator.js, regExpUtils.js] +---*/ + +function TestWithRegExpExec(exec) { + RegExp.prototype.exec = exec; + + var regexp = /\w/g; + var str = 'a*b'; + + assert.compareIterator(regexp[Symbol.matchAll](str), [ + matchValidator(['a'], 0, str), + matchValidator(['b'], 2, str) + ]); +} + +TestWithRegExpExec(undefined); +TestWithRegExpExec(null); +TestWithRegExpExec(5); +TestWithRegExpExec(true); +TestWithRegExpExec(Symbol()); diff --git a/test/built-ins/RegExpStringIteratorPrototype/next/custom-regexpexec.js b/test/built-ins/RegExpStringIteratorPrototype/next/custom-regexpexec.js new file mode 100644 index 00000000000..850a7a18c0e --- /dev/null +++ b/test/built-ins/RegExpStringIteratorPrototype/next/custom-regexpexec.js @@ -0,0 +1,55 @@ +// Copyright (C) 2018 Peter Wong. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: Behavior with a custom RegExp exec +info: | + %RegExpStringIteratorPrototype%.next ( ) + [...] + 9. Let match be ? RegExpExec(R, S). + + Runtime Semantics: RegExpExec ( R, S ) + 1. Assert: Type(R) is Object. + 2. Assert: Type(S) is String. + 3. Let exec be ? Get(R, "exec"). + 4. If IsCallable(exec) is true, then + a. Let result be ? Call(exec, R, « S »). + b. If Type(result) is neither Object or Null, throw a TypeError exception. + c. Return result. +features: [Symbol.matchAll] +---*/ + +var regexp = /./g; +var str = 'abc'; +var iter = regexp[Symbol.matchAll](str); + +var callArgs, callCount; +function callNextWithExecReturnValue(returnValue) { + callArgs = undefined; + callCount = 0; + + RegExp.prototype.exec = function() { + callArgs = arguments; + callCount++; + return returnValue; + } + + return iter.next(); +} + +var firstExecReturnValue = ['ab']; +var result = callNextWithExecReturnValue(firstExecReturnValue); +assert.sameValue(result.value, firstExecReturnValue); +assert(!result.done); + +assert.sameValue(callArgs.length, 1); +assert.sameValue(callArgs[0], str); +assert.sameValue(callCount, 1); + +result = callNextWithExecReturnValue(null); +assert.sameValue(result.value, undefined); +assert(result.done); + +assert.sameValue(callArgs.length, 1); +assert.sameValue(callArgs[0], str); +assert.sameValue(callCount, 1); diff --git a/test/built-ins/RegExpStringIteratorPrototype/next/length.js b/test/built-ins/RegExpStringIteratorPrototype/next/length.js new file mode 100644 index 00000000000..42cc58b7ef6 --- /dev/null +++ b/test/built-ins/RegExpStringIteratorPrototype/next/length.js @@ -0,0 +1,32 @@ +// Copyright (C) 2018 Peter Wong. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: %RegExpStringIteratorPrototype%.next `length` property +info: | + 17 ECMAScript Standard Built-in Objects: + + [...] + + Every built-in function object, including constructors, has a length + property whose value is an integer. Unless otherwise specified, this + value is equal to the largest number of named arguments shown in the + subclause headings for the function description. Optional parameters + (which are indicated with brackets: [ ]) or rest parameters (which + are shown using the form «...name») are not included in the default + argument count. + + Unless otherwise specified, the length property of a built-in function + object has the attributes { [[Writable]]: false, [[Enumerable]]: false, + [[Configurable]]: true }. +includes: [propertyHelper.js] +features: [Symbol.matchAll] +---*/ + +var RegExpStringIteratorProto = Object.getPrototypeOf(/./[Symbol.matchAll]('')); + +assert.sameValue(RegExpStringIteratorProto.next.length, 0); + +verifyNotEnumerable(RegExpStringIteratorProto.next, 'length'); +verifyNotWritable(RegExpStringIteratorProto.next, 'length'); +verifyConfigurable(RegExpStringIteratorProto.next, 'length'); diff --git a/test/built-ins/RegExpStringIteratorPrototype/next/name.js b/test/built-ins/RegExpStringIteratorPrototype/next/name.js new file mode 100644 index 00000000000..253c3b2f62a --- /dev/null +++ b/test/built-ins/RegExpStringIteratorPrototype/next/name.js @@ -0,0 +1,30 @@ +// Copyright (C) 2018 Peter Wong. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: %RegExpStringIteratorPrototype%.next `name` property +info: | + 17 ECMAScript Standard Built-in Objects: + + [...] + + Every built-in function object, including constructors, that is not + identified as an anonymous function has a name property whose value + is a String. + + [...] + + Unless otherwise specified, the name property of a built-in function + object, if it exists, has the attributes { [[Writable]]: false, + [[Enumerable]]: false, [[Configurable]]: true }. +includes: [propertyHelper.js] +features: [Symbol.matchAll] +---*/ + +var RegExpStringIteratorProto = Object.getPrototypeOf(/./[Symbol.matchAll]('')); + +assert.sameValue(RegExpStringIteratorProto.next.name, 'next'); + +verifyNotEnumerable(RegExpStringIteratorProto.next, 'name'); +verifyNotWritable(RegExpStringIteratorProto.next, 'name'); +verifyConfigurable(RegExpStringIteratorProto.next, 'name'); diff --git a/test/built-ins/RegExpStringIteratorPrototype/next/next-iteration-global.js b/test/built-ins/RegExpStringIteratorPrototype/next/next-iteration-global.js new file mode 100644 index 00000000000..d1b6726e585 --- /dev/null +++ b/test/built-ins/RegExpStringIteratorPrototype/next/next-iteration-global.js @@ -0,0 +1,40 @@ +// Copyright (C) 2018 Peter Wong. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: Iterates over each match +info: | + %RegExpStringIteratorPrototype%.next ( ) + [...] + 4. If O.[[Done]] is true, then + a. Return ! reateIterResultObject(undefined, true). + [...] + 9. Let match be ? RegExpExec(R, S). + 10. If match is null, then + a. Set O.[[Done]] to true. + b. Return ! CreateIterResultObject(undefined, true). + 11. Else, + a. If global is true, + i. Let matchStr be ? ToString(? Get(match, "0")). + ii. If matchStr is the empty string, + 1. Let thisIndex be ? ToLength(? Get(R, "lastIndex"). + 2. Let nextIndex be ! AdvanceStringIndex(S, thisIndex, fullUnicode). + 3. Perform ? Set(R, "lastIndex", nextIndex, true). + iii. Return ! CreateIterResultObject(match, false). +features: [Symbol.matchAll] +includes: [compareArray.js, compareIterator.js, regExpUtils.js] +---*/ + +var regexp = /\w/g; +var str = 'a*b'; +var iter = regexp[Symbol.matchAll](str); + +assert.compareIterator(iter, [ + matchValidator(['a'], 0, str), + matchValidator(['b'], 2, str) +]); + +// Verifies %RegExpStringIteratorPrototype%.next() step 4 +var result = iter.next(); +assert.sameValue(result.value, undefined); +assert(result.done); diff --git a/test/built-ins/RegExpStringIteratorPrototype/next/next-iteration.js b/test/built-ins/RegExpStringIteratorPrototype/next/next-iteration.js new file mode 100644 index 00000000000..a6de2ad8a91 --- /dev/null +++ b/test/built-ins/RegExpStringIteratorPrototype/next/next-iteration.js @@ -0,0 +1,37 @@ +// Copyright (C) 2018 Peter Wong. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: Iterates over the first match +info: | + %RegExpStringIteratorPrototype%.next ( ) + [...] + 4. If O.[[Done]] is true, then + a. Return ! reateIterResultObject(undefined, true). + [...] + 9. Let match be ? RegExpExec(R, S). + 10. If match is null, then + a. Set O.[[Done]] to true. + b. Return ! CreateIterResultObject(undefined, true). + 11. Else, + a. If global is true, + [...] + b. Else, + i. Set O.[[Done]] to true. + ii. Return ! CreateIterResultObject(match, false). +features: [Symbol.matchAll] +includes: [compareArray.js, compareIterator.js, regExpUtils.js] +---*/ + +var regexp = /\w/; +var str = '*a*b'; +var iter = regexp[Symbol.matchAll](str); + +assert.compareIterator(iter, [ + matchValidator(['a'], 1, str) +]); + +// Verifies %RegExpStringIteratorPrototype%.next() step 4 +var result = iter.next(); +assert.sameValue(result.value, undefined); +assert(result.done); diff --git a/test/built-ins/RegExpStringIteratorPrototype/next/next-missing-internal-slots.js b/test/built-ins/RegExpStringIteratorPrototype/next/next-missing-internal-slots.js new file mode 100644 index 00000000000..826b2ae3c5d --- /dev/null +++ b/test/built-ins/RegExpStringIteratorPrototype/next/next-missing-internal-slots.js @@ -0,0 +1,21 @@ +// Copyright (C) 2018 Peter Wong. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: Throws TypeError when `this` does not have all internal slots +info: | + %RegExpStringIteratorPrototype%.next ( ) + 1. Let O be the this value. + 2. If Type(O) is not Object, throw a TypeError exception. + 3. If O does not have all of the internal slots of a RegExp String Iterator + Object Instance (see PropertiesOfRegExpStringIteratorInstances), throw a + TypeError. +features: [Symbol.matchAll] +---*/ + +var iterator = /./[Symbol.matchAll](''); +var object = Object.create(iterator); + +assert.throws(TypeError, function() { + object.next(); +}); diff --git a/test/built-ins/RegExpStringIteratorPrototype/next/prop-desc.js b/test/built-ins/RegExpStringIteratorPrototype/next/prop-desc.js new file mode 100644 index 00000000000..3b8dd03d2b5 --- /dev/null +++ b/test/built-ins/RegExpStringIteratorPrototype/next/prop-desc.js @@ -0,0 +1,24 @@ +// Copyright (C) 2018 Peter Wong. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: %RegExpStringIteratorPrototype%.next property descriptor +info: | + 17 ECMAScript Standard Built-in Objects: + + [...] + + Every other data property described in clauses 18 through 26 and in Annex + B.2 has the attributes { [[Writable]]: true, [[Enumerable]]: false, + [[Configurable]]: true } unless otherwise specified. +includes: [propertyHelper.js] +features: [Symbol.matchAll] +---*/ + +var RegExpStringIteratorProto = Object.getPrototypeOf(/./[Symbol.matchAll]('')); + +assert.sameValue(typeof RegExpStringIteratorProto.next, 'function'); + +verifyNotEnumerable(RegExpStringIteratorProto, 'next'); +verifyWritable(RegExpStringIteratorProto, 'next'); +verifyConfigurable(RegExpStringIteratorProto, 'next'); diff --git a/test/built-ins/RegExpStringIteratorPrototype/next/regexp-tolength-lastindex-throws.js b/test/built-ins/RegExpStringIteratorPrototype/next/regexp-tolength-lastindex-throws.js new file mode 100644 index 00000000000..603393df67d --- /dev/null +++ b/test/built-ins/RegExpStringIteratorPrototype/next/regexp-tolength-lastindex-throws.js @@ -0,0 +1,33 @@ +// Copyright (C) 2018 Peter Wong. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: Re-throws errors thrown coercing RegExp's lastIndex to a length +info: | + %RegExpStringIteratorPrototype%.next ( ) + [...] + 9. Let match be ? RegExpExec(R, S). + 10. If match is null, then + [...] + 11. Else, + a. If global is true, + i. Let matchStr be ? ToString(? Get(match, "0")). + ii. If matchStr is the empty string, + 1. Let thisIndex be ? ToLength(? Get(R, "lastIndex"). +features: [Symbol.matchAll] +---*/ + +var iter = /./g[Symbol.matchAll](''); + +RegExp.prototype.exec = function() { + this.lastIndex = { + valueOf() { + throw new Test262Error(); + } + }; + return ['']; +}; + +assert.throws(Test262Error, function() { + iter.next(); +}); diff --git a/test/built-ins/RegExpStringIteratorPrototype/next/this-is-not-object-throws.js b/test/built-ins/RegExpStringIteratorPrototype/next/this-is-not-object-throws.js new file mode 100644 index 00000000000..4470ff19e8d --- /dev/null +++ b/test/built-ins/RegExpStringIteratorPrototype/next/this-is-not-object-throws.js @@ -0,0 +1,34 @@ +// Copyright (C) 2018 Peter Wong. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: Throws TypeError when `this` is not an Object +info: | + %RegExpStringIteratorPrototype%.next ( ) + 1. Let O be the this value. + 2. If Type(O) is not Object, throw a TypeError exception. +features: [Symbol.matchAll] +---*/ + +var RegExpStringIteratorProto = Object.getPrototypeOf(/./[Symbol.matchAll]('')); + +var thisValue; +var callNext = function() { + RegExpStringIteratorProto.next.call(thisValue); +}; + +thisValue = null; +assert.throws(TypeError, callNext, 'this value is null'); + +thisValue = true; +assert.throws(TypeError, callNext, 'this value is Boolean'); + +thisValue = ''; +assert.throws(TypeError, callNext, 'this value is String'); + +thisValue = Symbol(); +assert.throws(TypeError, callNext, 'this value is Symbol'); + +thisValue = 1; +assert.throws(TypeError, callNext, 'this value is Number'); + diff --git a/test/built-ins/String/prototype/matchAll/cstm-matcher-get-err.js b/test/built-ins/String/prototype/matchAll/cstm-matcher-get-err.js deleted file mode 100644 index e18431c89d7..00000000000 --- a/test/built-ins/String/prototype/matchAll/cstm-matcher-get-err.js +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (C) 2018 Jordan Harband. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -description: Behavior when error is thrown accessing @@matchAll property -info: | - [...] - 4. Let matcher be ? GetMethod(R, @@matchAll). - 5. If matcher is not undefined, then - a. Return ? Call(matcher, R, « O »). -features: [Symbol.match, Symbol.matchAll] ----*/ - -var obj = {}; -Object.defineProperty(obj, Symbol.match, { - value: true // to make IsRegExp pass -}); -Object.defineProperty(obj, Symbol.matchAll, { - get: function() { - throw new Test262Error(); - } -}); - -assert.throws(Test262Error, function() { - ''.matchAll(obj); -}); diff --git a/test/built-ins/String/prototype/matchAll/invoke-builtin-matchall.js b/test/built-ins/String/prototype/matchAll/invoke-builtin-matchall.js deleted file mode 100644 index feeb36bc6e5..00000000000 --- a/test/built-ins/String/prototype/matchAll/invoke-builtin-matchall.js +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (C) 2018 Jordan Harband. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -description: Invocation of @@matchAll property of internally-created RegExps -info: | - [...] - 3. Else, - a. Let R be ? RegExpCreate(regexp, "g"). - 4. Let matcher be ? GetMethod(R, @@matchAll). - 5. If matcher is not undefined, then - a. Return ? Call(matcher, R, « O »). - 6. Return ? MatchAllIterator(R, O). -features: [Symbol.match, Symbol.matchAll] ----*/ - -var originalMatchAll = RegExp.prototype[Symbol.matchAll]; -var returnVal = {}; -var result, thisVal, args; - -RegExp.prototype[Symbol.matchAll] = function() { - thisVal = this; - args = arguments; - return returnVal; -}; - -var str = 'target'; -var stringToMatch = 'string source'; - -try { - result = str.matchAll(stringToMatch); - - assert(thisVal instanceof RegExp); - assert.sameValue(!!thisVal[Symbol.match], true); - assert.sameValue(thisVal.source, stringToMatch); - assert.sameValue(thisVal.flags, 'g'); - assert.sameValue(thisVal.lastIndex, 0); - assert.sameValue(args.length, 1); - assert.sameValue(args[0], str); - assert.sameValue(result, returnVal); -} finally { - RegExp.prototype[Symbol.matchAll] = originalMatchAll; -} diff --git a/test/built-ins/String/prototype/matchAll/length.js b/test/built-ins/String/prototype/matchAll/length.js index fd5f0104c4f..101d8bbf2ed 100644 --- a/test/built-ins/String/prototype/matchAll/length.js +++ b/test/built-ins/String/prototype/matchAll/length.js @@ -1,20 +1,26 @@ // Copyright (C) 2018 Jordan Harband. All rights reserved. // This code is governed by the BSD license found in the LICENSE file. /*--- -description: Length of String.prototype.matchAll +esid: pending +description: String.prototype.matchAll `length` property info: | - ES6 Section 17: - Every built-in Function object, including constructors, has a length - property whose value is an integer. Unless otherwise specified, this value - is equal to the largest number of named arguments shown in the subclause - headings for the function description, including optional parameters. + 17 ECMAScript Standard Built-in Objects: [...] - Unless otherwise specified, the length property of a built-in Function + Every built-in function object, including constructors, has a length + property whose value is an integer. Unless otherwise specified, this + value is equal to the largest number of named arguments shown in the + subclause headings for the function description. Optional parameters + (which are indicated with brackets: [ ]) or rest parameters (which + are shown using the form «...name») are not included in the default + argument count. + + Unless otherwise specified, the length property of a built-in function object has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }. includes: [propertyHelper.js] +features: [String.prototype.matchAll] ---*/ assert.sameValue(String.prototype.matchAll.length, 1); diff --git a/test/built-ins/String/prototype/matchAll/name.js b/test/built-ins/String/prototype/matchAll/name.js index 84bb3cf647a..1175cb14038 100644 --- a/test/built-ins/String/prototype/matchAll/name.js +++ b/test/built-ins/String/prototype/matchAll/name.js @@ -1,27 +1,28 @@ // Copyright (C) 2018 Jordan Harband. All rights reserved. // This code is governed by the BSD license found in the LICENSE file. /*--- -description: Descriptor for `name` property +esid: pending +description: String.prototype.matchAll `name` property info: | - The value of the name property of this function is "matchAll". + 17 ECMAScript Standard Built-in Objects: - ES6 Section 17: ECMAScript Standard Built-in Objects + [...] - Every built-in Function object, including constructors, that is not - identified as an anonymous function has a name property whose value is a - String. Unless otherwise specified, this value is the name that is given to - the function in this specification. + Every built-in function object, including constructors, that is not + identified as an anonymous function has a name property whose value + is a String. - [...] + [...] - Unless otherwise specified, the name property of a built-in Function - object, if it exists, has the attributes { [[Writable]]: false, - [[Enumerable]]: false, [[Configurable]]: true }. -includes: [propertyHelper.js] + Unless otherwise specified, the name property of a built-in function + object, if it exists, has the attributes { [[Writable]]: false, + [[Enumerable]]: false, [[Configurable]]: true }. + includes: [propertyHelper.js] + features: [String.prototype.matchAll] ---*/ -assert.sameValue(String.prototype[Symbol.iterator].name, 'matchAll'); +assert.sameValue(String.prototype.matchAll.name, 'matchAll'); -verifyNotEnumerable(String.prototype[Symbol.iterator], 'name'); -verifyNotWritable(String.prototype[Symbol.iterator], 'name'); -verifyConfigurable(String.prototype[Symbol.iterator], 'name'); +verifyNotEnumerable(String.prototype.matchAll, 'name'); +verifyNotWritable(String.prototype.matchAll, 'name'); +verifyConfigurable(String.prototype.matchAll, 'name'); diff --git a/test/built-ins/String/prototype/matchAll/prop-desc.js b/test/built-ins/String/prototype/matchAll/prop-desc.js index 02b9eaa7140..eb1c59a60dc 100644 --- a/test/built-ins/String/prototype/matchAll/prop-desc.js +++ b/test/built-ins/String/prototype/matchAll/prop-desc.js @@ -1,18 +1,22 @@ // Copyright (C) 2018 Jordan Harband. All rights reserved. // This code is governed by the BSD license found in the LICENSE file. /*--- -description: Property descriptor +esid: pending +description: String.prototype.matchAll property descriptor info: | - ES6 Section 17 + 17 ECMAScript Standard Built-in Objects: + + [...] Every other data property described in clauses 18 through 26 and in Annex B.2 has the attributes { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true } unless otherwise specified. -features: [Symbol.iterator] includes: [propertyHelper.js] +features: [String.prototype.matchAll] ---*/ assert.sameValue(typeof String.prototype.matchAll, 'function'); + verifyNotEnumerable(String.prototype, 'matchAll'); verifyWritable(String.prototype, 'matchAll'); verifyConfigurable(String.prototype, 'matchAll'); diff --git a/test/built-ins/String/prototype/matchAll/regexp-get-matchAll-throws.js b/test/built-ins/String/prototype/matchAll/regexp-get-matchAll-throws.js new file mode 100644 index 00000000000..8c73480b05b --- /dev/null +++ b/test/built-ins/String/prototype/matchAll/regexp-get-matchAll-throws.js @@ -0,0 +1,25 @@ +// Copyright (C) 2018 Peter Wong. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: Re-throws errors when calling @@matchAll +info: | + String.prototype.matchAll ( regexp ) + [...] + 2. If regexp is neither undefined nor null, then + a. Let matcher be ? GetMethod(regexp, @@matchAll). + b. If matcher is not undefined, then + i. Return ? Call(matcher, regexp, « O »). +features: [Symbol.matchAll, String.prototype.matchAll] +---*/ + +var regexp = /./; +Object.defineProperty(regexp, Symbol.matchAll, { + get() { + throw new Test262Error(); + } +}); + +assert.throws(Test262Error, function() { + ''.matchAll(regexp); +}); diff --git a/test/built-ins/String/prototype/matchAll/regexp-is-null.js b/test/built-ins/String/prototype/matchAll/regexp-is-null.js new file mode 100644 index 00000000000..9ae102e6b16 --- /dev/null +++ b/test/built-ins/String/prototype/matchAll/regexp-is-null.js @@ -0,0 +1,27 @@ +// Copyright (C) 2018 Peter Wong. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: Behavior when regexp is null +info: | + String.prototype.matchAll ( regexp ) + 1. Let O be ? RequireObjectCoercible(this value). + 2. If regexp is neither undefined nor null, then + [...] + 3. Return ? MatchAllIterator(regexp, O). + + MatchAllIterator( regexp, O ) + [...] + 2. If ? IsRegExp(regexp) is true, then + [...] + 3. Else, + a. Let R be RegExpCreate(regexp, "g"). +features: [String.prototype.matchAll] +includes: [compareArray.js, compareIterator.js, regExpUtils.js] +---*/ + +var str = '-null-'; + +assert.compareIterator(str.matchAll(null), [ + matchValidator(['null'], 1, str) +]); diff --git a/test/built-ins/String/prototype/matchAll/regexp-is-undefined.js b/test/built-ins/String/prototype/matchAll/regexp-is-undefined.js new file mode 100644 index 00000000000..bf9ac09e004 --- /dev/null +++ b/test/built-ins/String/prototype/matchAll/regexp-is-undefined.js @@ -0,0 +1,28 @@ +// Copyright (C) 2018 Peter Wong. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: Behavior when regexp is null +info: | + String.prototype.matchAll ( regexp ) + 1. Let O be ? RequireObjectCoercible(this value). + 2. If regexp is neither undefined nor null, then + [...] + 3. Return ? MatchAllIterator(regexp, O). + + MatchAllIterator( regexp, O ) + [...] + 2. If ? IsRegExp(regexp) is true, then + [...] + 3. Else, + a. Let R be RegExpCreate(regexp, "g"). +features: [String.prototype.matchAll] +includes: [compareArray.js, compareIterator.js, regExpUtils.js] +---*/ + +var str = 'a'; + +assert.compareIterator(str.matchAll(undefined), [ + matchValidator([''], 0, str), + matchValidator([''], 1, str) +]); diff --git a/test/built-ins/String/prototype/matchAll/cstm-matcher-invocation.js b/test/built-ins/String/prototype/matchAll/regexp-matchAll-invocation.js similarity index 67% rename from test/built-ins/String/prototype/matchAll/cstm-matcher-invocation.js rename to test/built-ins/String/prototype/matchAll/regexp-matchAll-invocation.js index 72c09fd5418..7afe2c79657 100644 --- a/test/built-ins/String/prototype/matchAll/cstm-matcher-invocation.js +++ b/test/built-ins/String/prototype/matchAll/regexp-matchAll-invocation.js @@ -1,14 +1,16 @@ // Copyright (C) 2018 Jordan Harband. All rights reserved. // This code is governed by the BSD license found in the LICENSE file. - /*--- +esid: pending description: Invocation of @@matchAll property of user-supplied RegExp objects info: | + String.prototype.matchAll ( regexp ) [...] - 4. Let matcher be ? GetMethod(R, @@matchAll). - 5. If matcher is not undefined, then - a. Return ? Call(matcher, R, « O »). -features: [Symbol.match, Symbol.matchAll] + 2. If regexp is neither undefined nor null, then + a. Let matcher be ? GetMethod(regexp, @@matchAll). + b. If matcher is not undefined, then + i. Return ? Call(matcher, regexp, « O »). +features: [Symbol.matchAll, String.prototype.matchAll] ---*/ var obj = {}; @@ -16,9 +18,8 @@ var returnVal = {}; var callCount = 0; var thisVal, args; -obj[Symbol.match] = true; // https://tc39.github.io/ecma262/#sec-isregexp steps 1-3 obj[Symbol.matchAll] = function () { - callCount += 1; + callCount++; thisVal = this; args = arguments; return returnVal; diff --git a/test/built-ins/String/prototype/matchAll/regexp-matchAll-throws.js b/test/built-ins/String/prototype/matchAll/regexp-matchAll-throws.js new file mode 100644 index 00000000000..c94ddd095fe --- /dev/null +++ b/test/built-ins/String/prototype/matchAll/regexp-matchAll-throws.js @@ -0,0 +1,21 @@ +// Copyright (C) 2018 Peter Wong. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: Re-throws errors when calling @@matchAll +info: | + String.prototype.matchAll ( regexp ) + [...] + 2. If regexp is neither undefined nor null, then + a. Let matcher be ? GetMethod(regexp, @@matchAll). +features: [Symbol.matchAll, String.prototype.matchAll] +---*/ + +var regexp = /./; +regexp[Symbol.matchAll] = function() { + throw new Test262Error(); +}; + +assert.throws(Test262Error, function() { + ''.matchAll(regexp); +}); diff --git a/test/built-ins/String/prototype/matchAll/regexp-prototype-get-matchAll-throws.js b/test/built-ins/String/prototype/matchAll/regexp-prototype-get-matchAll-throws.js new file mode 100644 index 00000000000..ccafad46a52 --- /dev/null +++ b/test/built-ins/String/prototype/matchAll/regexp-prototype-get-matchAll-throws.js @@ -0,0 +1,22 @@ +// Copyright (C) 2018 Peter Wong. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: Re-throws errors thrown while accessing RegExp's @@matchAll property +info: | + String.prototype.matchAll ( regexp ) + [...] + 2. If regexp is neither undefined nor null, then + a. Let matcher be ? GetMethod(regexp, @@matchAll). +features: [Symbol.matchAll] +---*/ + +Object.defineProperty(RegExp.prototype, Symbol.matchAll, { + get() { + throw new Test262Error(); + } +}); + +assert.throws(Test262Error, function() { + ''.matchAll(/./); +}); diff --git a/test/built-ins/String/prototype/matchAll/regexp-prototype-has-no-matchAll.js b/test/built-ins/String/prototype/matchAll/regexp-prototype-has-no-matchAll.js new file mode 100644 index 00000000000..0aeb021a9e3 --- /dev/null +++ b/test/built-ins/String/prototype/matchAll/regexp-prototype-has-no-matchAll.js @@ -0,0 +1,24 @@ +// Copyright (C) 2018 Peter Wong. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: Behavior when @@matchAll is removed from RegExp's prototype +info: | + String.prototype.matchAll ( regexp ) + 1. Let O be ? RequireObjectCoercible(this value). + 2. If regexp is neither undefined nor null, then + a. Let matcher be ? GetMethod(regexp, @@matchAll). + b. If matcher is not undefined, then + [...] + 3. Return ? MatchAllIterator(regexp, O). +features: [Symbol.matchAll, String.prototype.matchAll] +includes: [compareArray.js, compareIterator.js, regExpUtils.js] +---*/ + +delete RegExp.prototype[Symbol.matchAll]; +var str = 'a*b'; + +assert.compareIterator(str.matchAll(/\w/g), [ + matchValidator(['a'], 0, str), + matchValidator(['b'], 2, str) +]); diff --git a/test/built-ins/String/prototype/matchAll/regexp-prototype-matchAll-invocation.js b/test/built-ins/String/prototype/matchAll/regexp-prototype-matchAll-invocation.js new file mode 100644 index 00000000000..2aec69141ce --- /dev/null +++ b/test/built-ins/String/prototype/matchAll/regexp-prototype-matchAll-invocation.js @@ -0,0 +1,36 @@ +// Copyright (C) 2018 Jordan Harband. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: Behavior when invoking of @@matchAll +info: | + String.prototype.matchAll ( regexp ) + [...] + 2. If regexp is neither undefined nor null, then + a. Let matcher be ? GetMethod(regexp, @@matchAll). + b. If matcher is not undefined, then + i. Return ? Call(matcher, regexp, « O »). +features: [Symbol.matchAll] +---*/ + +var obj = {}; +var returnVal = {}; +var callCount = 0; +var thisVal, args; + +RegExp.prototype[Symbol.matchAll] = function() { + callCount++; + thisVal = this; + args = arguments; + return returnVal; +}; + +var regexp = /./; +var str = ''; + +assert.sameValue(str.matchAll(regexp), returnVal); +assert.sameValue(callCount, 1, 'Invokes the method exactly once'); +assert.sameValue(thisVal, regexp); +assert.notSameValue(args, undefined); +assert.sameValue(args.length, 1); +assert.sameValue(args[0], str); diff --git a/test/built-ins/String/prototype/matchAll/regexp-prototype-matchAll-throws.js b/test/built-ins/String/prototype/matchAll/regexp-prototype-matchAll-throws.js new file mode 100644 index 00000000000..c2be2331a3e --- /dev/null +++ b/test/built-ins/String/prototype/matchAll/regexp-prototype-matchAll-throws.js @@ -0,0 +1,22 @@ +// Copyright (C) 2018 Peter Wong. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: Re-throws errors when calling @@matchAll +info: | + String.prototype.matchAll ( regexp ) + [...] + 2. If regexp is neither undefined nor null, then + a. Let matcher be ? GetMethod(regexp, @@matchAll). + b. If matcher is not undefined, then + i. Return ? Call(matcher, regexp, « O »). +features: [Symbol.matchAll] +---*/ + +RegExp.prototype[Symbol.matchAll] = function() { + throw new Test262Error(); +}; + +assert.throws(Test262Error, function() { + ''.matchAll(/./); +}); diff --git a/test/built-ins/String/prototype/matchAll/this-val-non-obj-coercible.js b/test/built-ins/String/prototype/matchAll/this-val-non-obj-coercible.js index 2189df4b65b..9cfd7705de6 100644 --- a/test/built-ins/String/prototype/matchAll/this-val-non-obj-coercible.js +++ b/test/built-ins/String/prototype/matchAll/this-val-non-obj-coercible.js @@ -1,12 +1,12 @@ // Copyright (C) 2018 Jordan Harband. All rights reserved. // This code is governed by the BSD license found in the LICENSE file. /*--- +esid: pending description: The `this` value cannot be coerced into an object info: | + String.prototype.matchAll ( regexp ) 1. Let O be RequireObjectCoercible(this value). - 2. Let S be ToString(O). - 3. ReturnIfAbrupt(S). -features: [Symbol.iterator] +features: [String.prototype.matchAll] ---*/ var matchAll = String.prototype.matchAll; diff --git a/test/built-ins/Symbol/matchAll/cross-realm.js b/test/built-ins/Symbol/matchAll/cross-realm.js new file mode 100644 index 00000000000..e6d2f9cebf1 --- /dev/null +++ b/test/built-ins/Symbol/matchAll/cross-realm.js @@ -0,0 +1,14 @@ +// Copyright (C) 2018 Peter Wong. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: Value shared by all realms +info: | + Unless otherwise specified, well-known symbols values are shared by all + realms. +features: [cross-realm, Symbol.matchAll] +---*/ + +var OSymbol = $262.createRealm().global.Symbol; + +assert.sameValue(Symbol.matchAll, OSymbol.matchAll); diff --git a/test/built-ins/Symbol/matchAll/prop-desc.js b/test/built-ins/Symbol/matchAll/prop-desc.js new file mode 100644 index 00000000000..0856b4f46b6 --- /dev/null +++ b/test/built-ins/Symbol/matchAll/prop-desc.js @@ -0,0 +1,16 @@ +// Copyright (C) 2018 Peter Wong. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: pending +description: `Symbol.matchAll` property descriptor +info: | + This property has the attributes { [[Writable]]: false, [[Enumerable]]: + false, [[Configurable]]: false }. +includes: [propertyHelper.js] +features: [Symbol.match] +---*/ + +assert.sameValue(typeof Symbol.matchAll, 'symbol'); +verifyNotEnumerable(Symbol, 'matchAll'); +verifyNotWritable(Symbol, 'matchAll'); +verifyNotConfigurable(Symbol, 'matchAll');