From 6a87be1e9e9a2f70bdcb7881e5bfee2b06571e47 Mon Sep 17 00:00:00 2001 From: peterwmwong Date: Sat, 17 Mar 2018 22:48:31 -0500 Subject: [PATCH] Fleshed out tests for String.p.matchAll, RegExp.p[@@matchAll], and %RegExpStringIteratorPrototype% Tests were updated and assuming https://github.com/tc39/proposal-string-matchall/pull/33 will be merged. --- .../get-species-constructor-err.js | 22 ------- .../internal-regexp-lastindex-not-zero.js | 40 +++++++++++++ .../isregexp-internal-regexp-is-false.js | 36 +++++++++++ .../isregexp-internal-regexp-throws.js | 36 +++++++++++ .../Symbol.matchAll/isregexp-this-throws.js | 26 ++++++++ .../prototype/Symbol.matchAll/length.js | 17 ++++-- .../RegExp/prototype/Symbol.matchAll/name.js | 11 +++- .../prototype/Symbol.matchAll/prop-desc.js | 7 ++- .../regexpcreate-this-throws.js | 29 +++++++++ ...cies-constructor-get-constructor-throws.js | 32 ++++++++++ .../species-constructor-get-species-throws.js | 31 ++++++++++ ...pecies-constructor-is-not-object-throws.js | 41 +++++++++++++ .../species-constructor-is-undefined.js | 43 +++++++++++++ ...-constructor-species-is-not-constructor.js | 45 ++++++++++++++ ...onstructor-species-is-null-or-undefined.js | 53 ++++++++++++++++ .../species-constructor-species-throws.js | 29 +++++++++ .../Symbol.matchAll/species-constructor.js | 53 ++++++++++++++++ .../species-regexp-get-global-throws.js | 33 ++++++++++ .../species-regexp-get-unicode-throws.js | 33 ++++++++++ ...oerce-arg.js => string-tostring-throws.js} | 22 +++---- .../Symbol.matchAll/string-tostring.js | 40 +++++++++++++ .../Symbol.matchAll/this-get-flags-throws.js | 28 +++++++++ .../Symbol.matchAll/this-get-flags.js | 41 +++++++++++++ .../Symbol.matchAll/this-lastindex-cached.js | 47 +++++++++++++++ .../Symbol.matchAll/this-not-object-throws.js | 31 ++++++++++ .../this-tolength-lastindex-throws.js | 28 +++++++++ .../this-tostring-flags-throws.js | 33 ++++++++++ .../Symbol.matchAll/this-tostring-flags.js | 45 ++++++++++++++ .../Symbol.matchAll/this-val-non-obj.js | 36 ----------- .../Symbol.matchAll/this-val-non-regexp.js | 22 ------- .../Symbol.toStringTag.js | 22 +++++++ .../RegExpStringIteratorPrototype/ancestry.js | 16 +++++ .../next/custom-regexpexec-call-throws.js | 33 ++++++++++ .../next/custom-regexpexec-get-throws.js | 33 ++++++++++ .../custom-regexpexec-match-get-0-throws.js | 33 ++++++++++ ...-regexpexec-match-get-0-tostring-throws.js | 34 +++++++++++ .../custom-regexpexec-match-get-0-tostring.js | 53 ++++++++++++++++ .../next/custom-regexpexec-not-callable.js | 57 ++++++++++++++++++ .../next/custom-regexpexec.js | 60 +++++++++++++++++++ .../next/length.js | 32 ++++++++++ .../next/name.js | 30 ++++++++++ .../next/next-iteration-global.js | 50 ++++++++++++++++ .../next/next-iteration.js | 42 +++++++++++++ .../next/next-missing-internal-slots.js | 21 +++++++ .../next/prop-desc.js | 24 ++++++++ .../next/regexp-tolength-lastindex-throws.js | 39 ++++++++++++ .../next/this-is-not-object-throws.js | 34 +++++++++++ .../matchAll/cstm-matcher-get-err.js | 26 -------- .../matchAll/invoke-builtin-matchall.js | 43 ------------- .../String/prototype/matchAll/length.js | 20 ++++--- .../String/prototype/matchAll/name.js | 33 +++++----- .../String/prototype/matchAll/prop-desc.js | 10 +++- .../matchAll/regexp-get-matchAll-throws.js | 21 +++++++ .../prototype/matchAll/regexp-is-null.js | 34 +++++++++++ .../prototype/matchAll/regexp-is-undefined.js | 39 ++++++++++++ ...ation.js => regexp-matchAll-invocation.js} | 25 ++++---- .../matchAll/regexp-matchAll-throws.js | 25 ++++++++ .../regexp-prototype-get-matchAll-throws.js | 29 +++++++++ .../regexp-prototype-has-no-matchAll.js | 42 +++++++++++++ .../regexp-prototype-matchAll-invocation.js | 41 +++++++++++++ .../regexp-prototype-matchAll-throws.js | 27 +++++++++ .../matchAll/this-val-non-obj-coercible.js | 12 ++-- 62 files changed, 1815 insertions(+), 215 deletions(-) delete mode 100644 test/built-ins/RegExp/prototype/Symbol.matchAll/get-species-constructor-err.js create mode 100644 test/built-ins/RegExp/prototype/Symbol.matchAll/internal-regexp-lastindex-not-zero.js create mode 100644 test/built-ins/RegExp/prototype/Symbol.matchAll/isregexp-internal-regexp-is-false.js create mode 100644 test/built-ins/RegExp/prototype/Symbol.matchAll/isregexp-internal-regexp-throws.js create mode 100644 test/built-ins/RegExp/prototype/Symbol.matchAll/isregexp-this-throws.js create mode 100644 test/built-ins/RegExp/prototype/Symbol.matchAll/regexpcreate-this-throws.js create mode 100644 test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor-get-constructor-throws.js create mode 100644 test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor-get-species-throws.js create mode 100644 test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor-is-not-object-throws.js create mode 100644 test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor-is-undefined.js create mode 100644 test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor-species-is-not-constructor.js create mode 100644 test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor-species-is-null-or-undefined.js create mode 100644 test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor-species-throws.js create mode 100644 test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor.js create mode 100644 test/built-ins/RegExp/prototype/Symbol.matchAll/species-regexp-get-global-throws.js create mode 100644 test/built-ins/RegExp/prototype/Symbol.matchAll/species-regexp-get-unicode-throws.js rename test/built-ins/RegExp/prototype/Symbol.matchAll/{coerce-arg.js => string-tostring-throws.js} (57%) create mode 100644 test/built-ins/RegExp/prototype/Symbol.matchAll/string-tostring.js create mode 100644 test/built-ins/RegExp/prototype/Symbol.matchAll/this-get-flags-throws.js create mode 100644 test/built-ins/RegExp/prototype/Symbol.matchAll/this-get-flags.js create mode 100644 test/built-ins/RegExp/prototype/Symbol.matchAll/this-lastindex-cached.js create mode 100644 test/built-ins/RegExp/prototype/Symbol.matchAll/this-not-object-throws.js create mode 100644 test/built-ins/RegExp/prototype/Symbol.matchAll/this-tolength-lastindex-throws.js create mode 100644 test/built-ins/RegExp/prototype/Symbol.matchAll/this-tostring-flags-throws.js create mode 100644 test/built-ins/RegExp/prototype/Symbol.matchAll/this-tostring-flags.js delete mode 100644 test/built-ins/RegExp/prototype/Symbol.matchAll/this-val-non-obj.js delete mode 100644 test/built-ins/RegExp/prototype/Symbol.matchAll/this-val-non-regexp.js create mode 100644 test/built-ins/RegExpStringIteratorPrototype/Symbol.toStringTag.js create mode 100644 test/built-ins/RegExpStringIteratorPrototype/ancestry.js create mode 100644 test/built-ins/RegExpStringIteratorPrototype/next/custom-regexpexec-call-throws.js create mode 100644 test/built-ins/RegExpStringIteratorPrototype/next/custom-regexpexec-get-throws.js create mode 100644 test/built-ins/RegExpStringIteratorPrototype/next/custom-regexpexec-match-get-0-throws.js create mode 100644 test/built-ins/RegExpStringIteratorPrototype/next/custom-regexpexec-match-get-0-tostring-throws.js create mode 100644 test/built-ins/RegExpStringIteratorPrototype/next/custom-regexpexec-match-get-0-tostring.js create mode 100644 test/built-ins/RegExpStringIteratorPrototype/next/custom-regexpexec-not-callable.js create mode 100644 test/built-ins/RegExpStringIteratorPrototype/next/custom-regexpexec.js create mode 100644 test/built-ins/RegExpStringIteratorPrototype/next/length.js create mode 100644 test/built-ins/RegExpStringIteratorPrototype/next/name.js create mode 100644 test/built-ins/RegExpStringIteratorPrototype/next/next-iteration-global.js create mode 100644 test/built-ins/RegExpStringIteratorPrototype/next/next-iteration.js create mode 100644 test/built-ins/RegExpStringIteratorPrototype/next/next-missing-internal-slots.js create mode 100644 test/built-ins/RegExpStringIteratorPrototype/next/prop-desc.js create mode 100644 test/built-ins/RegExpStringIteratorPrototype/next/regexp-tolength-lastindex-throws.js create mode 100644 test/built-ins/RegExpStringIteratorPrototype/next/this-is-not-object-throws.js delete mode 100644 test/built-ins/String/prototype/matchAll/cstm-matcher-get-err.js delete mode 100644 test/built-ins/String/prototype/matchAll/invoke-builtin-matchall.js create mode 100644 test/built-ins/String/prototype/matchAll/regexp-get-matchAll-throws.js create mode 100644 test/built-ins/String/prototype/matchAll/regexp-is-null.js create mode 100644 test/built-ins/String/prototype/matchAll/regexp-is-undefined.js rename test/built-ins/String/prototype/matchAll/{cstm-matcher-invocation.js => regexp-matchAll-invocation.js} (58%) create mode 100644 test/built-ins/String/prototype/matchAll/regexp-matchAll-throws.js create mode 100644 test/built-ins/String/prototype/matchAll/regexp-prototype-get-matchAll-throws.js create mode 100644 test/built-ins/String/prototype/matchAll/regexp-prototype-has-no-matchAll.js create mode 100644 test/built-ins/String/prototype/matchAll/regexp-prototype-matchAll-invocation.js create mode 100644 test/built-ins/String/prototype/matchAll/regexp-prototype-matchAll-throws.js 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..34468c371dc --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/internal-regexp-lastindex-not-zero.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: | + 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] +---*/ + +const originalMatch = RegExp.prototype[Symbol.match]; +Object.defineProperty(RegExp.prototype, Symbol.match, { + get() { + this.lastIndex = 1; + return true; + } +}); + +try { + assert.throws(TypeError, () => { + RegExp.prototype[Symbol.matchAll].call({}, ''); + }); +} finally { + Object.defineProperty(RegExp.prototype, Symbol.match, { + value: originalMatch + }); +} 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..aa9f2b6bbe6 --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/isregexp-internal-regexp-is-false.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: 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] +---*/ + +const originalMatch = RegExp.prototype[Symbol.match]; +Object.defineProperty(RegExp.prototype, Symbol.match, { + get() { + return false; + } +}); + +try { + assert.throws(TypeError, () => { + RegExp.prototype[Symbol.matchAll].call({}, ''); + }); +} finally { + Object.defineProperty(RegExp.prototype, Symbol.match, { + value: originalMatch + }); +} 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..a718dcc39f4 --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/isregexp-internal-regexp-throws.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: Re-throw errors from during retrieval of @@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] +---*/ + +const originalMatch = RegExp.prototype[Symbol.match]; +Object.defineProperty(RegExp.prototype, Symbol.match, { + get() { + throw new Test262Error(); + } +}); + +try { + assert.throws(Test262Error, () => { + RegExp.prototype[Symbol.matchAll].call({}, ''); + }); +} finally { + Object.defineProperty(RegExp.prototype, Symbol.match, { + value: originalMatch + }); +} 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..bef98262aaa --- /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-throw errors from regexp's @@match getter +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] +---*/ + +const obj = { + get [Symbol.match]() { + throw new Test262Error(); + } +}; + +assert.throws(Test262Error, () => { + 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..fc6157ee834 --- /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-throw errors from creating 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] +---*/ + +const 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..9d5a5991c29 --- /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-throw errors from RegExp's constructor getter +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] +---*/ + +const regexp = /./; +Object.defineProperty(regexp, 'constructor', { + get(){ + throw new Test262Error(); + } +}); + +assert.throws(Test262Error, () => { + 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..f9ca9370606 --- /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-throw errors from during retrieval 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] +---*/ + +const regexp = /./; +regexp.constructor = { + get [Symbol.species]() { + throw new Test262Error(); + } +}; + +assert.throws(Test262Error, () => { + 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..c18bbddb433 --- /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] +---*/ + +const 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..fbd567f1e02 --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor-is-undefined.js @@ -0,0 +1,43 @@ +// 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] +---*/ + +const regexp = /\w/g; +regexp.constructor = undefined; +const str = 'a*b'; +const iter = regexp[Symbol.matchAll](str); + +let { value, done } = iter.next(); +assert.compareArray(value, ['a']); +assert.sameValue(value.index, 0); +assert.sameValue(value.input, str); +assert(!done); + +({ value, done } = iter.next()); +assert.compareArray(value, ['b']); +assert.sameValue(value.index, 2); +assert.sameValue(value.input, str); +assert(!done); + +({ value, done } = iter.next()); +assert.sameValue(value, undefined); +assert(done); 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..09a5b40125f --- /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] +---*/ + +const regexp = /./; +const speciesConstructor = {}; +regexp.constructor = speciesConstructor; + +const callMatchAll = () => { + 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..cdeb4e68706 --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor-species-is-null-or-undefined.js @@ -0,0 +1,53 @@ +// 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] +---*/ + +function TestWithConstructor(ctor) { + const regexp = /\w/g; + regexp.constructor = { + [Symbol.species]: ctor + }; + const str = 'a*b'; + const iter = regexp[Symbol.matchAll](str); + + let { value, done } = iter.next(); + assert.compareArray(value, ['a']); + assert.sameValue(value.index, 0); + assert.sameValue(value.input, str); + assert(!done); + + ({ value, done } = iter.next()); + assert.compareArray(value, ['b']); + assert.sameValue(value.index, 2); + assert.sameValue(value.input, str); + assert(!done); + + ({ value, done } = iter.next()); + assert.sameValue(value, undefined); + assert(done); +} + +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..768fc2fb57f --- /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-throw errors from calling regexp's 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] +---*/ + +const regexp = /./; +regexp.constructor = { + [Symbol.species]: function() { + throw new Test262Error(); + } +}; + +assert.throws(Test262Error, () => { + 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..1c7205f18eb --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor.js @@ -0,0 +1,53 @@ +// 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] +---*/ + +let callCount = 0; +let callArgs; +const regexp = /\d/u; +regexp.constructor = { + [Symbol.species]: function(){ + callCount++;callArgs + callArgs = arguments; + return /\w/g; + } +}; +const str = 'a*b'; +const iter = regexp[Symbol.matchAll](str); + +assert.sameValue(callCount, 1);callArgs +assert.sameValue(callArgs.length, 2); +assert.sameValue(callArgs[0], regexp); +assert.sameValue(callArgs[1], 'u'); + +let { value, done } = iter.next(); +assert.compareArray(value, ['a']); +assert.sameValue(value.index, 0); +assert.sameValue(value.input, str); +assert(!done); + +({ value, done } = iter.next()); +assert.compareArray(value, ['b']); +assert.sameValue(value.index, 2); +assert.sameValue(value.input, str); +assert(!done); + +({ value, done } = iter.next()); +assert.sameValue(value, undefined); +assert(done); 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..8912c8dd004 --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/species-regexp-get-global-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-throw errors when 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] +---*/ + +const regexp = /./; +regexp.constructor = { + [Symbol.species]: function() { + return Object.defineProperty(/./, 'global', { + get() { + throw new Test262Error(); + } + }); + } +}; + +assert.throws(Test262Error, () => { + 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..c09c3434821 --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/species-regexp-get-unicode-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-throw errors when 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] +---*/ + +const regexp = /./; +regexp.constructor = { + [Symbol.species]: function() { + return Object.defineProperty(/./, 'unicode', { + get() { + throw new Test262Error(); + } + }); + } +}; + +assert.throws(Test262Error, () => { + 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 57% 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..457786cebc2 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() { +const obj = { + 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, () => { /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..29959ded128 --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/string-tostring.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: 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] +---*/ + +const str = 'a*b'; +const obj = { + toString() { + return str; + } +}; +const regexp = /\w/g; +const iter = regexp[Symbol.matchAll](obj); + +let { value, done } = iter.next(); +assert.compareArray(value, ['a']); +assert.sameValue(value.index, 0); +assert.sameValue(value.input, str); +assert(!done); + +({ value, done } = iter.next()); +assert.compareArray(value, ['b']); +assert.sameValue(value.index, 2); +assert.sameValue(value.input, str); +assert(!done); + +({ value, done } = iter.next()); +assert.sameValue(value, undefined); +assert(done); 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..3641cd54c5d --- /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-throw errors from RegExp's flags getter +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] +---*/ + +const regexp = /./; +Object.defineProperty(regexp, 'flags', { + get() { + throw new Test262Error(); + } +}); + +assert.throws(Test262Error, () => { + 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..734ab201391 --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/this-get-flags.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: 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] +---*/ + +const regexp = /\w/; +Object.defineProperty(regexp, 'flags', { + value: 'g' +}); +const str = 'a*b'; +const iter = regexp[Symbol.matchAll](str); + +let { value, done } = iter.next(); +assert.compareArray(value, ['a']); +assert.sameValue(value.index, 0); +assert.sameValue(value.input, str); +assert(!done); + +({ value, done } = iter.next()); +assert.compareArray(value, ['b']); +assert.sameValue(value.index, 2); +assert.sameValue(value.input, str); +assert(!done); + +({ value, done } = iter.next()); +assert.sameValue(value, undefined); +assert(done); 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..8916fcc1b25 --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/this-lastindex-cached.js @@ -0,0 +1,47 @@ +// 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] +---*/ + +const regexp = /./g; +regexp.lastIndex = { + valueOf() { + return 2; + } +}; +const str = 'abcd'; +const iter = regexp[Symbol.matchAll](str); + +// Verify lastIndex is cached at the time of calling @@matchAll +regexp.lastIndex = 0; + +let { value, done } = iter.next(); +assert.compareArray(value, ['c']); +assert.sameValue(value.index, 2); +assert.sameValue(value.input, str); +assert(!done); + +({ value, done } = iter.next()); +assert.compareArray(value, ['d']); +assert.sameValue(value.index, 3); +assert.sameValue(value.input, str); +assert(!done); + +({ value, done } = iter.next()); +assert.sameValue(value, undefined); +assert(done); 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..ea5dfd5083d --- /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] +---*/ + +let thisValue; +const callMatchAll = () => { + 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..9af29ebd042 --- /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-throw errors from 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] +---*/ + +const regexp = /./; +regexp.lastIndex = { + valueOf() { + throw new Test262Error(); + } +}; + +assert.throws(Test262Error, () => { + 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..86e05e96dd1 --- /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-throw errors from RegExp's flags getter +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] +---*/ + +const regexp = /\w/; +Object.defineProperty(regexp, 'flags', { + value: { + valueOf() { + ERROR('valueOf Should not be called'); + }, + toString() { + throw new Test262Error(); + } + } +}); + +assert.throws(Test262Error, () => { + 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..8da49c2cdb4 --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/this-tostring-flags.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: 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] +---*/ + +const regexp = /\w/; +Object.defineProperty(regexp, 'flags', { + value: { + toString() { + return 'g'; + } + } +}); +const str = 'a*b'; +const iter = regexp[Symbol.matchAll](str); + +let { value, done } = iter.next(); +assert.compareArray(value, ['a']); +assert.sameValue(value.index, 0); +assert.sameValue(value.input, str); +assert(!done); + +({ value, done } = iter.next()); +assert.compareArray(value, ['b']); +assert.sameValue(value.index, 2); +assert.sameValue(value.input, str); +assert(!done); + +({ value, done } = iter.next()); +assert.sameValue(value, undefined); +assert(done); 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..ee5aba3f73a --- /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] +---*/ + +const 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..8d30bfe06ed --- /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] +---*/ + +const RegExpStringIteratorProto = Object.getPrototypeOf(/./[Symbol.matchAll]('a')); +const 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..102ae3a0a5d --- /dev/null +++ b/test/built-ins/RegExpStringIteratorPrototype/next/custom-regexpexec-call-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 error thrown from calling RegExp's 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] +---*/ + +const originalExec = RegExp.prototype.exec; +const iter = /./[Symbol.matchAll](''); + +RegExp.prototype.exec = () => { + throw new Test262Error(); +}; + +try { + assert.throws(Test262Error, () => { + iter.next(); + }); +} finally { + RegExp.prototype.exec = originalExec; +} 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..b404cfd2ad8 --- /dev/null +++ b/test/built-ins/RegExpStringIteratorPrototype/next/custom-regexpexec-get-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 error from RegExp's exec getter +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] +---*/ + +const originalExec = RegExp.prototype.exec; +const iter = /./[Symbol.matchAll](''); + +Object.defineProperty(RegExp.prototype, 'exec', { + get() { + throw new Test262Error(); + } +}); + +try { + assert.throws(Test262Error, () => { + iter.next(); + }); +} finally { + RegExp.prototype.exec = originalExec; +} 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..53469bf0dfd --- /dev/null +++ b/test/built-ins/RegExpStringIteratorPrototype/next/custom-regexpexec-match-get-0-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 error thrown when 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] +---*/ + +const originalExec = RegExp.prototype.exec; +const iter = /./g[Symbol.matchAll](''); + +RegExp.prototype.exec = () => ({ + get '0'() { + throw new Test262Error(); + } +}); + +try { + assert.throws(Test262Error, () => { + iter.next(); + }); +} finally { + RegExp.prototype.exec = originalExec; +} 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..36d303ef72e --- /dev/null +++ b/test/built-ins/RegExpStringIteratorPrototype/next/custom-regexpexec-match-get-0-tostring-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 error from calling toString on 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] +---*/ + +const originalExec = RegExp.prototype.exec; +const iter = /./g[Symbol.matchAll](''); + +RegExp.prototype.exec = () => [{ + toString() { + throw new Test262Error(); + } +}]; + +try { + assert.throws(Test262Error, () => { + iter.next(); + }); +} finally { + RegExp.prototype.exec = originalExec; +} + 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..3bf07bb81e2 --- /dev/null +++ b/test/built-ins/RegExpStringIteratorPrototype/next/custom-regexpexec-match-get-0-tostring.js @@ -0,0 +1,53 @@ +// 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] +---*/ + +const originalExec = RegExp.prototype.exec; +const iter = /./g[Symbol.matchAll](''); + +try { + const execResult = { + get '0'() { + return { + toString() { return ''; } + }; + } + }; + + let internalRegExp; + RegExp.prototype.exec = function () { + internalRegExp = this; + return execResult; + }; + + let { value, done } = iter.next(); + assert.sameValue(internalRegExp.lastIndex, 1); + assert.sameValue(value, execResult); + assert(!done); + + + ({ value, done } = iter.next()); + assert.sameValue(internalRegExp.lastIndex, 2); + assert.sameValue(value, execResult); + assert(!done); +} finally { + RegExp.prototype.exec = originalExec; +} 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..906e77b02d6 --- /dev/null +++ b/test/built-ins/RegExpStringIteratorPrototype/next/custom-regexpexec-not-callable.js @@ -0,0 +1,57 @@ +// 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] +---*/ + +const originalExec = RegExp.prototype.exec; + +function TestWithRegExpExec(exec) { + RegExp.prototype.exec = exec; + + const regexp = /\w/g; + const str = 'a*b'; + const iter = regexp[Symbol.matchAll](str); + + let { value, done } = iter.next(); + assert.compareArray(value, ['a']); + assert.sameValue(value.index, 0); + assert.sameValue(value.input, str); + assert(!done); + + ({ value, done } = iter.next()); + assert.compareArray(value, ['b']); + assert.sameValue(value.index, 2); + assert.sameValue(value.input, str); + assert(!done); + + ({ value, done } = iter.next()); + assert.sameValue(value, undefined); + assert(done); +} + +try { + TestWithRegExpExec(undefined); + TestWithRegExpExec(null); + TestWithRegExpExec(5); + TestWithRegExpExec(true); + TestWithRegExpExec(Symbol()); +} finally { + RegExp.prototype.exec = originalExec; +} 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..02205c93d95 --- /dev/null +++ b/test/built-ins/RegExpStringIteratorPrototype/next/custom-regexpexec.js @@ -0,0 +1,60 @@ +// 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] +---*/ + +const originalExec = RegExp.prototype.exec; +const regexp = /./g; +const str = 'abc'; +const iter = regexp[Symbol.matchAll](str); + +let callArgs, callCount; +const callNextWithExecReturnValue = returnValue => { + callArgs = undefined; + callCount = 0; + + RegExp.prototype.exec = function() { + callArgs = arguments; + callCount++; + return returnValue; + } + + return iter.next(); +} + +try { + const firstExecReturnValue = ['ab']; + let { value, done } = callNextWithExecReturnValue(firstExecReturnValue); + assert.sameValue(value, firstExecReturnValue); + assert(!done); + + assert.sameValue(callArgs.length, 1); + assert.sameValue(callArgs[0], str); + assert.sameValue(callCount, 1); + + ({ value, done } = callNextWithExecReturnValue(null)); + assert.sameValue(value, undefined); + assert(done); + + assert.sameValue(callArgs.length, 1); + assert.sameValue(callArgs[0], str); + assert.sameValue(callCount, 1); +} finally { + RegExp.prototype.exec = originalExec; +} diff --git a/test/built-ins/RegExpStringIteratorPrototype/next/length.js b/test/built-ins/RegExpStringIteratorPrototype/next/length.js new file mode 100644 index 00000000000..b53fb3f64c0 --- /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] +---*/ + +const 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..aca53d44d89 --- /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] +---*/ + +const 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..f2af278243b --- /dev/null +++ b/test/built-ins/RegExpStringIteratorPrototype/next/next-iteration-global.js @@ -0,0 +1,50 @@ +// 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] +---*/ + +const regexp = /\w/g; +const str = 'a*b'; +const iter = regexp[Symbol.matchAll](str); + +let { value, done } = iter.next(); +assert.compareArray(value, ['a']); +assert.sameValue(value.index, 0); +assert.sameValue(value.input, str); +assert(!done); + +({ value, done } = iter.next()); +assert.compareArray(value, ['b']); +assert.sameValue(value.index, 2); +assert.sameValue(value.input, str); +assert(!done); + +({ value, done } = iter.next()); +assert.sameValue(value, undefined); +assert(done); + +// Verifies %RegExpStringIteratorPrototype%.next() step 4 +({ value, done } = iter.next()); +assert.sameValue(value, undefined); +assert(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..5047b6b6093 --- /dev/null +++ b/test/built-ins/RegExpStringIteratorPrototype/next/next-iteration.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: 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] +---*/ + +const regexp = /\w/; +const str = 'a*b'; +const iter = regexp[Symbol.matchAll](str); + +let { value, done } = iter.next(); +assert.compareArray(value, ['a']); +assert.sameValue(value.index, 0); +assert.sameValue(value.input, str); +assert(!done); + +({ value, done } = iter.next()); +assert.sameValue(value, undefined); +assert(done); + +// Verifies %RegExpStringIteratorPrototype%.next() step 4 +({ value, done } = iter.next()); +assert.sameValue(value, undefined); +assert(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..f5231599ac5 --- /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] +---*/ + +const iterator = /./[Symbol.matchAll](''); +const object = Object.create(iterator); + +assert.throws(TypeError, () => { + 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..8cbc18fdd06 --- /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] +---*/ + +const 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..48a2c3c2999 --- /dev/null +++ b/test/built-ins/RegExpStringIteratorPrototype/next/regexp-tolength-lastindex-throws.js @@ -0,0 +1,39 @@ +// 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 error from calling ToLength on the iterating regexp's lastIndex +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] +---*/ + +const originalExec = RegExp.prototype.exec; +const iter = /./g[Symbol.matchAll](''); + +RegExp.prototype.exec = function() { + this.lastIndex = { + valueOf() { + throw new Test262Error(); + } + }; + return ['']; +}; + +try { + assert.throws(Test262Error, () => { + iter.next(); + }); +} finally { + RegExp.prototype.exec = originalExec; +} 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..a8c71b6971c --- /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] +---*/ + +const RegExpStringIteratorProto = Object.getPrototypeOf(/./[Symbol.matchAll]('')); + +let thisValue; +const callNext = () => { + 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..ae8fbf79d0b --- /dev/null +++ b/test/built-ins/String/prototype/matchAll/regexp-get-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: Behavior when error is thrown accessing @@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, String.prototype.matchAll] +---*/ + +const regexp = /./; +regexp[Symbol.matchAll] = () => { + throw new Test262Error(); +}; + +assert.throws(Test262Error, () => { + ''.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..8f8170cb324 --- /dev/null +++ b/test/built-ins/String/prototype/matchAll/regexp-is-null.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: 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] +---*/ + +const str = '-null-' +const iter = str.matchAll(null); + +let { value, done } = iter.next(); +assert.compareArray(value, ['null']); +assert.sameValue(value.index, 1); +assert.sameValue(value.input, '-null-'); +assert(!done); + +({ value, done } = iter.next()); +assert.sameValue(value, undefined); +assert(done); 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..9958a877fed --- /dev/null +++ b/test/built-ins/String/prototype/matchAll/regexp-is-undefined.js @@ -0,0 +1,39 @@ +// 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] +---*/ + +const str = 'a'; +const iter = str.matchAll(undefined); + +let { value, done } = iter.next(); +assert.compareArray(value, ['']); +assert.sameValue(value.index, 0); +assert.sameValue(value.input, str); +assert(!done); + +({ value, done } = iter.next()); +assert.compareArray(value, ['']); +assert.sameValue(value.index, 1); +assert.sameValue(value.input, str); + +({ value, done } = iter.next()); +assert.sameValue(value, undefined); +assert(done); 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 58% 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..4fe848e3619 100644 --- a/test/built-ins/String/prototype/matchAll/cstm-matcher-invocation.js +++ b/test/built-ins/String/prototype/matchAll/regexp-matchAll-invocation.js @@ -1,30 +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: 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 = {}; -var returnVal = {}; -var callCount = 0; -var thisVal, args; +const obj = {}; +const returnVal = {}; +let callCount = 0; +let 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; }; -var str = ''; +const str = ''; assert.sameValue(str.matchAll(obj), returnVal); assert.sameValue(callCount, 1, 'Invokes the method exactly once'); 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..6fc8a042fc7 --- /dev/null +++ b/test/built-ins/String/prototype/matchAll/regexp-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: Behavior when error is thrown invoking @@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] +---*/ + +const regexp = /./; +Object.defineProperty(regexp, Symbol.matchAll, { + get() { + throw new Test262Error(); + } +});; + +assert.throws(Test262Error, () => { + ''.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..d111914371b --- /dev/null +++ b/test/built-ins/String/prototype/matchAll/regexp-prototype-get-matchAll-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: Behavior when error is thrown accessing @@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] +---*/ + +const originalMatchAll = RegExp.prototype[Symbol.matchAll]; +Object.defineProperty(RegExp.prototype, Symbol.matchAll, { + get() { + throw new Test262Error(); + } +}); + +try { + assert.throws(Test262Error, () => { + ''.matchAll(/./); + }); +} finally { + Object.defineProperty(RegExp.prototype, Symbol.matchAll, { + value: originalMatchAll + }); +} 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..e1d86fcb29e --- /dev/null +++ b/test/built-ins/String/prototype/matchAll/regexp-prototype-has-no-matchAll.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: 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] +---*/ + +const regexp = /\w/g; +const originalMatchAll = RegExp.prototype[Symbol.matchAll]; +delete RegExp.prototype[Symbol.matchAll]; +try { + const str = 'a*b'; + const iter = str.matchAll(regexp); + + let { value, done } = iter.next(); + assert.compareArray(value, ['a']); + assert.sameValue(value.index, 0); + assert.sameValue(value.input, str); + assert(!done); + + ({ value, done } = iter.next()); + assert.compareArray(value, ['b']); + assert.sameValue(value.index, 2); + assert.sameValue(value.input, str); + assert(!done); + + ({ value, done } = iter.next()); + assert.sameValue(value, undefined); + assert(done); +} finally { + RegExp.prototype[Symbol.matchAll] = originalMatchAll; +} 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..42bbe080059 --- /dev/null +++ b/test/built-ins/String/prototype/matchAll/regexp-prototype-matchAll-invocation.js @@ -0,0 +1,41 @@ +// 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] +---*/ + +const originalMatch = RegExp.prototype[Symbol.matchAll]; +const obj = {}; +const returnVal = {}; +let callCount = 0; +let thisVal, args; + +RegExp.prototype[Symbol.matchAll] = function() { + callCount++; + thisVal = this; + args = arguments; + return returnVal; +}; + +try { + const regexp = /./; + const 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); +} finally { + RegExp.prototype[Symbol.matchAll] = originalMatch; +} 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..767f3c5a24e --- /dev/null +++ b/test/built-ins/String/prototype/matchAll/regexp-prototype-matchAll-throws.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 error is thrown invoking @@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] +---*/ + +const originalMatch = RegExp.prototype[Symbol.matchAll]; +RegExp.prototype[Symbol.matchAll] = () => { + throw new Test262Error(); +}; + +try { + assert.throws(Test262Error, () => { + ''.matchAll(/./); + }); +} finally { + RegExp.prototype[Symbol.matchAll] = originalMatch; +} 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..3c2e74b4a53 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,22 +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: 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; +const matchAll = String.prototype.matchAll; assert.sameValue(typeof matchAll, 'function'); -assert.throws(TypeError, function() { +assert.throws(TypeError, () => { matchAll.call(undefined); }, 'undefined'); -assert.throws(TypeError, function() { +assert.throws(TypeError, () => { matchAll.call(null); }, 'null');