From e623dd7a1183b04d862baea22a4b133b1635cb95 Mon Sep 17 00:00:00 2001 From: Mathias Bynens Date: Tue, 26 Jul 2022 19:42:06 +0200 Subject: [PATCH] Add manually written tests for RegExp `v` flag proposal (#3614) https://github.com/tc39/proposal-regexp-v-flag Issue: #3496, https://github.com/tc39/proposal-regexp-v-flag/issues/52 Add more tests for the new RegExp `v` flag Add test for combination of `u` and `v` flag --- .../RegExp/prototype/flags/this-val-regexp.js | 13 +++-- .../prototype/unicodeSets/cross-realm.js | 29 +++++++++++ .../RegExp/prototype/unicodeSets/length.js | 34 +++++++++++++ .../RegExp/prototype/unicodeSets/name.js | 27 ++++++++++ .../RegExp/prototype/unicodeSets/prop-desc.js | 29 +++++++++++ .../unicodeSets/this-val-invalid-obj.js | 34 +++++++++++++ .../prototype/unicodeSets/this-val-non-obj.js | 44 ++++++++++++++++ .../unicodeSets/this-val-regexp-prototype.js | 21 ++++++++ .../prototype/unicodeSets/this-val-regexp.js | 51 +++++++++++++++++++ .../unicodeSets/uv-flags-constructor.js | 14 +++++ .../RegExp/prototype/unicodeSets/uv-flags.js | 17 +++++++ 11 files changed, 308 insertions(+), 5 deletions(-) create mode 100644 test/built-ins/RegExp/prototype/unicodeSets/cross-realm.js create mode 100644 test/built-ins/RegExp/prototype/unicodeSets/length.js create mode 100644 test/built-ins/RegExp/prototype/unicodeSets/name.js create mode 100644 test/built-ins/RegExp/prototype/unicodeSets/prop-desc.js create mode 100644 test/built-ins/RegExp/prototype/unicodeSets/this-val-invalid-obj.js create mode 100644 test/built-ins/RegExp/prototype/unicodeSets/this-val-non-obj.js create mode 100644 test/built-ins/RegExp/prototype/unicodeSets/this-val-regexp-prototype.js create mode 100644 test/built-ins/RegExp/prototype/unicodeSets/this-val-regexp.js create mode 100644 test/built-ins/RegExp/prototype/unicodeSets/uv-flags-constructor.js create mode 100644 test/built-ins/RegExp/prototype/unicodeSets/uv-flags.js diff --git a/test/built-ins/RegExp/prototype/flags/this-val-regexp.js b/test/built-ins/RegExp/prototype/flags/this-val-regexp.js index 4f7741726f..dada32d338 100644 --- a/test/built-ins/RegExp/prototype/flags/this-val-regexp.js +++ b/test/built-ins/RegExp/prototype/flags/this-val-regexp.js @@ -17,17 +17,20 @@ info: | 11. If dotAll is true, append "s" as the last code unit of result. 12. Let unicode be ToBoolean(? Get(R, "unicode")). 13. If unicode is true, append "u" as the last code unit of result. - 14. Let sticky be ToBoolean(? Get(R, "sticky")). - 15. If sticky is true, append "y" as the last code unit of result. - 16. Return result. -features: [regexp-dotall, regexp-match-indices] + 14. Let unicodeSets be ! ToBoolean(? Get(R, "unicodeSets")). + 15. If unicodeSets is true, append "v" as the last code unit of result. + 16. Let sticky be ToBoolean(? Get(R, "sticky")). + 17. If sticky is true, append "y" as the last code unit of result. + 18. Return result. +features: [regexp-dotall, regexp-match-indices, regexp-v-flag] ---*/ assert.sameValue(/./.flags, '', 'no flags'); +assert.sameValue(/./d.flags, 'd', 'hasIndices'); assert.sameValue(/./g.flags, 'g', 'global'); assert.sameValue(/./i.flags, 'i', 'ignoreCase'); assert.sameValue(/./m.flags, 'm', 'multiline'); assert.sameValue(/./s.flags, 's', 'dotAll'); assert.sameValue(/./u.flags, 'u', 'unicode'); +assert.sameValue(/./v.flags, 'v', 'unicodeSets'); assert.sameValue(/./y.flags, 'y', 'sticky'); -assert.sameValue(/./d.flags, 'd', 'hasIndices'); diff --git a/test/built-ins/RegExp/prototype/unicodeSets/cross-realm.js b/test/built-ins/RegExp/prototype/unicodeSets/cross-realm.js new file mode 100644 index 0000000000..003fe8d665 --- /dev/null +++ b/test/built-ins/RegExp/prototype/unicodeSets/cross-realm.js @@ -0,0 +1,29 @@ +// Copyright (C) 2022 Mathias Bynens, Ron Buckton, and the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-get-regexp.prototype.unicodeSets +description: RegExp#unicodeSets invoked on a cross-realm object +info: | + get RegExp.prototype.unicodeSets -> RegExpHasFlag + + 1. Let R be the this value. + 2. If Type(R) is not Object, throw a TypeError exception. + 3. If R does not have an [[OriginalFlags]] internal slot, then + a. If SameValue(R, %RegExpPrototype%) is true, return undefined. + b. Otherwise, throw a TypeError exception. +features: [regexp-v-flag, cross-realm] +---*/ + +var unicodeSets = Object.getOwnPropertyDescriptor(RegExp.prototype, 'unicodeSets').get; +var other = $262.createRealm().global; +var otherRegExpProto = other.RegExp.prototype; +var otherRegExpGetter = Object.getOwnPropertyDescriptor(otherRegExpProto, 'unicodeSets').get; + +assert.throws(TypeError, function() { + unicodeSets.call(otherRegExpProto); +}, 'cross-realm RegExp.prototype'); + +assert.throws(other.TypeError, function() { + otherRegExpGetter.call(RegExp.prototype); +}, 'cross-realm RegExp.prototype getter method against primary realm RegExp.prototype'); diff --git a/test/built-ins/RegExp/prototype/unicodeSets/length.js b/test/built-ins/RegExp/prototype/unicodeSets/length.js new file mode 100644 index 0000000000..3c39ad6bbb --- /dev/null +++ b/test/built-ins/RegExp/prototype/unicodeSets/length.js @@ -0,0 +1,34 @@ +// Copyright (C) 2022 Mathias Bynens, Ron Buckton, and André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-get-regexp.prototype.unicodeSets +description: > + get RegExp.prototype.unicodeSets.length is 0. +info: | + get RegExp.prototype.unicodeSets + + 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, including optional + parameters. However, rest parameters 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: [regexp-v-flag] +---*/ + +var desc = Object.getOwnPropertyDescriptor(RegExp.prototype, "unicodeSets"); + +assert.sameValue(desc.get.length, 0); + +verifyProperty(desc.get, "length", { + enumerable: false, + writable: false, + configurable: true, +}); diff --git a/test/built-ins/RegExp/prototype/unicodeSets/name.js b/test/built-ins/RegExp/prototype/unicodeSets/name.js new file mode 100644 index 0000000000..3fdcb919e5 --- /dev/null +++ b/test/built-ins/RegExp/prototype/unicodeSets/name.js @@ -0,0 +1,27 @@ +// Copyright (C) 2022 Mathias Bynens, Ron Buckton, and the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-get-regexp.prototype.unicodeSets +description: > + RegExp.prototype.unicodeSets name +info: | + 17 ECMAScript Standard Built-in Objects + + Functions that are specified as get or set accessor functions of built-in + properties have "get " or "set " prepended to the property name string. +includes: [propertyHelper.js] +features: [regexp-v-flag] +---*/ + +var desc = Object.getOwnPropertyDescriptor(RegExp.prototype, "unicodeSets"); + +assert.sameValue( + desc.get.name, + "get unicodeSets" +); + +verifyProperty(desc.get, "name", { + enumerable: false, + writable: false, + configurable: true, +}); diff --git a/test/built-ins/RegExp/prototype/unicodeSets/prop-desc.js b/test/built-ins/RegExp/prototype/unicodeSets/prop-desc.js new file mode 100644 index 0000000000..78460b3028 --- /dev/null +++ b/test/built-ins/RegExp/prototype/unicodeSets/prop-desc.js @@ -0,0 +1,29 @@ +// Copyright (C) 2022 Mathias Bynens, Ron Buckton, and the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-get-regexp.prototype.unicodeSets +description: > + `pending` property descriptor +info: | + RegExp.prototype.unicodeSets is an accessor property whose set accessor + function is undefined. + + 17 ECMAScript Standard Built-in Objects + + Every accessor property described in clauses 18 through 26 and in Annex B.2 has the attributes + { [[Enumerable]]: false, [[Configurable]]: true } unless otherwise specified. If only a get + accessor function is described, the set accessor function is the default value, undefined. If + only a set accessor is described the get accessor is the default value, undefined. +includes: [propertyHelper.js] +features: [regexp-v-flag] +---*/ + +var desc = Object.getOwnPropertyDescriptor(RegExp.prototype, "unicodeSets"); + +assert.sameValue(desc.set, undefined); +assert.sameValue(typeof desc.get, "function"); + +verifyProperty(RegExp.prototype, "unicodeSets", { + enumerable: false, + configurable: true, +}); diff --git a/test/built-ins/RegExp/prototype/unicodeSets/this-val-invalid-obj.js b/test/built-ins/RegExp/prototype/unicodeSets/this-val-invalid-obj.js new file mode 100644 index 0000000000..8862103043 --- /dev/null +++ b/test/built-ins/RegExp/prototype/unicodeSets/this-val-invalid-obj.js @@ -0,0 +1,34 @@ +// Copyright (C) 2022 Mathias Bynens, Ron Buckton, and the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-get-regexp.prototype.unicodeSets +description: Invoked on an object without an [[OriginalFlags]] internal slot +info: | + get RegExp.prototype.unicodeSets -> RegExpHasFlag + + 1. Let R be the this value. + 2. If Type(R) is not Object, throw a TypeError exception. + 3. If R does not have an [[OriginalFlags]] internal slot, then + a. If SameValue(R, %RegExpPrototype%) is true, return undefined. + b. Otherwise, throw a TypeError exception. +features: [regexp-v-flag] +---*/ + +var unicodeSets = Object.getOwnPropertyDescriptor(RegExp.prototype, 'unicodeSets').get; + +assert.throws(TypeError, function() { + unicodeSets.call({}); +}, 'ordinary object'); + +assert.throws(TypeError, function() { + unicodeSets.call([]); +}, 'array exotic object'); + +assert.throws(TypeError, function() { + unicodeSets.call(arguments); +}, 'arguments object'); + +assert.throws(TypeError, function() { + unicodeSets.call(() => {}); +}, 'function object'); diff --git a/test/built-ins/RegExp/prototype/unicodeSets/this-val-non-obj.js b/test/built-ins/RegExp/prototype/unicodeSets/this-val-non-obj.js new file mode 100644 index 0000000000..d765bdff30 --- /dev/null +++ b/test/built-ins/RegExp/prototype/unicodeSets/this-val-non-obj.js @@ -0,0 +1,44 @@ +// Copyright (C) 2022 Mathias Bynens, Ron Buckton, and the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-get-regexp.prototype.unicodeSets +description: > + `unicodeSets` accessor invoked on a non-object value +info: | + get RegExp.prototype.unicodeSets -> RegExpHasFlag + + 1. Let R be the this value. + 2. If Type(R) is not Object, throw a TypeError exception. +features: [Symbol, regexp-v-flag] +---*/ + +var unicodeSets = Object.getOwnPropertyDescriptor(RegExp.prototype, "unicodeSets").get; + +assert.throws(TypeError, function() { + unicodeSets.call(undefined); +}, "undefined"); + +assert.throws(TypeError, function() { + unicodeSets.call(null); +}, "null"); + +assert.throws(TypeError, function() { + unicodeSets.call(true); +}, "true"); + +assert.throws(TypeError, function() { + unicodeSets.call("string"); +}, "string"); + +assert.throws(TypeError, function() { + unicodeSets.call(Symbol("s")); +}, "symbol"); + +assert.throws(TypeError, function() { + unicodeSets.call(4); +}, "number"); + +assert.throws(TypeError, function() { + unicodeSets.call(4n); +}, "bigint"); diff --git a/test/built-ins/RegExp/prototype/unicodeSets/this-val-regexp-prototype.js b/test/built-ins/RegExp/prototype/unicodeSets/this-val-regexp-prototype.js new file mode 100644 index 0000000000..aace1e573e --- /dev/null +++ b/test/built-ins/RegExp/prototype/unicodeSets/this-val-regexp-prototype.js @@ -0,0 +1,21 @@ +// Copyright (C) 2022 Mathias Bynens, Ron Buckton, and the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-get-regexp.prototype.unicodeSets +description: > + Return value of `undefined` when the "this" value is the RegExp prototype + object +info: | + get RegExp.prototype.unicodeSets -> RegExpHasFlag + + 1. Let R be the this value. + 2. If Type(R) is not Object, throw a TypeError exception. + 3. If R does not have an [[OriginalFlags]] internal slot, then + a. If SameValue(R, %RegExpPrototype%) is true, return undefined. +features: [regexp-v-flag] +---*/ + +var get = Object.getOwnPropertyDescriptor(RegExp.prototype, "unicodeSets").get; + +assert.sameValue(get.call(RegExp.prototype), undefined); diff --git a/test/built-ins/RegExp/prototype/unicodeSets/this-val-regexp.js b/test/built-ins/RegExp/prototype/unicodeSets/this-val-regexp.js new file mode 100644 index 0000000000..0185e9410c --- /dev/null +++ b/test/built-ins/RegExp/prototype/unicodeSets/this-val-regexp.js @@ -0,0 +1,51 @@ +// Copyright (C) 2022 Mathias Bynens, Ron Buckton, and the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-get-regexp.prototype.unicodeSets +description: > + `unicodeSets` accessor function invoked on a RegExp instance +info: | + get RegExp.prototype.unicodeSets -> RegExpHasFlag + + 4. Let flags be the value of R’s [[OriginalFlags]] internal slot. + 5. If flags contains the code unit "s", return true. + 6. Return false. +features: [regexp-v-flag] +---*/ + +assert.sameValue(/./.unicodeSets, false, "/./.unicodeSets"); +assert.sameValue(/./d.unicodeSets, false, "/./d.unicodeSets"); +assert.sameValue(/./g.unicodeSets, false, "/./g.unicodeSets"); +assert.sameValue(/./i.unicodeSets, false, "/./i.unicodeSets"); +assert.sameValue(/./m.unicodeSets, false, "/./m.unicodeSets"); +assert.sameValue(/./s.unicodeSets, false, "/./s.unicodeSets"); +assert.sameValue(/./u.unicodeSets, false, "/./u.unicodeSets"); +assert.sameValue(/./y.unicodeSets, false, "/./y.unicodeSets"); + +assert.sameValue(/./v.unicodeSets, true, "/./v.unicodeSets"); +assert.sameValue(/./vd.unicodeSets, true, "/./vd.unicodeSets"); +assert.sameValue(/./vg.unicodeSets, true, "/./vg.unicodeSets"); +assert.sameValue(/./vi.unicodeSets, true, "/./vi.unicodeSets"); +assert.sameValue(/./vm.unicodeSets, true, "/./vm.unicodeSets"); +assert.sameValue(/./vs.unicodeSets, true, "/./vs.unicodeSets"); +// Note: `/vu` throws an early parse error and is tested separately. +assert.sameValue(/./vy.unicodeSets, true, "/./vy.unicodeSets"); + +assert.sameValue(new RegExp(".", "").unicodeSets, false, "new RegExp('.', '').unicodeSets"); +assert.sameValue(new RegExp(".", "d").unicodeSets, false, "new RegExp('.', 'd').unicodeSets"); +assert.sameValue(new RegExp(".", "g").unicodeSets, false, "new RegExp('.', 'g').unicodeSets"); +assert.sameValue(new RegExp(".", "i").unicodeSets, false, "new RegExp('.', 'i').unicodeSets"); +assert.sameValue(new RegExp(".", "m").unicodeSets, false, "new RegExp('.', 'm').unicodeSets"); +assert.sameValue(new RegExp(".", "s").unicodeSets, false, "new RegExp('.', 's').unicodeSets"); +assert.sameValue(new RegExp(".", "u").unicodeSets, false, "new RegExp('.', 'u').unicodeSets"); +assert.sameValue(new RegExp(".", "y").unicodeSets, false, "new RegExp('.', 'y').unicodeSets"); + +assert.sameValue(new RegExp(".", "v").unicodeSets, true, "new RegExp('.', 'v').unicodeSets"); +assert.sameValue(new RegExp(".", "vd").unicodeSets, true, "new RegExp('.', 'vd').unicodeSets"); +assert.sameValue(new RegExp(".", "vg").unicodeSets, true, "new RegExp('.', 'vg').unicodeSets"); +assert.sameValue(new RegExp(".", "vi").unicodeSets, true, "new RegExp('.', 'vi').unicodeSets"); +assert.sameValue(new RegExp(".", "vm").unicodeSets, true, "new RegExp('.', 'vm').unicodeSets"); +assert.sameValue(new RegExp(".", "vs").unicodeSets, true, "new RegExp('.', 'vs').unicodeSets"); +// Note: `new RegExp(pattern, 'vu')` throws a runtime error and is tested separately. +assert.sameValue(new RegExp(".", "vy").unicodeSets, true, "new RegExp('.', 'vy').unicodeSets"); diff --git a/test/built-ins/RegExp/prototype/unicodeSets/uv-flags-constructor.js b/test/built-ins/RegExp/prototype/unicodeSets/uv-flags-constructor.js new file mode 100644 index 0000000000..a001932171 --- /dev/null +++ b/test/built-ins/RegExp/prototype/unicodeSets/uv-flags-constructor.js @@ -0,0 +1,14 @@ +// Copyright 2022 Mathias Bynens. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +author: Mathias Bynens +description: > + Setting the `u` and `v` flag at the same time produces an error. +esid: sec-parsepattern +features: [regexp-v-flag] +---*/ + +assert.throws(SyntaxError, function() { + new RegExp(".", "uv"); +}); diff --git a/test/built-ins/RegExp/prototype/unicodeSets/uv-flags.js b/test/built-ins/RegExp/prototype/unicodeSets/uv-flags.js new file mode 100644 index 0000000000..9db7cdddf3 --- /dev/null +++ b/test/built-ins/RegExp/prototype/unicodeSets/uv-flags.js @@ -0,0 +1,17 @@ +// Copyright 2022 Mathias Bynens. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +author: Mathias Bynens +description: > + Setting the `u` and `v` flag at the same time produces an error. +esid: sec-parsepattern +negative: + phase: parse + type: SyntaxError +features: [regexp-v-flag] +---*/ + +$DONOTEVALUATE(); + +/./uv;