diff --git a/features.txt b/features.txt index c53e945eb3..841917b83c 100644 --- a/features.txt +++ b/features.txt @@ -276,6 +276,10 @@ regexp-v-flag # https://github.com/tc39/proposal-decorators decorators +# Duplicate named capturing groups +# https://github.com/tc39/proposal-duplicate-named-capturing-groups +regexp-duplicate-named-groups + ## Standard language features # # Language features that have been included in a published version of the diff --git a/test/built-ins/RegExp/named-groups/duplicate-names-group-property-enumeration-order.js b/test/built-ins/RegExp/named-groups/duplicate-names-group-property-enumeration-order.js new file mode 100644 index 0000000000..9b44f45687 --- /dev/null +++ b/test/built-ins/RegExp/named-groups/duplicate-names-group-property-enumeration-order.js @@ -0,0 +1,24 @@ +// Copyright 2022 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: Enumeration order of the groups object with duplicate named capture groups +esid: prod-GroupSpecifier +features: [regexp-duplicate-named-groups] +includes: [compareArray.js] +---*/ + + +let regexp = /(?a)(?a)|(?b)(?b)/; + +assert.compareArray( + Object.keys(regexp.exec("aa").groups), + ["y", "x"], + "property enumeration order of the groups object is based on source order, not match order" +); + +assert.compareArray( + Object.keys(regexp.exec("bb").groups), + ["y", "x"], + "property enumeration order of the groups object is based on source order, not match order" +); diff --git a/test/built-ins/RegExp/named-groups/duplicate-names-match-indices.js b/test/built-ins/RegExp/named-groups/duplicate-names-match-indices.js new file mode 100644 index 0000000000..0fea52e496 --- /dev/null +++ b/test/built-ins/RegExp/named-groups/duplicate-names-match-indices.js @@ -0,0 +1,15 @@ +// Copyright 2022 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: match indices with duplicate named capture groups +esid: sec-makematchindicesindexpairarray +features: [regexp-duplicate-named-groups, regexp-match-indices] +includes: [compareArray.js] +---*/ + +let indices = "..ab".match(/(?a)|(?b)/d).indices; +assert.compareArray(indices.groups.x, [2, 3]); + +indices = "..ba".match(/(?a)|(?b)/d).indices; +assert.compareArray(indices.groups.x, [2, 3]); diff --git a/test/built-ins/RegExp/named-groups/duplicate-names-replace.js b/test/built-ins/RegExp/named-groups/duplicate-names-replace.js new file mode 100644 index 0000000000..01b0cdf6ca --- /dev/null +++ b/test/built-ins/RegExp/named-groups/duplicate-names-replace.js @@ -0,0 +1,17 @@ +// Copyright 2022 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: String.prototype.replace behavior with duplicate named capture groups +esid: prod-GroupSpecifier +features: [regexp-duplicate-named-groups] +---*/ + +assert.sameValue("ab".replace(/(?a)|(?b)/, "[$]"), "[a]b"); +assert.sameValue("ba".replace(/(?a)|(?b)/, "[$]"), "[b]a"); + +assert.sameValue("ab".replace(/(?a)|(?b)/, "[$][$1][$2]"), "[a][a][]b"); +assert.sameValue("ba".replace(/(?a)|(?b)/, "[$][$1][$2]"), "[b][][b]a"); + +assert.sameValue("ab".replace(/(?a)|(?b)/g, "[$]"), "[a][b]"); +assert.sameValue("ba".replace(/(?a)|(?b)/g, "[$]"), "[b][a]"); diff --git a/test/built-ins/RegExp/named-groups/duplicate-names.js b/test/built-ins/RegExp/named-groups/duplicate-names.js new file mode 100644 index 0000000000..8213a3e0c2 --- /dev/null +++ b/test/built-ins/RegExp/named-groups/duplicate-names.js @@ -0,0 +1,19 @@ +// Copyright 2022 Kevin Gibbons. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: Matching behavior with duplicate named capture groups +esid: prod-GroupSpecifier +features: [regexp-duplicate-named-groups] +includes: [compareArray.js] +---*/ + +assert.compareArray(["b", "b"], "bab".match(/(?a)|(?b)/)); +assert.compareArray(["b", "b"], "bab".match(/(?b)|(?a)/)); + +assert.compareArray(["aa", "aa", undefined], "aa".match(/(?:(?a)|(?b))\k/)); +assert.compareArray(["bb", undefined, "bb"], "bb".match(/(?:(?a)|(?b))\k/)); + +let matchResult = "aabb".match(/(?:(?:(?a)|(?b))\k){2}/); +assert.compareArray(["aabb", undefined, "bb"], matchResult); +assert.sameValue(matchResult.groups.x, "bb");