mirror of
https://github.com/tc39/test262.git
synced 2025-07-28 08:24:23 +02:00
parent
7040938bd0
commit
3682ddd7e3
@ -158,6 +158,10 @@ Intl.DisplayNames
|
|||||||
Promise.any
|
Promise.any
|
||||||
AggregateError
|
AggregateError
|
||||||
|
|
||||||
|
# String.prototype.replaceAll
|
||||||
|
# https://github.com/tc39/proposal-string-replaceall
|
||||||
|
String.prototype.replaceAll
|
||||||
|
|
||||||
## Standard language features
|
## Standard language features
|
||||||
#
|
#
|
||||||
# Language features that have been included in a published version of the
|
# Language features that have been included in a published version of the
|
||||||
|
70
test/built-ins/String/prototype/replaceAll/getSubstitution-0x0024-0x0024.js
vendored
Normal file
70
test/built-ins/String/prototype/replaceAll/getSubstitution-0x0024-0x0024.js
vendored
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
// Copyright (C) 2019 Leo Balter. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-string.prototype.replaceall
|
||||||
|
description: >
|
||||||
|
Replacement Text Symbol Substitutions ($$)
|
||||||
|
info: |
|
||||||
|
String.prototype.replaceAll ( searchValue, replaceValue )
|
||||||
|
|
||||||
|
10. Let position be ! StringIndexOf(string, searchString, 0).
|
||||||
|
11. Repeat, while position is not -1
|
||||||
|
a. Append position to the end of matchPositions.
|
||||||
|
b. Let position be ! StringIndexOf(string, searchString, position + advanceBy).
|
||||||
|
...
|
||||||
|
14. For each position in matchPositions, do
|
||||||
|
a. If functionalReplace is true, then
|
||||||
|
...
|
||||||
|
b. Else,
|
||||||
|
...
|
||||||
|
ii. Let captures be a new empty List.
|
||||||
|
iii. Let replacement be GetSubstitution(searchString, string, position, captures, undefined, replaceValue).
|
||||||
|
|
||||||
|
StringIndexOf ( string, searchValue, fromIndex )
|
||||||
|
|
||||||
|
...
|
||||||
|
4. Let len be the length of string.
|
||||||
|
5. If searchValue is the empty string, and fromIndex <= len, return fromIndex.
|
||||||
|
6. Let searchLen be the length of searchValue.
|
||||||
|
7. If there exists any integer k such that fromIndex ≤ k ≤ len - searchLen and for all nonnegative integers j less than searchLen, the code unit at index k + j within string is the same as the code unit at index j within searchValue, let pos be the smallest (closest to -∞) such integer. Otherwise, let pos be -1.
|
||||||
|
8. Return pos.
|
||||||
|
|
||||||
|
Runtime Semantics: GetSubstitution ( matched, str, position, captures, namedCaptures, replacement )
|
||||||
|
|
||||||
|
...
|
||||||
|
2. Let matchLength be the number of code units in matched.
|
||||||
|
...
|
||||||
|
4. Let stringLength be the number of code units in str.
|
||||||
|
...
|
||||||
|
9. Let tailPos be position + matchLength.
|
||||||
|
10. Let m be the number of elements in captures.
|
||||||
|
11. Let result be the String value derived from replacement by copying code unit elements from replacement to result while performing replacements as specified in Table 53. These $ replacements are done left-to-right, and, once such a replacement is performed, the new replacement text is not subject to further replacements.
|
||||||
|
12 Return result.
|
||||||
|
|
||||||
|
Table 53: Replacement Text Symbol Substitutions
|
||||||
|
...
|
||||||
|
features: [String.prototype.replaceAll]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
var str = 'Ninguém é igual a ninguém. Todo o ser humano é um estranho ímpar.';
|
||||||
|
|
||||||
|
var result;
|
||||||
|
|
||||||
|
result = str.replaceAll('ninguém', '$$');
|
||||||
|
assert.sameValue(result, 'Ninguém é igual a $. Todo o ser humano é um estranho ímpar.');
|
||||||
|
|
||||||
|
result = str.replaceAll('é', '$$');
|
||||||
|
assert.sameValue(result, 'Ningu$m $ igual a ningu$m. Todo o ser humano $ um estranho ímpar.');
|
||||||
|
|
||||||
|
result = str.replaceAll('é', '$$ -');
|
||||||
|
assert.sameValue(result, 'Ningu$ -m $ - igual a ningu$ -m. Todo o ser humano $ - um estranho ímpar.');
|
||||||
|
|
||||||
|
result = str.replaceAll('é', '$$&');
|
||||||
|
assert.sameValue(result, 'Ningu$&m $& igual a ningu$&m. Todo o ser humano $& um estranho ímpar.');
|
||||||
|
|
||||||
|
result = str.replaceAll('é', '$$$');
|
||||||
|
assert.sameValue(result, 'Ningu$$m $$ igual a ningu$$m. Todo o ser humano $$ um estranho ímpar.');
|
||||||
|
|
||||||
|
result = str.replaceAll('é', '$$$$');
|
||||||
|
assert.sameValue(result, 'Ningu$$m $$ igual a ningu$$m. Todo o ser humano $$ um estranho ímpar.');
|
64
test/built-ins/String/prototype/replaceAll/getSubstitution-0x0024-0x0026.js
vendored
Normal file
64
test/built-ins/String/prototype/replaceAll/getSubstitution-0x0024-0x0026.js
vendored
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
// Copyright (C) 2019 Leo Balter. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-string.prototype.replaceall
|
||||||
|
description: >
|
||||||
|
Replacement Text Symbol Substitutions ($&)
|
||||||
|
info: |
|
||||||
|
String.prototype.replaceAll ( searchValue, replaceValue )
|
||||||
|
|
||||||
|
10. Let position be ! StringIndexOf(string, searchString, 0).
|
||||||
|
11. Repeat, while position is not -1
|
||||||
|
a. Append position to the end of matchPositions.
|
||||||
|
b. Let position be ! StringIndexOf(string, searchString, position + advanceBy).
|
||||||
|
...
|
||||||
|
14. For each position in matchPositions, do
|
||||||
|
a. If functionalReplace is true, then
|
||||||
|
...
|
||||||
|
b. Else,
|
||||||
|
...
|
||||||
|
ii. Let captures be a new empty List.
|
||||||
|
iii. Let replacement be GetSubstitution(searchString, string, position, captures, undefined, replaceValue).
|
||||||
|
|
||||||
|
StringIndexOf ( string, searchValue, fromIndex )
|
||||||
|
|
||||||
|
...
|
||||||
|
4. Let len be the length of string.
|
||||||
|
5. If searchValue is the empty string, and fromIndex <= len, return fromIndex.
|
||||||
|
6. Let searchLen be the length of searchValue.
|
||||||
|
7. If there exists any integer k such that fromIndex ≤ k ≤ len - searchLen and for all nonnegative integers j less than searchLen, the code unit at index k + j within string is the same as the code unit at index j within searchValue, let pos be the smallest (closest to -∞) such integer. Otherwise, let pos be -1.
|
||||||
|
8. Return pos.
|
||||||
|
|
||||||
|
Runtime Semantics: GetSubstitution ( matched, str, position, captures, namedCaptures, replacement )
|
||||||
|
|
||||||
|
...
|
||||||
|
2. Let matchLength be the number of code units in matched.
|
||||||
|
...
|
||||||
|
4. Let stringLength be the number of code units in str.
|
||||||
|
...
|
||||||
|
9. Let tailPos be position + matchLength.
|
||||||
|
10. Let m be the number of elements in captures.
|
||||||
|
11. Let result be the String value derived from replacement by copying code unit elements from replacement to result while performing replacements as specified in Table 53. These $ replacements are done left-to-right, and, once such a replacement is performed, the new replacement text is not subject to further replacements.
|
||||||
|
12 Return result.
|
||||||
|
|
||||||
|
Table 53: Replacement Text Symbol Substitutions
|
||||||
|
...
|
||||||
|
features: [String.prototype.replaceAll]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
var str = 'Ninguém é igual a ninguém. Todo o ser humano é um estranho ímpar.';
|
||||||
|
|
||||||
|
var result;
|
||||||
|
|
||||||
|
result = str.replaceAll('ninguém', '$&');
|
||||||
|
assert.sameValue(result, 'Ninguém é igual a ninguém. Todo o ser humano é um estranho ímpar.');
|
||||||
|
|
||||||
|
result = str.replaceAll('ninguém', '($&)');
|
||||||
|
assert.sameValue(result, 'Ninguém é igual a (ninguém). Todo o ser humano é um estranho ímpar.');
|
||||||
|
|
||||||
|
result = str.replaceAll('é', '($&)');
|
||||||
|
assert.sameValue(result, 'Ningu(é)m (é) igual a ningu(é)m. Todo o ser humano (é) um estranho ímpar.');
|
||||||
|
|
||||||
|
result = str.replaceAll('é', '($&) $&');
|
||||||
|
assert.sameValue(result, 'Ningu(é) ém (é) é igual a ningu(é) ém. Todo o ser humano (é) é um estranho ímpar.');
|
64
test/built-ins/String/prototype/replaceAll/getSubstitution-0x0024-0x0027.js
vendored
Normal file
64
test/built-ins/String/prototype/replaceAll/getSubstitution-0x0024-0x0027.js
vendored
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
// Copyright (C) 2019 Leo Balter. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-string.prototype.replaceall
|
||||||
|
description: >
|
||||||
|
Replacement Text Symbol Substitutions ($')
|
||||||
|
info: |
|
||||||
|
String.prototype.replaceAll ( searchValue, replaceValue )
|
||||||
|
|
||||||
|
10. Let position be ! StringIndexOf(string, searchString, 0).
|
||||||
|
11. Repeat, while position is not -1
|
||||||
|
a. Append position to the end of matchPositions.
|
||||||
|
b. Let position be ! StringIndexOf(string, searchString, position + advanceBy).
|
||||||
|
...
|
||||||
|
14. For each position in matchPositions, do
|
||||||
|
a. If functionalReplace is true, then
|
||||||
|
...
|
||||||
|
b. Else,
|
||||||
|
...
|
||||||
|
ii. Let captures be a new empty List.
|
||||||
|
iii. Let replacement be GetSubstitution(searchString, string, position, captures, undefined, replaceValue).
|
||||||
|
|
||||||
|
StringIndexOf ( string, searchValue, fromIndex )
|
||||||
|
|
||||||
|
...
|
||||||
|
4. Let len be the length of string.
|
||||||
|
5. If searchValue is the empty string, and fromIndex <= len, return fromIndex.
|
||||||
|
6. Let searchLen be the length of searchValue.
|
||||||
|
7. If there exists any integer k such that fromIndex ≤ k ≤ len - searchLen and for all nonnegative integers j less than searchLen, the code unit at index k + j within string is the same as the code unit at index j within searchValue, let pos be the smallest (closest to -∞) such integer. Otherwise, let pos be -1.
|
||||||
|
8. Return pos.
|
||||||
|
|
||||||
|
Runtime Semantics: GetSubstitution ( matched, str, position, captures, namedCaptures, replacement )
|
||||||
|
|
||||||
|
...
|
||||||
|
2. Let matchLength be the number of code units in matched.
|
||||||
|
...
|
||||||
|
4. Let stringLength be the number of code units in str.
|
||||||
|
...
|
||||||
|
9. Let tailPos be position + matchLength.
|
||||||
|
10. Let m be the number of elements in captures.
|
||||||
|
11. Let result be the String value derived from replacement by copying code unit elements from replacement to result while performing replacements as specified in Table 53. These $ replacements are done left-to-right, and, once such a replacement is performed, the new replacement text is not subject to further replacements.
|
||||||
|
12 Return result.
|
||||||
|
|
||||||
|
Table 53: Replacement Text Symbol Substitutions
|
||||||
|
...
|
||||||
|
features: [String.prototype.replaceAll]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
var str = 'Ninguém é igual a ninguém. Todo o ser humano é um estranho ímpar.';
|
||||||
|
|
||||||
|
var result;
|
||||||
|
|
||||||
|
result = str.replaceAll('ninguém', '$\'');
|
||||||
|
assert.sameValue(result, 'Ninguém é igual a . Todo o ser humano é um estranho ímpar.. Todo o ser humano é um estranho ímpar.');
|
||||||
|
|
||||||
|
result = str.replaceAll('.', '--- $\'');
|
||||||
|
assert.sameValue(result, 'Ninguém é igual a ninguém--- Todo o ser humano é um estranho ímpar. Todo o ser humano é um estranho ímpar--- ');
|
||||||
|
|
||||||
|
result = str.replaceAll('é', '($\')');
|
||||||
|
assert.sameValue(result, 'Ningu(m é igual a ninguém. Todo o ser humano é um estranho ímpar.)m ( igual a ninguém. Todo o ser humano é um estranho ímpar.) igual a ningu(m. Todo o ser humano é um estranho ímpar.)m. Todo o ser humano ( um estranho ímpar.) um estranho ímpar.');
|
||||||
|
|
||||||
|
result = str.replaceAll('é', '($\') $\'');
|
||||||
|
assert.sameValue(result, 'Ningu(m é igual a ninguém. Todo o ser humano é um estranho ímpar.) m é igual a ninguém. Todo o ser humano é um estranho ímpar.m ( igual a ninguém. Todo o ser humano é um estranho ímpar.) igual a ninguém. Todo o ser humano é um estranho ímpar. igual a ningu(m. Todo o ser humano é um estranho ímpar.) m. Todo o ser humano é um estranho ímpar.m. Todo o ser humano ( um estranho ímpar.) um estranho ímpar. um estranho ímpar.');
|
71
test/built-ins/String/prototype/replaceAll/getSubstitution-0x0024-0x003C.js
vendored
Normal file
71
test/built-ins/String/prototype/replaceAll/getSubstitution-0x0024-0x003C.js
vendored
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
// Copyright (C) 2019 Leo Balter. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-string.prototype.replaceall
|
||||||
|
description: >
|
||||||
|
Replacement Text Symbol Substitutions ($<)
|
||||||
|
info: |
|
||||||
|
String.prototype.replaceAll ( searchValue, replaceValue )
|
||||||
|
|
||||||
|
10. Let position be ! StringIndexOf(string, searchString, 0).
|
||||||
|
11. Repeat, while position is not -1
|
||||||
|
a. Append position to the end of matchPositions.
|
||||||
|
b. Let position be ! StringIndexOf(string, searchString, position + advanceBy).
|
||||||
|
...
|
||||||
|
14. For each position in matchPositions, do
|
||||||
|
a. If functionalReplace is true, then
|
||||||
|
...
|
||||||
|
b. Else,
|
||||||
|
...
|
||||||
|
ii. Let captures be a new empty List.
|
||||||
|
iii. Let replacement be GetSubstitution(searchString, string, position, captures, undefined, replaceValue).
|
||||||
|
|
||||||
|
StringIndexOf ( string, searchValue, fromIndex )
|
||||||
|
|
||||||
|
...
|
||||||
|
4. Let len be the length of string.
|
||||||
|
5. If searchValue is the empty string, and fromIndex <= len, return fromIndex.
|
||||||
|
6. Let searchLen be the length of searchValue.
|
||||||
|
7. If there exists any integer k such that fromIndex ≤ k ≤ len - searchLen and for all nonnegative integers j less than searchLen, the code unit at index k + j within string is the same as the code unit at index j within searchValue, let pos be the smallest (closest to -∞) such integer. Otherwise, let pos be -1.
|
||||||
|
8. Return pos.
|
||||||
|
|
||||||
|
Runtime Semantics: GetSubstitution ( matched, str, position, captures, namedCaptures, replacement )
|
||||||
|
|
||||||
|
...
|
||||||
|
2. Let matchLength be the number of code units in matched.
|
||||||
|
...
|
||||||
|
4. Let stringLength be the number of code units in str.
|
||||||
|
...
|
||||||
|
9. Let tailPos be position + matchLength.
|
||||||
|
10. Let m be the number of elements in captures.
|
||||||
|
11. Let result be the String value derived from replacement by copying code unit elements from replacement to result while performing replacements as specified in Table 53. These $ replacements are done left-to-right, and, once such a replacement is performed, the new replacement text is not subject to further replacements.
|
||||||
|
12 Return result.
|
||||||
|
|
||||||
|
Table 53: Replacement Text Symbol Substitutions
|
||||||
|
...
|
||||||
|
|
||||||
|
$<
|
||||||
|
1. If namedCaptures is undefined, the replacement text is the String "$<".
|
||||||
|
...
|
||||||
|
features: [String.prototype.replaceAll, Symbol.replace]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
var str = 'aaaaaaaaaaaaaaaa aaaaaaaa aaaaaaaaaaaaaaaa';
|
||||||
|
|
||||||
|
var result;
|
||||||
|
|
||||||
|
// captures is always an empty list if GetSubstitution is called from the string value of SearchValue
|
||||||
|
|
||||||
|
result = str.replaceAll('a', '$<');
|
||||||
|
assert.sameValue(result, '$<$<$<$<$<$<$<$<$<$<$<$<$<$<$<$< $<$<$<$<$<$<$<$< $<$<$<$<$<$<$<$<$<$<$<$<$<$<$<$<');
|
||||||
|
|
||||||
|
var customRE = /./g;
|
||||||
|
|
||||||
|
Object.defineProperty(customRE, Symbol.replace, {
|
||||||
|
value: undefined
|
||||||
|
});
|
||||||
|
|
||||||
|
result = '------------------- /./g -------/./g'.replaceAll(customRE, 'a($<$<)');
|
||||||
|
assert.sameValue(result, '------------------- a($<$<) -------a($<$<)');
|
||||||
|
|
67
test/built-ins/String/prototype/replaceAll/getSubstitution-0x0024-0x0060.js
vendored
Normal file
67
test/built-ins/String/prototype/replaceAll/getSubstitution-0x0024-0x0060.js
vendored
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
// Copyright (C) 2019 Leo Balter. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-string.prototype.replaceall
|
||||||
|
description: >
|
||||||
|
Replacement Text Symbol Substitutions ($`)
|
||||||
|
info: |
|
||||||
|
String.prototype.replaceAll ( searchValue, replaceValue )
|
||||||
|
|
||||||
|
10. Let position be ! StringIndexOf(string, searchString, 0).
|
||||||
|
11. Repeat, while position is not -1
|
||||||
|
a. Append position to the end of matchPositions.
|
||||||
|
b. Let position be ! StringIndexOf(string, searchString, position + advanceBy).
|
||||||
|
...
|
||||||
|
14. For each position in matchPositions, do
|
||||||
|
a. If functionalReplace is true, then
|
||||||
|
...
|
||||||
|
b. Else,
|
||||||
|
...
|
||||||
|
ii. Let captures be a new empty List.
|
||||||
|
iii. Let replacement be GetSubstitution(searchString, string, position, captures, undefined, replaceValue).
|
||||||
|
|
||||||
|
StringIndexOf ( string, searchValue, fromIndex )
|
||||||
|
|
||||||
|
...
|
||||||
|
4. Let len be the length of string.
|
||||||
|
5. If searchValue is the empty string, and fromIndex <= len, return fromIndex.
|
||||||
|
6. Let searchLen be the length of searchValue.
|
||||||
|
7. If there exists any integer k such that fromIndex ≤ k ≤ len - searchLen and for all nonnegative integers j less than searchLen, the code unit at index k + j within string is the same as the code unit at index j within searchValue, let pos be the smallest (closest to -∞) such integer. Otherwise, let pos be -1.
|
||||||
|
8. Return pos.
|
||||||
|
|
||||||
|
Runtime Semantics: GetSubstitution ( matched, str, position, captures, namedCaptures, replacement )
|
||||||
|
|
||||||
|
...
|
||||||
|
2. Let matchLength be the number of code units in matched.
|
||||||
|
...
|
||||||
|
4. Let stringLength be the number of code units in str.
|
||||||
|
...
|
||||||
|
9. Let tailPos be position + matchLength.
|
||||||
|
10. Let m be the number of elements in captures.
|
||||||
|
11. Let result be the String value derived from replacement by copying code unit elements from replacement to result while performing replacements as specified in Table 53. These $ replacements are done left-to-right, and, once such a replacement is performed, the new replacement text is not subject to further replacements.
|
||||||
|
12 Return result.
|
||||||
|
|
||||||
|
Table 53: Replacement Text Symbol Substitutions
|
||||||
|
...
|
||||||
|
features: [String.prototype.replaceAll]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
var str = 'Ninguém é igual a ninguém. Todo o ser humano é um estranho ímpar.';
|
||||||
|
|
||||||
|
var result;
|
||||||
|
|
||||||
|
result = str.replaceAll('ninguém', '$`');
|
||||||
|
assert.sameValue(result, 'Ninguém é igual a Ninguém é igual a . Todo o ser humano é um estranho ímpar.');
|
||||||
|
|
||||||
|
result = str.replaceAll('Ninguém', '$`');
|
||||||
|
assert.sameValue(result, ' é igual a ninguém. Todo o ser humano é um estranho ímpar.');
|
||||||
|
|
||||||
|
result = str.replaceAll('ninguém', '($`)');
|
||||||
|
assert.sameValue(result, 'Ninguém é igual a (Ninguém é igual a ). Todo o ser humano é um estranho ímpar.');
|
||||||
|
|
||||||
|
result = str.replaceAll('é', '($`)');
|
||||||
|
assert.sameValue(result, 'Ningu(Ningu)m (Ninguém ) igual a ningu(Ninguém é igual a ningu)m. Todo o ser humano (Ninguém é igual a ninguém. Todo o ser humano ) um estranho ímpar.');
|
||||||
|
|
||||||
|
result = str.replaceAll('é', '($`) $`');
|
||||||
|
assert.sameValue(result, 'Ningu(Ningu) Ningum (Ninguém ) Ninguém igual a ningu(Ninguém é igual a ningu) Ninguém é igual a ningum. Todo o ser humano (Ninguém é igual a ninguém. Todo o ser humano ) Ninguém é igual a ninguém. Todo o ser humano um estranho ímpar.');
|
64
test/built-ins/String/prototype/replaceAll/getSubstitution-0x0024.js
vendored
Normal file
64
test/built-ins/String/prototype/replaceAll/getSubstitution-0x0024.js
vendored
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
// Copyright (C) 2019 Leo Balter. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-string.prototype.replaceall
|
||||||
|
description: >
|
||||||
|
Replacement Text Symbol Substitutions ($)
|
||||||
|
info: |
|
||||||
|
String.prototype.replaceAll ( searchValue, replaceValue )
|
||||||
|
|
||||||
|
10. Let position be ! StringIndexOf(string, searchString, 0).
|
||||||
|
11. Repeat, while position is not -1
|
||||||
|
a. Append position to the end of matchPositions.
|
||||||
|
b. Let position be ! StringIndexOf(string, searchString, position + advanceBy).
|
||||||
|
...
|
||||||
|
14. For each position in matchPositions, do
|
||||||
|
a. If functionalReplace is true, then
|
||||||
|
...
|
||||||
|
b. Else,
|
||||||
|
...
|
||||||
|
ii. Let captures be a new empty List.
|
||||||
|
iii. Let replacement be GetSubstitution(searchString, string, position, captures, undefined, replaceValue).
|
||||||
|
|
||||||
|
StringIndexOf ( string, searchValue, fromIndex )
|
||||||
|
|
||||||
|
...
|
||||||
|
4. Let len be the length of string.
|
||||||
|
5. If searchValue is the empty string, and fromIndex <= len, return fromIndex.
|
||||||
|
6. Let searchLen be the length of searchValue.
|
||||||
|
7. If there exists any integer k such that fromIndex ≤ k ≤ len - searchLen and for all nonnegative integers j less than searchLen, the code unit at index k + j within string is the same as the code unit at index j within searchValue, let pos be the smallest (closest to -∞) such integer. Otherwise, let pos be -1.
|
||||||
|
8. Return pos.
|
||||||
|
|
||||||
|
Runtime Semantics: GetSubstitution ( matched, str, position, captures, namedCaptures, replacement )
|
||||||
|
|
||||||
|
...
|
||||||
|
2. Let matchLength be the number of code units in matched.
|
||||||
|
...
|
||||||
|
4. Let stringLength be the number of code units in str.
|
||||||
|
...
|
||||||
|
9. Let tailPos be position + matchLength.
|
||||||
|
10. Let m be the number of elements in captures.
|
||||||
|
11. Let result be the String value derived from replacement by copying code unit elements from replacement to result while performing replacements as specified in Table 53. These $ replacements are done left-to-right, and, once such a replacement is performed, the new replacement text is not subject to further replacements.
|
||||||
|
12 Return result.
|
||||||
|
|
||||||
|
Table 53: Replacement Text Symbol Substitutions
|
||||||
|
...
|
||||||
|
features: [String.prototype.replaceAll]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
var str = 'Ninguém é igual a ninguém. Todo o ser humano é um estranho ímpar.';
|
||||||
|
|
||||||
|
var result;
|
||||||
|
|
||||||
|
result = str.replaceAll('ninguém', '$');
|
||||||
|
assert.sameValue(result, 'Ninguém é igual a $. Todo o ser humano é um estranho ímpar.');
|
||||||
|
|
||||||
|
result = str.replaceAll('é', '$');
|
||||||
|
assert.sameValue(result, 'Ningu$m $ igual a ningu$m. Todo o ser humano $ um estranho ímpar.');
|
||||||
|
|
||||||
|
result = str.replaceAll('é', '$ -');
|
||||||
|
assert.sameValue(result, 'Ningu$ -m $ - igual a ningu$ -m. Todo o ser humano $ - um estranho ímpar.');
|
||||||
|
|
||||||
|
result = str.replaceAll('é', '$$$');
|
||||||
|
assert.sameValue(result, 'Ningu$$m $$ igual a ningu$$m. Todo o ser humano $$ um estranho ímpar.');
|
93
test/built-ins/String/prototype/replaceAll/getSubstitution-0x0024N.js
vendored
Normal file
93
test/built-ins/String/prototype/replaceAll/getSubstitution-0x0024N.js
vendored
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
// Copyright (C) 2019 Leo Balter. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-string.prototype.replaceall
|
||||||
|
description: >
|
||||||
|
Replacement Text Symbol Substitutions ($N)
|
||||||
|
info: |
|
||||||
|
String.prototype.replaceAll ( searchValue, replaceValue )
|
||||||
|
|
||||||
|
10. Let position be ! StringIndexOf(string, searchString, 0).
|
||||||
|
11. Repeat, while position is not -1
|
||||||
|
a. Append position to the end of matchPositions.
|
||||||
|
b. Let position be ! StringIndexOf(string, searchString, position + advanceBy).
|
||||||
|
...
|
||||||
|
14. For each position in matchPositions, do
|
||||||
|
a. If functionalReplace is true, then
|
||||||
|
...
|
||||||
|
b. Else,
|
||||||
|
...
|
||||||
|
ii. Let captures be a new empty List.
|
||||||
|
iii. Let replacement be GetSubstitution(searchString, string, position, captures, undefined, replaceValue).
|
||||||
|
|
||||||
|
StringIndexOf ( string, searchValue, fromIndex )
|
||||||
|
|
||||||
|
...
|
||||||
|
4. Let len be the length of string.
|
||||||
|
5. If searchValue is the empty string, and fromIndex <= len, return fromIndex.
|
||||||
|
6. Let searchLen be the length of searchValue.
|
||||||
|
7. If there exists any integer k such that fromIndex ≤ k ≤ len - searchLen and for all nonnegative integers j less than searchLen, the code unit at index k + j within string is the same as the code unit at index j within searchValue, let pos be the smallest (closest to -∞) such integer. Otherwise, let pos be -1.
|
||||||
|
8. Return pos.
|
||||||
|
|
||||||
|
Runtime Semantics: GetSubstitution ( matched, str, position, captures, namedCaptures, replacement )
|
||||||
|
|
||||||
|
...
|
||||||
|
2. Let matchLength be the number of code units in matched.
|
||||||
|
...
|
||||||
|
4. Let stringLength be the number of code units in str.
|
||||||
|
...
|
||||||
|
9. Let tailPos be position + matchLength.
|
||||||
|
10. Let m be the number of elements in captures.
|
||||||
|
11. Let result be the String value derived from replacement by copying code unit elements from replacement to result while performing replacements as specified in Table 53. These $ replacements are done left-to-right, and, once such a replacement is performed, the new replacement text is not subject to further replacements.
|
||||||
|
12 Return result.
|
||||||
|
|
||||||
|
Table 53: Replacement Text Symbol Substitutions
|
||||||
|
...
|
||||||
|
|
||||||
|
The nth element of captures, where n is a single digit in the range 1 to 9. If n ≤ m and the nth element of captures is undefined, use the empty String instead. If n > m, no replacement is done.
|
||||||
|
features: [String.prototype.replaceAll, Symbol.replace]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
var str = 'ABC AAA ABC AAA';
|
||||||
|
|
||||||
|
var result;
|
||||||
|
|
||||||
|
// captures is always an empty list if GetSubstitution is called from the string value of SearchValue
|
||||||
|
|
||||||
|
result = str.replaceAll('ABC', '$1');
|
||||||
|
assert.sameValue(result, '$1 AAA $1 AAA');
|
||||||
|
|
||||||
|
result = str.replaceAll('ABC', '$2');
|
||||||
|
assert.sameValue(result, '$2 AAA $2 AAA');
|
||||||
|
|
||||||
|
result = str.replaceAll('ABC', '$3');
|
||||||
|
assert.sameValue(result, '$3 AAA $3 AAA');
|
||||||
|
|
||||||
|
result = str.replaceAll('ABC', '$4');
|
||||||
|
assert.sameValue(result, '$4 AAA $4 AAA');
|
||||||
|
|
||||||
|
result = str.replaceAll('ABC', '$5');
|
||||||
|
assert.sameValue(result, '$5 AAA $5 AAA');
|
||||||
|
|
||||||
|
result = str.replaceAll('ABC', '$6');
|
||||||
|
assert.sameValue(result, '$6 AAA $6 AAA');
|
||||||
|
|
||||||
|
result = str.replaceAll('ABC', '$7');
|
||||||
|
assert.sameValue(result, '$7 AAA $7 AAA');
|
||||||
|
|
||||||
|
result = str.replaceAll('ABC', '$8');
|
||||||
|
assert.sameValue(result, '$8 AAA $8 AAA');
|
||||||
|
|
||||||
|
result = str.replaceAll('ABC', '$9');
|
||||||
|
assert.sameValue(result, '$9 AAA $9 AAA');
|
||||||
|
|
||||||
|
var customRE = /./g;
|
||||||
|
|
||||||
|
Object.defineProperty(customRE, Symbol.replace, {
|
||||||
|
value: undefined
|
||||||
|
});
|
||||||
|
|
||||||
|
result = '--- /./g --- /a/g --- /./g ---'.replaceAll(customRE, 'a($1$1)');
|
||||||
|
assert.sameValue(result, '--- a($1$1) --- /a/g --- a($1$1) ---');
|
||||||
|
|
72
test/built-ins/String/prototype/replaceAll/getSubstitution-0x0024NN.js
vendored
Normal file
72
test/built-ins/String/prototype/replaceAll/getSubstitution-0x0024NN.js
vendored
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
// Copyright (C) 2019 Leo Balter. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-string.prototype.replaceall
|
||||||
|
description: >
|
||||||
|
Replacement Text Symbol Substitutions ($NN)
|
||||||
|
info: |
|
||||||
|
String.prototype.replaceAll ( searchValue, replaceValue )
|
||||||
|
|
||||||
|
10. Let position be ! StringIndexOf(string, searchString, 0).
|
||||||
|
11. Repeat, while position is not -1
|
||||||
|
a. Append position to the end of matchPositions.
|
||||||
|
b. Let position be ! StringIndexOf(string, searchString, position + advanceBy).
|
||||||
|
...
|
||||||
|
14. For each position in matchPositions, do
|
||||||
|
a. If functionalReplace is true, then
|
||||||
|
...
|
||||||
|
b. Else,
|
||||||
|
...
|
||||||
|
ii. Let captures be a new empty List.
|
||||||
|
iii. Let replacement be GetSubstitution(searchString, string, position, captures, undefined, replaceValue).
|
||||||
|
|
||||||
|
StringIndexOf ( string, searchValue, fromIndex )
|
||||||
|
|
||||||
|
...
|
||||||
|
4. Let len be the length of string.
|
||||||
|
5. If searchValue is the empty string, and fromIndex <= len, return fromIndex.
|
||||||
|
6. Let searchLen be the length of searchValue.
|
||||||
|
7. If there exists any integer k such that fromIndex ≤ k ≤ len - searchLen and for all nonnegative integers j less than searchLen, the code unit at index k + j within string is the same as the code unit at index j within searchValue, let pos be the smallest (closest to -∞) such integer. Otherwise, let pos be -1.
|
||||||
|
8. Return pos.
|
||||||
|
|
||||||
|
Runtime Semantics: GetSubstitution ( matched, str, position, captures, namedCaptures, replacement )
|
||||||
|
|
||||||
|
...
|
||||||
|
2. Let matchLength be the number of code units in matched.
|
||||||
|
...
|
||||||
|
4. Let stringLength be the number of code units in str.
|
||||||
|
...
|
||||||
|
9. Let tailPos be position + matchLength.
|
||||||
|
10. Let m be the number of elements in captures.
|
||||||
|
11. Let result be the String value derived from replacement by copying code unit elements from replacement to result while performing replacements as specified in Table 53. These $ replacements are done left-to-right, and, once such a replacement is performed, the new replacement text is not subject to further replacements.
|
||||||
|
12 Return result.
|
||||||
|
|
||||||
|
Table 53: Replacement Text Symbol Substitutions
|
||||||
|
...
|
||||||
|
|
||||||
|
The nnth element of captures, where nn is a two-digit decimal number in the range 01 to 99. If nn ≤ m and the nnth element of captures is undefined, use the empty String instead. If nn is 00 or nn > m, no replacement is done.
|
||||||
|
features: [String.prototype.replaceAll, Symbol.replace]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
var str = 'aaaaaaaaaaaaaaaa aaaaaaaa aaaaaaaaaaaaaaaa';
|
||||||
|
|
||||||
|
var result;
|
||||||
|
|
||||||
|
// captures is always an empty list if GetSubstitution is called from the string value of SearchValue
|
||||||
|
|
||||||
|
result = str.replaceAll('a', '$11');
|
||||||
|
assert.sameValue(result, '$11$11$11$11$11$11$11$11$11$11$11$11$11$11$11$11 $11$11$11$11$11$11$11$11 $11$11$11$11$11$11$11$11$11$11$11$11$11$11$11$11');
|
||||||
|
|
||||||
|
result = str.replaceAll('a', '$29');
|
||||||
|
assert.sameValue(result, '$29$29$29$29$29$29$29$29$29$29$29$29$29$29$29$29 $29$29$29$29$29$29$29$29 $29$29$29$29$29$29$29$29$29$29$29$29$29$29$29$29');
|
||||||
|
|
||||||
|
var customRE = /./g;
|
||||||
|
|
||||||
|
Object.defineProperty(customRE, Symbol.replace, {
|
||||||
|
value: undefined
|
||||||
|
});
|
||||||
|
|
||||||
|
result = '------------------- /./g -------/./g'.replaceAll(customRE, 'a($12$11)');
|
||||||
|
assert.sameValue(result, '------------------- a($12$11) -------a($12$11)');
|
||||||
|
|
21
test/built-ins/String/prototype/replaceAll/length.js
vendored
Normal file
21
test/built-ins/String/prototype/replaceAll/length.js
vendored
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
// Copyright (C) 2019 Leo Balter. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-string.prototype.replaceall
|
||||||
|
description: >
|
||||||
|
String.prototype.replaceAll.length value and descriptor.
|
||||||
|
info: |
|
||||||
|
String.prototype.replaceAll ( searchValue, replaceValue )
|
||||||
|
|
||||||
|
17 ECMAScript Standard Built-in Objects
|
||||||
|
includes: [propertyHelper.js]
|
||||||
|
features: [String.prototype.replaceAll]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
verifyProperty(String.prototype.replaceAll, 'length', {
|
||||||
|
value: 2,
|
||||||
|
enumerable: false,
|
||||||
|
writable: false,
|
||||||
|
configurable: true,
|
||||||
|
});
|
21
test/built-ins/String/prototype/replaceAll/name.js
vendored
Normal file
21
test/built-ins/String/prototype/replaceAll/name.js
vendored
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
// Copyright (C) 2019 Leo Balter. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-string.prototype.replaceall
|
||||||
|
description: >
|
||||||
|
String.prototype.replaceAll.name value and descriptor.
|
||||||
|
info: |
|
||||||
|
String.prototype.replaceAll ( searchValue, replaceValue )
|
||||||
|
|
||||||
|
17 ECMAScript Standard Built-in Objects
|
||||||
|
includes: [propertyHelper.js]
|
||||||
|
features: [String.prototype.replaceAll]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
verifyProperty(String.prototype.replaceAll, 'name', {
|
||||||
|
value: 'replaceAll',
|
||||||
|
enumerable: false,
|
||||||
|
writable: false,
|
||||||
|
configurable: true,
|
||||||
|
});
|
26
test/built-ins/String/prototype/replaceAll/replaceAll.js
vendored
Normal file
26
test/built-ins/String/prototype/replaceAll/replaceAll.js
vendored
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
// Copyright (C) 2019 Leo Balter. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-string.prototype.replaceall
|
||||||
|
description: >
|
||||||
|
Property type and descriptor.
|
||||||
|
info: |
|
||||||
|
String.prototype.replaceAll ( searchValue, replaceValue )
|
||||||
|
|
||||||
|
17 ECMAScript Standard Built-in Objects
|
||||||
|
includes: [propertyHelper.js]
|
||||||
|
features: [String.prototype.replaceAll]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
assert.sameValue(
|
||||||
|
typeof String.prototype.replaceAll,
|
||||||
|
'function',
|
||||||
|
'`typeof String.prototype.replaceAll` is `function`'
|
||||||
|
);
|
||||||
|
|
||||||
|
verifyProperty(String.prototype, 'replaceAll', {
|
||||||
|
enumerable: false,
|
||||||
|
writable: true,
|
||||||
|
configurable: true,
|
||||||
|
});
|
26
test/built-ins/String/prototype/replaceAll/replaceValue-call-abrupt.js
vendored
Normal file
26
test/built-ins/String/prototype/replaceAll/replaceValue-call-abrupt.js
vendored
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
// Copyright (C) 2019 Leo Balter. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-string.prototype.replaceall
|
||||||
|
description: >
|
||||||
|
Return abrupt from Call(replaceValue, ...)
|
||||||
|
info: |
|
||||||
|
String.prototype.replaceAll ( searchValue, replaceValue )
|
||||||
|
|
||||||
|
...
|
||||||
|
5. Let functionalReplace be IsCallable(replaceValue).
|
||||||
|
...
|
||||||
|
14. For each position in matchPositions, do
|
||||||
|
a. If functionalReplace is true, then
|
||||||
|
i. Let replacement be ? ToString(? Call(replaceValue, undefined, « searchString, position, string »).
|
||||||
|
features: [String.prototype.replaceAll]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
function custom() {
|
||||||
|
throw new Test262Error();
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.throws(Test262Error, function() {
|
||||||
|
'a'.replaceAll('a', custom);
|
||||||
|
});
|
42
test/built-ins/String/prototype/replaceAll/replaceValue-call-each-match-position.js
vendored
Normal file
42
test/built-ins/String/prototype/replaceAll/replaceValue-call-each-match-position.js
vendored
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
// Copyright (C) 2019 Leo Balter. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-string.prototype.replaceall
|
||||||
|
description: >
|
||||||
|
If replaceValue is a function, it's called for each matching position
|
||||||
|
info: |
|
||||||
|
String.prototype.replaceAll ( searchValue, replaceValue )
|
||||||
|
|
||||||
|
...
|
||||||
|
5. Let functionalReplace be IsCallable(replaceValue).
|
||||||
|
...
|
||||||
|
14. For each position in matchPositions, do
|
||||||
|
a. If functionalReplace is true, then
|
||||||
|
i. Let replacement be ? ToString(? Call(replaceValue, undefined, « searchString, position, string »).
|
||||||
|
features: [String.prototype.replaceAll]
|
||||||
|
includes: [compareArray.js]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
var t = (function() { return this; })();
|
||||||
|
|
||||||
|
var calls = [];
|
||||||
|
var replaceValue = function(...args) {
|
||||||
|
calls.push([this, ...args]);
|
||||||
|
return 'z';
|
||||||
|
};
|
||||||
|
|
||||||
|
var searchValue = new String('ab c');
|
||||||
|
|
||||||
|
var obj = new String('ab c ab cdab cab c');
|
||||||
|
|
||||||
|
var result = obj.replaceAll(searchValue, replaceValue);
|
||||||
|
assert.sameValue(calls.length, 4);
|
||||||
|
assert.sameValue(result, 'z zdzz');
|
||||||
|
|
||||||
|
var str = obj.toString();
|
||||||
|
|
||||||
|
assert.compareArray(calls[0], [t, 'ab c', 0, str]);
|
||||||
|
assert.compareArray(calls[1], [t, 'ab c', 5, str]);
|
||||||
|
assert.compareArray(calls[2], [t, 'ab c', 10, str]);
|
||||||
|
assert.compareArray(calls[3], [t, 'ab c', 14, str]);
|
39
test/built-ins/String/prototype/replaceAll/replaceValue-call-matching-empty.js
vendored
Normal file
39
test/built-ins/String/prototype/replaceAll/replaceValue-call-matching-empty.js
vendored
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
// Copyright (C) 2019 Leo Balter. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-string.prototype.replaceall
|
||||||
|
description: >
|
||||||
|
replaceValue can be called for matching position of an empty string
|
||||||
|
info: |
|
||||||
|
String.prototype.replaceAll ( searchValue, replaceValue )
|
||||||
|
|
||||||
|
...
|
||||||
|
5. Let functionalReplace be IsCallable(replaceValue).
|
||||||
|
...
|
||||||
|
14. For each position in matchPositions, do
|
||||||
|
a. If functionalReplace is true, then
|
||||||
|
i. Let replacement be ? ToString(? Call(replaceValue, undefined, « searchString, position, string »).
|
||||||
|
features: [String.prototype.replaceAll]
|
||||||
|
includes: [compareArray.js]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
var t = (function() { return this; })();
|
||||||
|
|
||||||
|
var calls = [];
|
||||||
|
var replaceValue = function(...args) {
|
||||||
|
calls.push([this, ...args]);
|
||||||
|
return 'abc';
|
||||||
|
};
|
||||||
|
|
||||||
|
var searchValue = new String('');
|
||||||
|
|
||||||
|
var obj = new String('');
|
||||||
|
|
||||||
|
var result = obj.replaceAll(searchValue, replaceValue);
|
||||||
|
assert.sameValue(calls.length, 1);
|
||||||
|
assert.sameValue(result, 'abc');
|
||||||
|
|
||||||
|
var str = obj.toString();
|
||||||
|
|
||||||
|
assert.compareArray(calls[0], [t, '', 0, str]);
|
32
test/built-ins/String/prototype/replaceAll/replaceValue-call-skip-no-match.js
vendored
Normal file
32
test/built-ins/String/prototype/replaceAll/replaceValue-call-skip-no-match.js
vendored
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
// Copyright (C) 2019 Leo Balter. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-string.prototype.replaceall
|
||||||
|
description: >
|
||||||
|
replaceValue is not called if there isn't a match
|
||||||
|
info: |
|
||||||
|
String.prototype.replaceAll ( searchValue, replaceValue )
|
||||||
|
|
||||||
|
...
|
||||||
|
5. Let functionalReplace be IsCallable(replaceValue).
|
||||||
|
...
|
||||||
|
14. For each position in matchPositions, do
|
||||||
|
a. If functionalReplace is true, then
|
||||||
|
i. Let replacement be ? ToString(? Call(replaceValue, undefined, « searchString, position, string »).
|
||||||
|
features: [String.prototype.replaceAll]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
function replaceValue() {
|
||||||
|
throw new Test262Error();
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.sameValue(
|
||||||
|
'a'.replaceAll('b', replaceValue),
|
||||||
|
'a'
|
||||||
|
);
|
||||||
|
|
||||||
|
assert.sameValue(
|
||||||
|
'a'.replaceAll('aa', replaceValue),
|
||||||
|
'a'
|
||||||
|
);
|
42
test/built-ins/String/prototype/replaceAll/replaceValue-call-tostring-abrupt.js
vendored
Normal file
42
test/built-ins/String/prototype/replaceAll/replaceValue-call-tostring-abrupt.js
vendored
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
// Copyright (C) 2019 Leo Balter. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-string.prototype.replaceall
|
||||||
|
description: >
|
||||||
|
Return abrupt from ToString(Call(replaceValue, ...))
|
||||||
|
info: |
|
||||||
|
String.prototype.replaceAll ( searchValue, replaceValue )
|
||||||
|
|
||||||
|
...
|
||||||
|
5. Let functionalReplace be IsCallable(replaceValue).
|
||||||
|
...
|
||||||
|
14. For each position in matchPositions, do
|
||||||
|
a. If functionalReplace is true, then
|
||||||
|
i. Let replacement be ? ToString(? Call(replaceValue, undefined, « searchString, position, string »).
|
||||||
|
features: [String.prototype.replaceAll, Symbol]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
function custom() {
|
||||||
|
return {
|
||||||
|
toString() {
|
||||||
|
throw new Test262Error();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.throws(Test262Error, function() {
|
||||||
|
'a'.replaceAll('a', custom);
|
||||||
|
});
|
||||||
|
|
||||||
|
function symbol() {
|
||||||
|
return {
|
||||||
|
toString() {
|
||||||
|
return Symbol();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.throws(TypeError, function() {
|
||||||
|
'a'.replaceAll('a', symbol);
|
||||||
|
});
|
39
test/built-ins/String/prototype/replaceAll/replaceValue-fn-skip-toString.js
vendored
Normal file
39
test/built-ins/String/prototype/replaceAll/replaceValue-fn-skip-toString.js
vendored
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
// Copyright (C) 2019 Leo Balter. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-string.prototype.replaceall
|
||||||
|
description: >
|
||||||
|
Skip ToString(replaceValue) if it's a function
|
||||||
|
info: |
|
||||||
|
String.prototype.replaceAll ( searchValue, replaceValue )
|
||||||
|
|
||||||
|
1. Let O be RequireObjectCoercible(this value).
|
||||||
|
2. If searchValue is neither undefined nor null, then
|
||||||
|
...
|
||||||
|
3. Let string be ? ToString(O).
|
||||||
|
4. Let searchString be ? ToString(searchValue).
|
||||||
|
5. Let functionalReplace be IsCallable(replaceValue).
|
||||||
|
6. If functionalReplace is false, then
|
||||||
|
a. Let replaceValue be ? ToString(replaceValue).
|
||||||
|
...
|
||||||
|
features: [String.prototype.replaceAll]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
var called = 0;
|
||||||
|
var replaceValue = function() {
|
||||||
|
called += 1;
|
||||||
|
return 'b';
|
||||||
|
};
|
||||||
|
var poisoned = 0;
|
||||||
|
Object.defineProperty(replaceValue, 'toString', {
|
||||||
|
value: function() {
|
||||||
|
poisoned += 1;
|
||||||
|
throw 'should not call this';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var result = 'aaa'.replaceAll('a', replaceValue);
|
||||||
|
assert.sameValue(called, 3);
|
||||||
|
assert.sameValue(poisoned, 0);
|
||||||
|
assert.sameValue(result, 'bbb');
|
75
test/built-ins/String/prototype/replaceAll/replaceValue-tostring-abrupt.js
vendored
Normal file
75
test/built-ins/String/prototype/replaceAll/replaceValue-tostring-abrupt.js
vendored
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
// Copyright (C) 2019 Leo Balter. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-string.prototype.replaceall
|
||||||
|
description: >
|
||||||
|
Returns abrupt completions from ToString(replaceValue)
|
||||||
|
info: |
|
||||||
|
String.prototype.replaceAll ( searchValue, replaceValue )
|
||||||
|
|
||||||
|
1. Let O be RequireObjectCoercible(this value).
|
||||||
|
2. If searchValue is neither undefined nor null, then
|
||||||
|
...
|
||||||
|
3. Let string be ? ToString(O).
|
||||||
|
4. Let searchString be ? ToString(searchValue).
|
||||||
|
5. Let functionalReplace be IsCallable(replaceValue).
|
||||||
|
6. If functionalReplace is false, then
|
||||||
|
a. Let replaceValue be ? ToString(replaceValue).
|
||||||
|
...
|
||||||
|
features: [String.prototype.replaceAll, Symbol]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
assert.sameValue(
|
||||||
|
typeof String.prototype.replaceAll,
|
||||||
|
'function',
|
||||||
|
'function must exist'
|
||||||
|
);
|
||||||
|
|
||||||
|
var thisValueCalled = 0;
|
||||||
|
var thisValue = {
|
||||||
|
toString() {
|
||||||
|
thisValueCalled += 1;
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var searchValueCalled = 0;
|
||||||
|
var searchValue = {
|
||||||
|
toString() {
|
||||||
|
searchValueCalled += 1;
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var called = 0;
|
||||||
|
var replaceValue = {
|
||||||
|
toString() {
|
||||||
|
called += 1;
|
||||||
|
throw new Test262Error();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
assert.throws(Test262Error, function() {
|
||||||
|
''.replaceAll.call(thisValue, searchValue, replaceValue);
|
||||||
|
}, 'custom');
|
||||||
|
assert.sameValue(called, 1);
|
||||||
|
assert.sameValue(thisValueCalled, 1);
|
||||||
|
assert.sameValue(searchValueCalled, 1);
|
||||||
|
|
||||||
|
searchValueCalled = 0;
|
||||||
|
thisValueCalled = 0;
|
||||||
|
called = 0;
|
||||||
|
replaceValue = {
|
||||||
|
toString() {
|
||||||
|
called += 1;
|
||||||
|
return Symbol();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
assert.throws(TypeError, function() {
|
||||||
|
''.replaceAll.call(thisValue, searchValue, replaceValue);
|
||||||
|
}, 'Symbol');
|
||||||
|
assert.sameValue(called, 1);
|
||||||
|
assert.sameValue(thisValueCalled, 1);
|
||||||
|
assert.sameValue(searchValueCalled, 1);
|
36
test/built-ins/String/prototype/replaceAll/replaceValue-value-replaces-string.js
vendored
Normal file
36
test/built-ins/String/prototype/replaceAll/replaceValue-value-replaces-string.js
vendored
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
// Copyright (C) 2019 Leo Balter. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-string.prototype.replaceall
|
||||||
|
description: >
|
||||||
|
replaceValue is used to replace matching positions in string
|
||||||
|
info: |
|
||||||
|
String.prototype.replaceAll ( searchValue, replaceValue )
|
||||||
|
|
||||||
|
...
|
||||||
|
5. Let functionalReplace be IsCallable(replaceValue).
|
||||||
|
6. If functionalReplace is false, then
|
||||||
|
a. Let replaceValue be ? ToString(replaceValue).
|
||||||
|
...
|
||||||
|
14. For each position in matchPositions, do
|
||||||
|
a. If functionalReplace is true, then
|
||||||
|
...
|
||||||
|
b. Else,
|
||||||
|
...
|
||||||
|
ii. Let captures be a new empty List.
|
||||||
|
iii. Let replacement be GetSubstitution(searchString, string, position, captures, undefined, replaceValue).
|
||||||
|
features: [String.prototype.replaceAll]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
var result = 'aaab a a aac'.replaceAll('aa', 'z');
|
||||||
|
assert.sameValue(result, 'zab a a zc');
|
||||||
|
|
||||||
|
result = 'aaab a a aac'.replaceAll('aa', 'a');
|
||||||
|
assert.sameValue(result, 'aab a a ac');
|
||||||
|
|
||||||
|
result = 'aaab a a aac'.replaceAll('a', 'a');
|
||||||
|
assert.sameValue(result, 'aaab a a aac');
|
||||||
|
|
||||||
|
result = 'aaab a a aac'.replaceAll('a', 'z');
|
||||||
|
assert.sameValue(result, 'zzzb z z zzc');
|
97
test/built-ins/String/prototype/replaceAll/replaceValue-value-tostring.js
vendored
Normal file
97
test/built-ins/String/prototype/replaceAll/replaceValue-value-tostring.js
vendored
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
// Copyright (C) 2019 Leo Balter. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-string.prototype.replaceall
|
||||||
|
description: >
|
||||||
|
ToString(replaceValue)
|
||||||
|
info: |
|
||||||
|
String.prototype.replaceAll ( searchValue, replaceValue )
|
||||||
|
|
||||||
|
...
|
||||||
|
5. Let functionalReplace be IsCallable(replaceValue).
|
||||||
|
6. If functionalReplace is false, then
|
||||||
|
a. Let replaceValue be ? ToString(replaceValue).
|
||||||
|
...
|
||||||
|
14. For each position in matchPositions, do
|
||||||
|
a. If functionalReplace is true, then
|
||||||
|
...
|
||||||
|
b. Else,
|
||||||
|
...
|
||||||
|
ii. Let captures be a new empty List.
|
||||||
|
iii. Let replacement be GetSubstitution(searchString, string, position, captures, undefined, replaceValue).
|
||||||
|
features: [String.prototype.replaceAll, Symbol.toPrimitive]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
var result;
|
||||||
|
|
||||||
|
var called;
|
||||||
|
var replaceValue;
|
||||||
|
|
||||||
|
called = 0;
|
||||||
|
replaceValue = {
|
||||||
|
[Symbol.toPrimitive](){
|
||||||
|
called += 1;
|
||||||
|
return 'z';
|
||||||
|
},
|
||||||
|
toString() {
|
||||||
|
throw 'poison';
|
||||||
|
},
|
||||||
|
valueOf() {
|
||||||
|
throw 'poison';
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
result = 'aa'.replaceAll('a', replaceValue);
|
||||||
|
assert.sameValue(result, 'zz', 'object @@toPrimitive');
|
||||||
|
assert.sameValue(called, 1, '@@toPrimitive is called only once');
|
||||||
|
|
||||||
|
called = 0;
|
||||||
|
replaceValue = {
|
||||||
|
[Symbol.toPrimitive]: undefined,
|
||||||
|
toString() {
|
||||||
|
called += 1;
|
||||||
|
return 'z';
|
||||||
|
},
|
||||||
|
valueOf() {
|
||||||
|
throw 'poison';
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
result = 'aa'.replaceAll('a', replaceValue);
|
||||||
|
assert.sameValue(result, 'zz', 'object toString');
|
||||||
|
assert.sameValue(called, 1, 'toString is called only once');
|
||||||
|
|
||||||
|
called = 0;
|
||||||
|
replaceValue = {
|
||||||
|
[Symbol.toPrimitive]: undefined,
|
||||||
|
toString: undefined,
|
||||||
|
valueOf() {
|
||||||
|
called += 1;
|
||||||
|
return 'z';
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
result = 'aa'.replaceAll('a', replaceValue);
|
||||||
|
assert.sameValue(result, 'zz', 'object valueOf');
|
||||||
|
assert.sameValue(called, 1, 'valueOf is called only once');
|
||||||
|
|
||||||
|
replaceValue = 42;
|
||||||
|
result = 'aa'.replaceAll('a', replaceValue);
|
||||||
|
assert.sameValue(result, '4242', 'number');
|
||||||
|
|
||||||
|
replaceValue = true;
|
||||||
|
result = 'aa'.replaceAll('a', replaceValue);
|
||||||
|
assert.sameValue(result, 'truetrue', 'Boolean true');
|
||||||
|
|
||||||
|
replaceValue = false;
|
||||||
|
result = 'aa'.replaceAll('a', replaceValue);
|
||||||
|
assert.sameValue(result, 'falsefalse', 'Boolean false');
|
||||||
|
|
||||||
|
replaceValue = undefined;
|
||||||
|
result = 'aa'.replaceAll('a', replaceValue);
|
||||||
|
assert.sameValue(result, 'undefinedundefined', 'undefined');
|
||||||
|
|
||||||
|
replaceValue = null;
|
||||||
|
result = 'aa'.replaceAll('a', replaceValue);
|
||||||
|
assert.sameValue(result, 'nullnull', 'null');
|
41
test/built-ins/String/prototype/replaceAll/searchValue-empty-string-this-empty-string.js
vendored
Normal file
41
test/built-ins/String/prototype/replaceAll/searchValue-empty-string-this-empty-string.js
vendored
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
// Copyright (C) 2019 Leo Balter. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-string.prototype.replaceall
|
||||||
|
description: >
|
||||||
|
Matching empty string for the this value and the searchValue
|
||||||
|
info: |
|
||||||
|
String.prototype.replaceAll ( searchValue, replaceValue )
|
||||||
|
|
||||||
|
...
|
||||||
|
5. Let functionalReplace be IsCallable(replaceValue).
|
||||||
|
6. If functionalReplace is false, then
|
||||||
|
a. Let replaceValue be ? ToString(replaceValue).
|
||||||
|
...
|
||||||
|
10. Let position be ! StringIndexOf(string, searchString, 0).
|
||||||
|
11. Repeat, while position is not -1
|
||||||
|
a. Append position to the end of matchPositions.
|
||||||
|
b. Let position be ! StringIndexOf(string, searchString, position + advanceBy).
|
||||||
|
...
|
||||||
|
14. For each position in matchPositions, do
|
||||||
|
a. If functionalReplace is true, then
|
||||||
|
...
|
||||||
|
b. Else,
|
||||||
|
...
|
||||||
|
ii. Let captures be a new empty List.
|
||||||
|
iii. Let replacement be GetSubstitution(searchString, string, position, captures, undefined, replaceValue).
|
||||||
|
|
||||||
|
StringIndexOf ( string, searchValue, fromIndex )
|
||||||
|
|
||||||
|
...
|
||||||
|
4. Let len be the length of string.
|
||||||
|
5. If searchValue is the empty string, and fromIndex <= len, return fromIndex.
|
||||||
|
6. Let searchLen be the length of searchValue.
|
||||||
|
7. If there exists any integer k such that fromIndex ≤ k ≤ len - searchLen and for all nonnegative integers j less than searchLen, the code unit at index k + j within string is the same as the code unit at index j within searchValue, let pos be the smallest (closest to -∞) such integer. Otherwise, let pos be -1.
|
||||||
|
8. Return pos.
|
||||||
|
features: [String.prototype.replaceAll]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
var result = ''.replaceAll('', 'abc');
|
||||||
|
assert.sameValue(result, 'abc');
|
53
test/built-ins/String/prototype/replaceAll/searchValue-empty-string.js
vendored
Normal file
53
test/built-ins/String/prototype/replaceAll/searchValue-empty-string.js
vendored
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
// Copyright (C) 2019 Leo Balter. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-string.prototype.replaceall
|
||||||
|
description: >
|
||||||
|
Replacements when the search value is the empty string
|
||||||
|
info: |
|
||||||
|
String.prototype.replaceAll ( searchValue, replaceValue )
|
||||||
|
|
||||||
|
10. Let position be ! StringIndexOf(string, searchString, 0).
|
||||||
|
11. Repeat, while position is not -1
|
||||||
|
a. Append position to the end of matchPositions.
|
||||||
|
b. Let position be ! StringIndexOf(string, searchString, position + advanceBy).
|
||||||
|
...
|
||||||
|
14. For each position in matchPositions, do
|
||||||
|
a. If functionalReplace is true, then
|
||||||
|
...
|
||||||
|
b. Else,
|
||||||
|
...
|
||||||
|
ii. Let captures be a new empty List.
|
||||||
|
iii. Let replacement be GetSubstitution(searchString, string, position, captures, undefined, replaceValue).
|
||||||
|
|
||||||
|
StringIndexOf ( string, searchValue, fromIndex )
|
||||||
|
|
||||||
|
...
|
||||||
|
4. Let len be the length of string.
|
||||||
|
5. If searchValue is the empty string, and fromIndex <= len, return fromIndex.
|
||||||
|
6. Let searchLen be the length of searchValue.
|
||||||
|
7. If there exists any integer k such that fromIndex ≤ k ≤ len - searchLen and for all nonnegative integers j less than searchLen, the code unit at index k + j within string is the same as the code unit at index j within searchValue, let pos be the smallest (closest to -∞) such integer. Otherwise, let pos be -1.
|
||||||
|
8. Return pos.
|
||||||
|
|
||||||
|
Runtime Semantics: GetSubstitution ( matched, str, position, captures, namedCaptures, replacement )
|
||||||
|
|
||||||
|
...
|
||||||
|
2. Let matchLength be the number of code units in matched.
|
||||||
|
...
|
||||||
|
4. Let stringLength be the number of code units in str.
|
||||||
|
...
|
||||||
|
9. Let tailPos be position + matchLength.
|
||||||
|
10. Let m be the number of elements in captures.
|
||||||
|
11. Let result be the String value derived from replacement by copying code unit elements from replacement to result while performing replacements as specified in Table 53. These $ replacements are done left-to-right, and, once such a replacement is performed, the new replacement text is not subject to further replacements.
|
||||||
|
12 Return result.
|
||||||
|
features: [String.prototype.replaceAll]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
var result;
|
||||||
|
|
||||||
|
result = 'aab c \nx'.replaceAll('', '_');
|
||||||
|
assert.sameValue(result, '_a_a_b_ _c_ _ _\n_x_');
|
||||||
|
|
||||||
|
result = 'a'.replaceAll('', '_');
|
||||||
|
assert.sameValue(result, '_a_');
|
62
test/built-ins/String/prototype/replaceAll/searchValue-flags-no-g-throws.js
vendored
Normal file
62
test/built-ins/String/prototype/replaceAll/searchValue-flags-no-g-throws.js
vendored
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
// Copyright (C) 2019 Leo Balter. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-string.prototype.replaceall
|
||||||
|
description: >
|
||||||
|
Throws a TypeError if flags does not contain "g"
|
||||||
|
info: |
|
||||||
|
String.prototype.replaceAll ( searchValue, replaceValue )
|
||||||
|
|
||||||
|
1. Let O be RequireObjectCoercible(this value).
|
||||||
|
2. If searchValue is neither undefined nor null, then
|
||||||
|
a. Let isRegExp be ? IsRegExp(searchString).
|
||||||
|
b. If isRegExp is true, then
|
||||||
|
i. Let flags be ? Get(searchValue, "flags").
|
||||||
|
ii. Perform ? RequireObjectCoercible(flags).
|
||||||
|
iii. If ? ToString(flags) does not contain "g", throw a TypeError exception.
|
||||||
|
...
|
||||||
|
features: [String.prototype.replaceAll, Symbol.match, Symbol]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
assert.sameValue(
|
||||||
|
typeof String.prototype.replaceAll,
|
||||||
|
'function',
|
||||||
|
'function must exist'
|
||||||
|
);
|
||||||
|
|
||||||
|
var poisoned = 0;
|
||||||
|
var poison = {
|
||||||
|
toString() {
|
||||||
|
poisoned += 1;
|
||||||
|
throw 'Should not call toString on this/replaceValue';
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
var searchValue = /./;
|
||||||
|
|
||||||
|
assert.throws(TypeError, function() {
|
||||||
|
''.replaceAll.call(poison, searchValue, poison);
|
||||||
|
}, 'flags is the empty string');
|
||||||
|
|
||||||
|
Object.defineProperty(searchValue, 'flags', {
|
||||||
|
value: 'G',
|
||||||
|
writable: true,
|
||||||
|
configurable: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.throws(TypeError, function() {
|
||||||
|
''.replaceAll.call(poison, searchValue, poison);
|
||||||
|
}, 'case sensitive G');
|
||||||
|
|
||||||
|
Object.defineProperty(searchValue, 'flags', {
|
||||||
|
value: 'i',
|
||||||
|
writable: true,
|
||||||
|
configurable: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.throws(TypeError, function() {
|
||||||
|
''.replaceAll.call(poison, searchValue, poison);
|
||||||
|
}, 'i');
|
||||||
|
|
||||||
|
assert.sameValue(poisoned, 0);
|
58
test/built-ins/String/prototype/replaceAll/searchValue-flags-null-undefined-throws.js
vendored
Normal file
58
test/built-ins/String/prototype/replaceAll/searchValue-flags-null-undefined-throws.js
vendored
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
// Copyright (C) 2019 Leo Balter. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-string.prototype.replaceall
|
||||||
|
description: >
|
||||||
|
Throws a TypeError if flags is not an ObjectCoercible (null or undefined)
|
||||||
|
info: |
|
||||||
|
String.prototype.replaceAll ( searchValue, replaceValue )
|
||||||
|
|
||||||
|
1. Let O be RequireObjectCoercible(this value).
|
||||||
|
2. If searchValue is neither undefined nor null, then
|
||||||
|
a. Let isRegExp be ? IsRegExp(searchString).
|
||||||
|
b. If isRegExp is true, then
|
||||||
|
i. Let flags be ? Get(searchValue, "flags").
|
||||||
|
ii. Perform ? RequireObjectCoercible(flags).
|
||||||
|
iii. If ? ToString(flags) does not contain "g", throw a TypeError exception.
|
||||||
|
...
|
||||||
|
features: [String.prototype.replaceAll, Symbol.match]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
assert.sameValue(
|
||||||
|
typeof String.prototype.replaceAll,
|
||||||
|
'function',
|
||||||
|
'function must exist'
|
||||||
|
);
|
||||||
|
|
||||||
|
var poisoned = 0;
|
||||||
|
var poison = {
|
||||||
|
toString() {
|
||||||
|
poisoned += 1;
|
||||||
|
throw 'Should not call toString on this/replaceValue';
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
var called = 0;
|
||||||
|
var value = undefined;
|
||||||
|
var searchValue = {
|
||||||
|
[Symbol.match]: true,
|
||||||
|
get flags() {
|
||||||
|
called += 1;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
assert.throws(TypeError, function() {
|
||||||
|
''.replaceAll.call(poison, searchValue, poison);
|
||||||
|
}, 'undefined');
|
||||||
|
assert.sameValue(called, 1);
|
||||||
|
|
||||||
|
called = 0;
|
||||||
|
value = null;
|
||||||
|
assert.throws(TypeError, function() {
|
||||||
|
''.replaceAll.call(poison, searchValue, poison);
|
||||||
|
}, 'null');
|
||||||
|
assert.sameValue(called, 1);
|
||||||
|
|
||||||
|
assert.sameValue(poisoned, 0);
|
58
test/built-ins/String/prototype/replaceAll/searchValue-flags-toString-abrupt.js
vendored
Normal file
58
test/built-ins/String/prototype/replaceAll/searchValue-flags-toString-abrupt.js
vendored
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
// Copyright (C) 2019 Leo Balter. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-string.prototype.replaceall
|
||||||
|
description: >
|
||||||
|
Returns abrupt completions from ToString(flags)
|
||||||
|
info: |
|
||||||
|
String.prototype.replaceAll ( searchValue, replaceValue )
|
||||||
|
|
||||||
|
1. Let O be RequireObjectCoercible(this value).
|
||||||
|
2. If searchValue is neither undefined nor null, then
|
||||||
|
a. Let isRegExp be ? IsRegExp(searchString).
|
||||||
|
b. If isRegExp is true, then
|
||||||
|
i. Let flags be ? Get(searchValue, "flags").
|
||||||
|
ii. Perform ? RequireObjectCoercible(flags).
|
||||||
|
iii. If ? ToString(flags) does not contain "g", throw a TypeError exception.
|
||||||
|
...
|
||||||
|
features: [String.prototype.replaceAll, Symbol.match, Symbol]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
assert.sameValue(
|
||||||
|
typeof String.prototype.replaceAll,
|
||||||
|
'function',
|
||||||
|
'function must exist'
|
||||||
|
);
|
||||||
|
|
||||||
|
var poisoned = 0;
|
||||||
|
var poison = {
|
||||||
|
toString() {
|
||||||
|
poisoned += 1;
|
||||||
|
throw 'Should not call toString on this/replaceValue';
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
var searchValue = {
|
||||||
|
[Symbol.match]: true,
|
||||||
|
flags: Symbol(),
|
||||||
|
toString() {
|
||||||
|
throw 'Should not call toString on searchValue';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
assert.throws(TypeError, function() {
|
||||||
|
''.replaceAll.call(poison, searchValue, poison);
|
||||||
|
}, 'Symbol');
|
||||||
|
|
||||||
|
searchValue.flags = {
|
||||||
|
toString() {
|
||||||
|
throw new Test262Error();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
assert.throws(Test262Error, function() {
|
||||||
|
''.replaceAll.call(poison, searchValue, poison);
|
||||||
|
}, 'custom abrupt');
|
||||||
|
|
||||||
|
assert.sameValue(poisoned, 0);
|
84
test/built-ins/String/prototype/replaceAll/searchValue-get-flags-abrupt.js
vendored
Normal file
84
test/built-ins/String/prototype/replaceAll/searchValue-get-flags-abrupt.js
vendored
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
// Copyright (C) 2019 Leo Balter. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-string.prototype.replaceall
|
||||||
|
description: >
|
||||||
|
Return Abrupt completion from Get(searchValue, "flags")
|
||||||
|
info: |
|
||||||
|
String.prototype.replaceAll ( searchValue, replaceValue )
|
||||||
|
|
||||||
|
1. Let O be RequireObjectCoercible(this value).
|
||||||
|
2. If searchValue is neither undefined nor null, then
|
||||||
|
a. Let isRegExp be ? IsRegExp(searchString).
|
||||||
|
b. If isRegExp is true, then
|
||||||
|
i. Let flags be ? Get(searchValue, "flags").
|
||||||
|
ii. Perform ? RequireObjectCoercible(flags).
|
||||||
|
iii. If ? ToString(flags) does not contain "g", throw a TypeError exception.
|
||||||
|
...
|
||||||
|
features: [String.prototype.replaceAll, Symbol.match]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
var searchValue = {
|
||||||
|
[Symbol.match]: true,
|
||||||
|
get flags() {
|
||||||
|
throw new Test262Error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var poisoned = 0;
|
||||||
|
var poison = {
|
||||||
|
toString() {
|
||||||
|
poisoned += 1;
|
||||||
|
throw 'Should not call toString on this/replaceValue';
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
assert.throws(Test262Error, function() {
|
||||||
|
''.replaceAll.call(poison, searchValue, poison);
|
||||||
|
}, 'from custom searchValue object');
|
||||||
|
|
||||||
|
var re1 = /./;
|
||||||
|
Object.defineProperty(re1, 'flags', {
|
||||||
|
get() { throw new Test262Error(); }
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.throws(Test262Error, function() {
|
||||||
|
''.replaceAll.call(poison, re1, poison);
|
||||||
|
}, 'from RE instance, using default Symbol.match check');
|
||||||
|
|
||||||
|
var called = 0;
|
||||||
|
var re2 = /./;
|
||||||
|
Object.defineProperty(re2, Symbol.match, {
|
||||||
|
get() {
|
||||||
|
called += 1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Object.defineProperty(re2, 'flags', {
|
||||||
|
get() { throw new Test262Error(); }
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.throws(Test262Error, function() {
|
||||||
|
''.replaceAll.call(poison, re2, poison);
|
||||||
|
}, 'from RE instance, using Symbol.match check (true)');
|
||||||
|
assert.sameValue(called, 1);
|
||||||
|
|
||||||
|
called = 0;
|
||||||
|
var re3 = /./;
|
||||||
|
Object.defineProperty(re3, Symbol.match, {
|
||||||
|
get() {
|
||||||
|
called += 1;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Object.defineProperty(re3, 'flags', {
|
||||||
|
get() { throw new Test262Error(); }
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.throws(Test262Error, function() {
|
||||||
|
''.replaceAll.call(poison, re3, poison);
|
||||||
|
}, 'from RE instance, using Symbol.match check (1), uses Internal for IsRegExp');
|
||||||
|
assert.sameValue(called, 1);
|
||||||
|
|
||||||
|
assert.sameValue(poisoned, 0);
|
47
test/built-ins/String/prototype/replaceAll/searchValue-isRegExp-abrupt.js
vendored
Normal file
47
test/built-ins/String/prototype/replaceAll/searchValue-isRegExp-abrupt.js
vendored
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
// Copyright (C) 2019 Leo Balter. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-string.prototype.replaceall
|
||||||
|
description: >
|
||||||
|
Return Abrupt completion from isRegExp
|
||||||
|
info: |
|
||||||
|
String.prototype.replaceAll ( searchValue, replaceValue )
|
||||||
|
|
||||||
|
1. Let O be RequireObjectCoercible(this value).
|
||||||
|
2. If searchValue is neither undefined nor null, then
|
||||||
|
a. Let isRegExp be ? IsRegExp(searchString).
|
||||||
|
...
|
||||||
|
|
||||||
|
IsRegExp ( argument )
|
||||||
|
|
||||||
|
1. If Type(argument) is not Object, return false.
|
||||||
|
2. Let matcher be ? Get(argument, @@match).
|
||||||
|
3. If matcher is not undefined, return ! ToBoolean(matcher).
|
||||||
|
4. If argument has a [[RegExpMatcher]] internal slot, return true.
|
||||||
|
5. Return false.
|
||||||
|
features: [String.prototype.replaceAll, Symbol.match]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
var searchValue = {
|
||||||
|
get [Symbol.match]() {
|
||||||
|
throw new Test262Error();
|
||||||
|
},
|
||||||
|
toString() {
|
||||||
|
throw 'Should not call toString on searchValue';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var poisoned = 0;
|
||||||
|
var poison = {
|
||||||
|
toString() {
|
||||||
|
poisoned += 1;
|
||||||
|
throw 'Should not call toString on this/replaceValue';
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
assert.throws(Test262Error, function() {
|
||||||
|
''.replaceAll.call(poison, searchValue, poison);
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.sameValue(poisoned, 0);
|
129
test/built-ins/String/prototype/replaceAll/searchValue-replace-method-abrupt.js
vendored
Normal file
129
test/built-ins/String/prototype/replaceAll/searchValue-replace-method-abrupt.js
vendored
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
// Copyright (C) 2019 Leo Balter. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-string.prototype.replaceall
|
||||||
|
description: >
|
||||||
|
Return abrupt completion from GetMethod(searchValeu @@replace)
|
||||||
|
info: |
|
||||||
|
String.prototype.replaceAll ( searchValue, replaceValue )
|
||||||
|
|
||||||
|
1. Let O be RequireObjectCoercible(this value).
|
||||||
|
2. If searchValue is neither undefined nor null, then
|
||||||
|
a. Let isRegExp be ? IsRegExp(searchString).
|
||||||
|
b. If isRegExp is true, then
|
||||||
|
i. Let flags be ? Get(searchValue, "flags").
|
||||||
|
ii. Perform ? RequireObjectCoercible(flags).
|
||||||
|
iii. If ? ToString(flags) does not contain "g", throw a TypeError exception.
|
||||||
|
c. Let replacer be ? GetMethod(searchValue, @@replace).
|
||||||
|
...
|
||||||
|
|
||||||
|
GetMethod ( V, P )
|
||||||
|
|
||||||
|
...
|
||||||
|
2. Let func be ? GetV(V, P).
|
||||||
|
3. If func is either undefined or null, return undefined.
|
||||||
|
4. If IsCallable(func) is false, throw a TypeError exception.
|
||||||
|
5. Return func.
|
||||||
|
features: [String.prototype.replaceAll, Symbol, Symbol.match, Symbol.replace]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
var poisoned = 0;
|
||||||
|
var poison = {
|
||||||
|
toString() {
|
||||||
|
poisoned += 1;
|
||||||
|
throw 'Should not call toString on this/replaceValue';
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
var searchValue = {
|
||||||
|
[Symbol.match]: false,
|
||||||
|
flags: 'g',
|
||||||
|
get [Symbol.replace]() {
|
||||||
|
throw new Test262Error();
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
assert.throws(Test262Error, function() {
|
||||||
|
''.replaceAll.call(poison, searchValue, poison);
|
||||||
|
}, 'custom abrupt');
|
||||||
|
|
||||||
|
searchValue = {
|
||||||
|
[Symbol.match]: false,
|
||||||
|
flags: 'g',
|
||||||
|
[Symbol.replace]: {},
|
||||||
|
toString() {
|
||||||
|
throw 'Should not call toString on searchValue';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
assert.throws(TypeError, function() {
|
||||||
|
''.replaceAll.call(poison, searchValue, poison);
|
||||||
|
}, '@@replace is an object (not callable)');
|
||||||
|
|
||||||
|
searchValue = {
|
||||||
|
[Symbol.match]: false,
|
||||||
|
flags: 'g',
|
||||||
|
[Symbol.replace]: '',
|
||||||
|
toString() {
|
||||||
|
throw 'Should not call toString on searchValue';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
assert.throws(TypeError, function() {
|
||||||
|
''.replaceAll.call(poison, searchValue, poison);
|
||||||
|
}, '@@replace is a string');
|
||||||
|
|
||||||
|
searchValue = {
|
||||||
|
[Symbol.match]: false,
|
||||||
|
flags: 'g',
|
||||||
|
[Symbol.replace]: 42,
|
||||||
|
toString() {
|
||||||
|
throw 'Should not call toString on searchValue';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
assert.throws(TypeError, function() {
|
||||||
|
''.replaceAll.call(poison, searchValue, poison);
|
||||||
|
}, '@@replace is a number');
|
||||||
|
|
||||||
|
searchValue = {
|
||||||
|
[Symbol.match]: false,
|
||||||
|
flags: 'g',
|
||||||
|
[Symbol.replace]: Symbol(),
|
||||||
|
toString() {
|
||||||
|
throw 'Should not call toString on searchValue';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
assert.throws(TypeError, function() {
|
||||||
|
''.replaceAll.call(poison, searchValue, poison);
|
||||||
|
}, '@@replace is a symbol');
|
||||||
|
|
||||||
|
searchValue = {
|
||||||
|
[Symbol.match]: false,
|
||||||
|
flags: 'g',
|
||||||
|
[Symbol.replace]: true,
|
||||||
|
toString() {
|
||||||
|
throw 'Should not call toString on searchValue';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
assert.throws(TypeError, function() {
|
||||||
|
''.replaceAll.call(poison, searchValue, poison);
|
||||||
|
}, '@@replace is true');
|
||||||
|
|
||||||
|
searchValue = {
|
||||||
|
[Symbol.match]: false,
|
||||||
|
flags: 'g',
|
||||||
|
[Symbol.replace]: false,
|
||||||
|
toString() {
|
||||||
|
throw 'Should not call toString on searchValue';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
assert.throws(TypeError, function() {
|
||||||
|
''.replaceAll.call(poison, searchValue, poison);
|
||||||
|
}, '@@replace is false');
|
||||||
|
|
||||||
|
assert.sameValue(poisoned, 0);
|
123
test/built-ins/String/prototype/replaceAll/searchValue-replacer-RegExp-call-fn.js
vendored
Normal file
123
test/built-ins/String/prototype/replaceAll/searchValue-replacer-RegExp-call-fn.js
vendored
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
// Copyright (C) 2019 Leo Balter. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-string.prototype.replaceall
|
||||||
|
description: >
|
||||||
|
A RegExp searchValue's Symbol.replace can be called instead of the next steps of replaceAll
|
||||||
|
info: |
|
||||||
|
String.prototype.replaceAll ( searchValue, replaceValue )
|
||||||
|
|
||||||
|
1. Let O be RequireObjectCoercible(this value).
|
||||||
|
2. If searchValue is neither undefined nor null, then
|
||||||
|
a. Let isRegExp be ? IsRegExp(searchString).
|
||||||
|
b. If isRegExp is true, then
|
||||||
|
i. Let flags be ? Get(searchValue, "flags").
|
||||||
|
ii. Perform ? RequireObjectCoercible(flags).
|
||||||
|
iii. If ? ToString(flags) does not contain "g", throw a TypeError exception.
|
||||||
|
c. Let replacer be ? GetMethod(searchValue, @@replace).
|
||||||
|
d. If replacer is not undefined, then
|
||||||
|
i. Return ? Call(replacer, searchValue, « O, replaceValue »).
|
||||||
|
3. Let string be ? ToString(O).
|
||||||
|
4. Let searchString be ? ToString(searchValue).
|
||||||
|
...
|
||||||
|
features: [String.prototype.replaceAll, Symbol.replace, class]
|
||||||
|
includes: [compareArray.js]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
let called = 0;
|
||||||
|
|
||||||
|
class RE extends RegExp {
|
||||||
|
[Symbol.replace](...args) {
|
||||||
|
const actual = super[Symbol.replace](...args);
|
||||||
|
|
||||||
|
// Ordering is intentional to observe call from super
|
||||||
|
called += 1;
|
||||||
|
return actual;
|
||||||
|
}
|
||||||
|
|
||||||
|
toString() {
|
||||||
|
throw 'Should not call toString on searchValue';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const t = (function() { return this; })();
|
||||||
|
let calls;
|
||||||
|
|
||||||
|
function getFn(val) {
|
||||||
|
return function replaceValueFn(...args) {
|
||||||
|
calls.push([this, ...args]);
|
||||||
|
return val;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const samples = [
|
||||||
|
[ '(a)', 'aaa abc', 'z', 'zzz zbc' ],
|
||||||
|
[ '(a)', 'aaa abc', '$1', '$1$1$1 $1bc' ],
|
||||||
|
[ '(a)', 'aaa abc', '$$', '$$$$$$ $$bc' ],
|
||||||
|
[ '(a)', 'aaa abc', '$&', '$&$&$& $&bc' ],
|
||||||
|
[ '(a)', 'aaa abc', '$\'', '$\'$\'$\' $\'bc' ],
|
||||||
|
[ '(a)', 'aaa abc', '$`', '$`$`$` $`bc' ],
|
||||||
|
];
|
||||||
|
|
||||||
|
let count = 0;
|
||||||
|
for (const [ reStr, thisValue, replaceValue, expected ] of samples) {
|
||||||
|
const searchValue = new RE(reStr, 'g');
|
||||||
|
const replaceFn = getFn(replaceValue);
|
||||||
|
|
||||||
|
// Observes the toString
|
||||||
|
const obj = new String(thisValue);
|
||||||
|
|
||||||
|
called = 0;
|
||||||
|
calls = [];
|
||||||
|
|
||||||
|
const actual = obj.replaceAll(searchValue, replaceFn);
|
||||||
|
|
||||||
|
const message = `sample ${count}: '${thisValue}'.replaceAll(/${reStr}/g, () => '${replaceValue}')`;
|
||||||
|
|
||||||
|
assert.sameValue(called, 1, `called -- ${message}`);
|
||||||
|
assert.sameValue(actual, expected, `actual -- ${message}`);
|
||||||
|
|
||||||
|
assert.sameValue(calls.length, 4, `calls.length -- ${message}`);
|
||||||
|
assert.compareArray(calls[0], [t, 'a', 'a', 0, thisValue]);
|
||||||
|
assert.compareArray(calls[1], [t, 'a', 'a', 1, thisValue]);
|
||||||
|
assert.compareArray(calls[2], [t, 'a', 'a', 2, thisValue]);
|
||||||
|
assert.compareArray(calls[3], [t, 'a', 'a', 4, thisValue]);
|
||||||
|
|
||||||
|
count += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const samplesSticky = [
|
||||||
|
[ '(a)', 'aaa abc', 'z', 'zzz abc' ],
|
||||||
|
[ '(a)', 'aaa abc', '$1', '$1$1$1 abc' ],
|
||||||
|
[ '(a)', 'aaa abc', '$$', '$$$$$$ abc' ],
|
||||||
|
[ '(a)', 'aaa abc', '$&', '$&$&$& abc' ],
|
||||||
|
[ '(a)', 'aaa abc', '$\'', '$\'$\'$\' abc' ],
|
||||||
|
[ '(a)', 'aaa abc', '$`', '$`$`$` abc' ],
|
||||||
|
];
|
||||||
|
|
||||||
|
count = 0;
|
||||||
|
for (const [ reStr, thisValue, replaceValue, expected ] of samplesSticky) {
|
||||||
|
const searchValue = new RE(reStr, 'gy');
|
||||||
|
const replaceFn = getFn(replaceValue);
|
||||||
|
|
||||||
|
// Observes the toString
|
||||||
|
const obj = new String(thisValue);
|
||||||
|
|
||||||
|
called = 0;
|
||||||
|
calls = [];
|
||||||
|
|
||||||
|
const actual = obj.replaceAll(searchValue, replaceFn);
|
||||||
|
|
||||||
|
const message = `sample ${count}: '${thisValue}'.replaceAll(/${reStr}/gy, () => '${replaceValue}')`;
|
||||||
|
|
||||||
|
assert.sameValue(called, 1, `called -- ${message}`);
|
||||||
|
assert.sameValue(actual, expected, `actual -- ${message}`);
|
||||||
|
|
||||||
|
assert.sameValue(calls.length, 3, `calls.length -- ${message}`);
|
||||||
|
assert.compareArray(calls[0], [t, 'a', 'a', 0, thisValue]);
|
||||||
|
assert.compareArray(calls[1], [t, 'a', 'a', 1, thisValue]);
|
||||||
|
assert.compareArray(calls[2], [t, 'a', 'a', 2, thisValue]);
|
||||||
|
|
||||||
|
count += 1;
|
||||||
|
}
|
82
test/built-ins/String/prototype/replaceAll/searchValue-replacer-RegExp-call.js
vendored
Normal file
82
test/built-ins/String/prototype/replaceAll/searchValue-replacer-RegExp-call.js
vendored
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
// Copyright (C) 2019 Leo Balter. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-string.prototype.replaceall
|
||||||
|
description: >
|
||||||
|
A RegExp searchValue's Symbol.replace can be called instead of the next steps of replaceAll
|
||||||
|
info: |
|
||||||
|
String.prototype.replaceAll ( searchValue, replaceValue )
|
||||||
|
|
||||||
|
1. Let O be RequireObjectCoercible(this value).
|
||||||
|
2. If searchValue is neither undefined nor null, then
|
||||||
|
a. Let isRegExp be ? IsRegExp(searchString).
|
||||||
|
b. If isRegExp is true, then
|
||||||
|
i. Let flags be ? Get(searchValue, "flags").
|
||||||
|
ii. Perform ? RequireObjectCoercible(flags).
|
||||||
|
iii. If ? ToString(flags) does not contain "g", throw a TypeError exception.
|
||||||
|
c. Let replacer be ? GetMethod(searchValue, @@replace).
|
||||||
|
d. If replacer is not undefined, then
|
||||||
|
i. Return ? Call(replacer, searchValue, « O, replaceValue »).
|
||||||
|
3. Let string be ? ToString(O).
|
||||||
|
4. Let searchString be ? ToString(searchValue).
|
||||||
|
...
|
||||||
|
features: [String.prototype.replaceAll, Symbol.replace, class]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
let called = 0;
|
||||||
|
|
||||||
|
class RE extends RegExp {
|
||||||
|
[Symbol.replace](...args) {
|
||||||
|
const actual = super[Symbol.replace](...args);
|
||||||
|
|
||||||
|
// Ordering is intentional to observe call from super
|
||||||
|
called += 1;
|
||||||
|
return actual;
|
||||||
|
}
|
||||||
|
|
||||||
|
toString() {
|
||||||
|
throw 'Should not call toString on searchValue';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const samples = [
|
||||||
|
[ ['b', 'g'], 'abc abc abc', 'z', 'azc azc azc' ],
|
||||||
|
[ ['b', 'gy'], 'abc abc abc', 'z', 'abc abc abc' ],
|
||||||
|
[ ['b', 'giy'], 'abc abc abc', 'z', 'abc abc abc' ],
|
||||||
|
[ [ '[A-Z]', 'g' ], 'No Uppercase!', '', 'o ppercase!' ],
|
||||||
|
[ [ '[A-Z]', 'gy' ], 'No Uppercase?', '', 'o Uppercase?' ],
|
||||||
|
[ [ '[A-Z]', 'gy' ], 'NO UPPERCASE!', '', ' UPPERCASE!' ],
|
||||||
|
[ [ 'a(b)(ca)', 'g' ], 'abcabcabcabc', '$2-$1', 'ca-bbcca-bbc' ],
|
||||||
|
[ [ '(a(.))', 'g' ], 'abcabcabcabc', '$1$2$3', 'abb$3cabb$3cabb$3cabb$3c' ],
|
||||||
|
[ [ '(((((((((((((a(.).).).).).).).).))))))', 'g' ], 'aabacadaeafagahaiajakalamano a azaya', '($10)-($12)-($1)', '(aabaca)-(aaba)-(aabacadaea)f(agahai)-(agah)-(agahaiajak)(alaman)-(alam)-(alamano a )azaya' ],
|
||||||
|
[ [ 'b', 'g' ], 'abcba', '$\'', 'acbacaa' ],
|
||||||
|
[ [ 'b', 'g' ], 'abcba', '$`', 'aacabca' ],
|
||||||
|
[ [ '(?<named>b)', 'g' ], 'abcba', '($<named>)', 'a(b)c(b)a' ],
|
||||||
|
[ [ '(?<named>b)', 'g' ], 'abcba', '($<named)', 'a($<named)c($<named)a' ],
|
||||||
|
[ [ '(?<named>b)', 'g' ], 'abcba', '($<unnamed>)', 'a()c()a' ],
|
||||||
|
[ [ 'a(b)(ca)', 'g' ], 'abcabcabcabc', '($$)', '($)bc($)bc' ],
|
||||||
|
[ [ 'a(b)(ca)', 'g' ], 'abcabcabcabc', '($)', '($)bc($)bc' ],
|
||||||
|
[ [ 'a(b)(ca)', 'g' ], 'abcabcabcabc', '($$$$)', '($$)bc($$)bc' ],
|
||||||
|
[ [ 'a(b)(ca)', 'g' ], 'abcabcabcabc', '($$$)', '($$)bc($$)bc' ],
|
||||||
|
[ [ 'a(b)(ca)', 'g' ], 'abcabcabcabc', '($$&)', '($&)bc($&)bc' ],
|
||||||
|
[ [ 'a(b)(ca)', 'g' ], 'abcabcabcabc', '($$1)', '($1)bc($1)bc' ],
|
||||||
|
[ [ 'a(b)(ca)', 'g' ], 'abcabcabcabc', '($$`)', '($`)bc($`)bc' ],
|
||||||
|
[ [ 'a(b)(ca)', 'g' ], 'abcabcabcabc', '($$\')', '($\')bc($\')bc' ],
|
||||||
|
[ [ 'a(?<z>b)(ca)', 'g' ], 'abcabcabcabc', '($$<z>)', '($<z>)bc($<z>)bc' ],
|
||||||
|
[ [ 'a(b)(ca)', 'g' ], 'abcabcabcabc', '($&)', '(abca)bc(abca)bc' ],
|
||||||
|
];
|
||||||
|
|
||||||
|
let count = 0;
|
||||||
|
for (const [ [ reStr, flags ], thisValue, replaceValue, expected ] of samples) {
|
||||||
|
const searchValue = new RE(reStr, flags);
|
||||||
|
|
||||||
|
called = 0;
|
||||||
|
const actual = thisValue.replaceAll(searchValue, replaceValue);
|
||||||
|
|
||||||
|
const message = `sample ${count}: '${thisValue}'.replaceAll(/${reStr}/${flags}, '${replaceValue}')`;
|
||||||
|
|
||||||
|
assert.sameValue(called, 1, message);
|
||||||
|
assert.sameValue(actual, expected, message);
|
||||||
|
count += 1;
|
||||||
|
}
|
58
test/built-ins/String/prototype/replaceAll/searchValue-replacer-before-tostring.js
vendored
Normal file
58
test/built-ins/String/prototype/replaceAll/searchValue-replacer-before-tostring.js
vendored
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
// Copyright (C) 2019 Leo Balter. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-string.prototype.replaceall
|
||||||
|
description: >
|
||||||
|
The searchValue is observed before ToString(this value) and ToString(replaceValue)
|
||||||
|
info: |
|
||||||
|
String.prototype.replaceAll ( searchValue, replaceValue )
|
||||||
|
|
||||||
|
1. Let O be RequireObjectCoercible(this value).
|
||||||
|
2. If searchValue is neither undefined nor null, then
|
||||||
|
a. Let isRegExp be ? IsRegExp(searchString).
|
||||||
|
b. If isRegExp is true, then
|
||||||
|
i. Let flags be ? Get(searchValue, "flags").
|
||||||
|
ii. Perform ? RequireObjectCoercible(flags).
|
||||||
|
iii. If ? ToString(flags) does not contain "g", throw a TypeError exception.
|
||||||
|
c. Let replacer be ? GetMethod(searchValue, @@replace).
|
||||||
|
d. If replacer is not undefined, then
|
||||||
|
i. Return ? Call(replacer, searchValue, « O, replaceValue »).
|
||||||
|
3. Let string be ? ToString(O).
|
||||||
|
4. Let searchString be ? ToString(searchValue).
|
||||||
|
...
|
||||||
|
features: [String.prototype.replaceAll, Symbol.replace]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
var called = 0;
|
||||||
|
var searchValue = /./g;
|
||||||
|
Object.defineProperty(searchValue, Symbol.replace, {
|
||||||
|
value: function(O, replaceValue) {
|
||||||
|
assert.sameValue(this, searchValue);
|
||||||
|
assert.sameValue(O, poison, 'first arg is the this value of replaceAll');
|
||||||
|
assert.sameValue(replaceValue, poison, 'second arg is the replaceValue');
|
||||||
|
assert.sameValue(arguments.length, 2);
|
||||||
|
called += 1;
|
||||||
|
return 'return from searchValue';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Object.defineProperty(searchValue, 'toString', {
|
||||||
|
value: function() {
|
||||||
|
throw 'Should not call toString on searchValue';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var poisoned = 0;
|
||||||
|
var poison = {
|
||||||
|
toString() {
|
||||||
|
poisoned += 1;
|
||||||
|
throw 'Should not call toString on this/replaceValue';
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
var returned = ''.replaceAll.call(poison, searchValue, poison);
|
||||||
|
|
||||||
|
assert.sameValue(returned, 'return from searchValue');
|
||||||
|
assert.sameValue(called, 1);
|
||||||
|
assert.sameValue(poisoned, 0);
|
48
test/built-ins/String/prototype/replaceAll/searchValue-replacer-call-abrupt.js
vendored
Normal file
48
test/built-ins/String/prototype/replaceAll/searchValue-replacer-call-abrupt.js
vendored
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
// Copyright (C) 2019 Leo Balter. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-string.prototype.replaceall
|
||||||
|
description: >
|
||||||
|
Return abrupt completion from Call.call(poison, replacer, poison)
|
||||||
|
info: |
|
||||||
|
String.prototype.replaceAll ( searchValue, replaceValue )
|
||||||
|
|
||||||
|
1. Let O be RequireObjectCoercible(this value).
|
||||||
|
2. If searchValue is neither undefined nor null, then
|
||||||
|
a. Let isRegExp be ? IsRegExp(searchString).
|
||||||
|
b. If isRegExp is true, then
|
||||||
|
i. Let flags be ? Get(searchValue, "flags").
|
||||||
|
ii. Perform ? RequireObjectCoercible(flags).
|
||||||
|
iii. If ? ToString(flags) does not contain "g", throw a TypeError exception.
|
||||||
|
c. Let replacer be ? GetMethod(searchValue, @@replace).
|
||||||
|
d. If replacer is not undefined, then
|
||||||
|
i. Return ? Call(replacer, searchValue, « O, replaceValue »).
|
||||||
|
...
|
||||||
|
features: [String.prototype.replaceAll, Symbol.match, Symbol.replace]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
var poisoned = 0;
|
||||||
|
var poison = {
|
||||||
|
toString() {
|
||||||
|
poisoned += 1;
|
||||||
|
throw 'Should not call toString on this/replaceValue';
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
var searchValue = {
|
||||||
|
[Symbol.match]: false,
|
||||||
|
flags: 'g',
|
||||||
|
[Symbol.replace]() {
|
||||||
|
throw new Test262Error();
|
||||||
|
},
|
||||||
|
toString() {
|
||||||
|
throw 'Should not call toString on searchValue';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
assert.throws(Test262Error, function() {
|
||||||
|
''.replaceAll.call(poison, searchValue, poison);
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.sameValue(poisoned, 0);
|
55
test/built-ins/String/prototype/replaceAll/searchValue-replacer-call.js
vendored
Normal file
55
test/built-ins/String/prototype/replaceAll/searchValue-replacer-call.js
vendored
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
// Copyright (C) 2019 Leo Balter. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-string.prototype.replaceall
|
||||||
|
description: >
|
||||||
|
Return value from Call(replacer, ...)
|
||||||
|
info: |
|
||||||
|
String.prototype.replaceAll ( searchValue, replaceValue )
|
||||||
|
|
||||||
|
1. Let O be RequireObjectCoercible(this value).
|
||||||
|
2. If searchValue is neither undefined nor null, then
|
||||||
|
a. Let isRegExp be ? IsRegExp(searchString).
|
||||||
|
b. If isRegExp is true, then
|
||||||
|
i. Let flags be ? Get(searchValue, "flags").
|
||||||
|
ii. Perform ? RequireObjectCoercible(flags).
|
||||||
|
iii. If ? ToString(flags) does not contain "g", throw a TypeError exception.
|
||||||
|
c. Let replacer be ? GetMethod(searchValue, @@replace).
|
||||||
|
d. If replacer is not undefined, then
|
||||||
|
i. Return ? Call(replacer, searchValue, « O, replaceValue »).
|
||||||
|
3. Let string be ? ToString(O).
|
||||||
|
4. Let searchString be ? ToString(searchValue).
|
||||||
|
5. Let functionalReplace be IsCallable(replaceValue).
|
||||||
|
6. If functionalReplace is false, then
|
||||||
|
a. Let replaceValue be ? ToString(replaceValue).
|
||||||
|
...
|
||||||
|
features: [String.prototype.replaceAll, Symbol.replace]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
var called = 0;
|
||||||
|
var searchValue = /./g;
|
||||||
|
Object.defineProperty(searchValue, Symbol.replace, {
|
||||||
|
value: function(O, replaceValue) {
|
||||||
|
assert.sameValue(this, searchValue);
|
||||||
|
assert.sameValue(O, str, 'first arg is the this value of replaceAll');
|
||||||
|
assert.sameValue(replaceValue, obj, 'second arg is the replaceValue');
|
||||||
|
assert.sameValue(arguments.length, 2);
|
||||||
|
called += 1;
|
||||||
|
return 42;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Object.defineProperty(searchValue, 'toString', {
|
||||||
|
value: function() {
|
||||||
|
throw 'Should not call searchValue toString'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var str = new String('Leo');
|
||||||
|
var obj = {};
|
||||||
|
|
||||||
|
var returned = str.replaceAll(searchValue, obj);
|
||||||
|
|
||||||
|
assert.sameValue(returned, 42);
|
||||||
|
assert.sameValue(called, 1);
|
74
test/built-ins/String/prototype/replaceAll/searchValue-tostring-abrupt.js
vendored
Normal file
74
test/built-ins/String/prototype/replaceAll/searchValue-tostring-abrupt.js
vendored
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
// Copyright (C) 2019 Leo Balter. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-string.prototype.replaceall
|
||||||
|
description: >
|
||||||
|
Returns abrupt completions from ToString(searchValue)
|
||||||
|
info: |
|
||||||
|
String.prototype.replaceAll ( searchValue, replaceValue )
|
||||||
|
|
||||||
|
1. Let O be RequireObjectCoercible(this value).
|
||||||
|
2. If searchValue is neither undefined nor null, then
|
||||||
|
...
|
||||||
|
3. Let string be ? ToString(O).
|
||||||
|
4. Let searchString be ? ToString(searchValue).
|
||||||
|
5. Let functionalReplace be IsCallable(replaceValue).
|
||||||
|
6. If functionalReplace is false, then
|
||||||
|
a. Let replaceValue be ? ToString(replaceValue).
|
||||||
|
...
|
||||||
|
features: [String.prototype.replaceAll, Symbol]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
assert.sameValue(
|
||||||
|
typeof String.prototype.replaceAll,
|
||||||
|
'function',
|
||||||
|
'function must exist'
|
||||||
|
);
|
||||||
|
|
||||||
|
var poisoned = 0;
|
||||||
|
var poison = {
|
||||||
|
toString() {
|
||||||
|
poisoned += 1;
|
||||||
|
throw 'Should not call toString on replaceValue';
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
var thisValueCalled = 0;
|
||||||
|
var thisValue = {
|
||||||
|
toString() {
|
||||||
|
thisValueCalled += 1;
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var called = 0;
|
||||||
|
var searchValue = {
|
||||||
|
toString() {
|
||||||
|
called += 1;
|
||||||
|
throw new Test262Error();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
assert.throws(Test262Error, function() {
|
||||||
|
''.replaceAll.call(thisValue, searchValue, poison);
|
||||||
|
}, 'custom');
|
||||||
|
assert.sameValue(called, 1);
|
||||||
|
assert.sameValue(thisValueCalled, 1);
|
||||||
|
|
||||||
|
thisValueCalled = 0;
|
||||||
|
called = 0;
|
||||||
|
searchValue = {
|
||||||
|
toString() {
|
||||||
|
called += 1;
|
||||||
|
return Symbol();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
assert.throws(TypeError, function() {
|
||||||
|
''.replaceAll.call(thisValue, searchValue, poison);
|
||||||
|
}, 'Symbol');
|
||||||
|
assert.sameValue(called, 1);
|
||||||
|
assert.sameValue(thisValueCalled, 1);
|
||||||
|
|
||||||
|
assert.sameValue(poisoned, 0);
|
56
test/built-ins/String/prototype/replaceAll/searchValue-tostring-regexp.js
vendored
Normal file
56
test/built-ins/String/prototype/replaceAll/searchValue-tostring-regexp.js
vendored
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
// Copyright (C) 2019 Leo Balter. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-string.prototype.replaceall
|
||||||
|
description: >
|
||||||
|
ToString(searchValue)
|
||||||
|
info: |
|
||||||
|
String.prototype.replaceAll ( searchValue, replaceValue )
|
||||||
|
|
||||||
|
...
|
||||||
|
4. Let searchString be ? ToString(searchValue).
|
||||||
|
5. Let functionalReplace be IsCallable(replaceValue).
|
||||||
|
6. If functionalReplace is false, then
|
||||||
|
a. Let replaceValue be ? ToString(replaceValue).
|
||||||
|
...
|
||||||
|
14. For each position in matchPositions, do
|
||||||
|
a. If functionalReplace is true, then
|
||||||
|
...
|
||||||
|
b. Else,
|
||||||
|
...
|
||||||
|
ii. Let captures be a new empty List.
|
||||||
|
iii. Let replacement be GetSubstitution(searchString, string, position, captures, undefined, replaceValue).
|
||||||
|
features: [String.prototype.replaceAll, Symbol.replace]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
var result;
|
||||||
|
var searchValue;
|
||||||
|
|
||||||
|
searchValue = /./g;
|
||||||
|
|
||||||
|
Object.defineProperty(searchValue, Symbol.replace, { value: undefined });
|
||||||
|
|
||||||
|
result = 'aa /./g /./g aa'.replaceAll(searchValue, 'z');
|
||||||
|
assert.sameValue(result, 'aa z z aa', '/./g');
|
||||||
|
|
||||||
|
searchValue = /./gy;
|
||||||
|
|
||||||
|
Object.defineProperty(searchValue, Symbol.replace, { value: undefined });
|
||||||
|
|
||||||
|
result = 'aa /./gy /./gy aa'.replaceAll(searchValue, 'z');
|
||||||
|
assert.sameValue(result, 'aa z z aa', '/./gy');
|
||||||
|
|
||||||
|
searchValue = /./gi;
|
||||||
|
|
||||||
|
Object.defineProperty(searchValue, Symbol.replace, { value: undefined });
|
||||||
|
|
||||||
|
result = 'aa /./gi /./gi aa'.replaceAll(searchValue, 'z');
|
||||||
|
assert.sameValue(result, 'aa z z aa', '/./gi');
|
||||||
|
|
||||||
|
searchValue = /./iyg;
|
||||||
|
|
||||||
|
Object.defineProperty(searchValue, Symbol.replace, { value: undefined });
|
||||||
|
|
||||||
|
result = 'aa /./giy /./iyg /./gyi /./giy aa'.replaceAll(searchValue, 'z');
|
||||||
|
assert.sameValue(result, 'aa z /./iyg /./gyi z aa', '/./iyg');
|
30
test/built-ins/String/prototype/replaceAll/this-is-null-throws.js
vendored
Normal file
30
test/built-ins/String/prototype/replaceAll/this-is-null-throws.js
vendored
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
// Copyright (C) 2019 Leo Balter. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-string.prototype.replaceall
|
||||||
|
description: >
|
||||||
|
Throws TypeError when `this` is null
|
||||||
|
info: |
|
||||||
|
String.prototype.replaceAll ( searchValue, replaceValue )
|
||||||
|
|
||||||
|
1. Let O be RequireObjectCoercible(this value).
|
||||||
|
...
|
||||||
|
|
||||||
|
RequireObjectCoercible ( argument )
|
||||||
|
|
||||||
|
- Undefined: Throw a TypeError exception.
|
||||||
|
- Null: Throw a TypeError exception.
|
||||||
|
features: [String.prototype.replaceAll]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
assert.sameValue(
|
||||||
|
typeof String.prototype.replaceAll,
|
||||||
|
'function',
|
||||||
|
'function must exist'
|
||||||
|
);
|
||||||
|
|
||||||
|
assert.throws(TypeError, function() {
|
||||||
|
String.prototype.replaceAll.call(null);
|
||||||
|
});
|
||||||
|
|
29
test/built-ins/String/prototype/replaceAll/this-is-undefined-throws.js
vendored
Normal file
29
test/built-ins/String/prototype/replaceAll/this-is-undefined-throws.js
vendored
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
// Copyright (C) 2019 Leo Balter. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-string.prototype.replaceall
|
||||||
|
description: >
|
||||||
|
Throws TypeError when `this` is undefined
|
||||||
|
info: |
|
||||||
|
String.prototype.replaceAll ( searchValue, replaceValue )
|
||||||
|
|
||||||
|
1. Let O be RequireObjectCoercible(this value).
|
||||||
|
...
|
||||||
|
|
||||||
|
RequireObjectCoercible ( argument )
|
||||||
|
|
||||||
|
- Undefined: Throw a TypeError exception.
|
||||||
|
- Null: Throw a TypeError exception.
|
||||||
|
features: [String.prototype.replaceAll]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
assert.sameValue(
|
||||||
|
typeof String.prototype.replaceAll,
|
||||||
|
'function',
|
||||||
|
'function must exist'
|
||||||
|
);
|
||||||
|
|
||||||
|
assert.throws(TypeError, function() {
|
||||||
|
String.prototype.replaceAll.call(undefined);
|
||||||
|
});
|
65
test/built-ins/String/prototype/replaceAll/this-tostring-abrupt.js
vendored
Normal file
65
test/built-ins/String/prototype/replaceAll/this-tostring-abrupt.js
vendored
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
// Copyright (C) 2019 Leo Balter. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-string.prototype.replaceall
|
||||||
|
description: >
|
||||||
|
Returns abrupt completions from ToString(this value)
|
||||||
|
info: |
|
||||||
|
String.prototype.replaceAll ( searchValue, replaceValue )
|
||||||
|
|
||||||
|
1. Let O be RequireObjectCoercible(this value).
|
||||||
|
2. If searchValue is neither undefined nor null, then
|
||||||
|
...
|
||||||
|
3. Let string be ? ToString(O).
|
||||||
|
...
|
||||||
|
features: [String.prototype.replaceAll, Symbol]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
assert.sameValue(
|
||||||
|
typeof String.prototype.replaceAll,
|
||||||
|
'function',
|
||||||
|
'function must exist'
|
||||||
|
);
|
||||||
|
|
||||||
|
var poisoned = 0;
|
||||||
|
var poison = {
|
||||||
|
toString() {
|
||||||
|
poisoned += 1;
|
||||||
|
throw 'Should not call toString on replaceValue';
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
var called = 0;
|
||||||
|
var thisValue = {
|
||||||
|
toString() {
|
||||||
|
called += 1;
|
||||||
|
throw new Test262Error();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var searchValue = {
|
||||||
|
toString() {
|
||||||
|
throw 'Should not call toString on searchValue';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
assert.throws(Test262Error, function() {
|
||||||
|
''.replaceAll.call(thisValue, searchValue, poison);
|
||||||
|
}, 'custom');
|
||||||
|
assert.sameValue(called, 1);
|
||||||
|
|
||||||
|
called = 0;
|
||||||
|
thisValue = {
|
||||||
|
toString() {
|
||||||
|
called += 1;
|
||||||
|
return Symbol();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
assert.throws(TypeError, function() {
|
||||||
|
''.replaceAll.call(thisValue, searchValue, poison);
|
||||||
|
}, 'Symbol');
|
||||||
|
assert.sameValue(called, 1);
|
||||||
|
|
||||||
|
assert.sameValue(poisoned, 0);
|
91
test/built-ins/String/prototype/replaceAll/this-tostring.js
vendored
Normal file
91
test/built-ins/String/prototype/replaceAll/this-tostring.js
vendored
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
// Copyright (C) 2019 Leo Balter. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
|
||||||
|
/*---
|
||||||
|
esid: sec-string.prototype.replaceall
|
||||||
|
description: >
|
||||||
|
ToString(this value)
|
||||||
|
info: |
|
||||||
|
String.prototype.replaceAll ( searchValue, replaceValue )
|
||||||
|
|
||||||
|
...
|
||||||
|
3. Let string be ? ToString(O).
|
||||||
|
4. Let searchString be ? ToString(searchValue).
|
||||||
|
5. Let functionalReplace be IsCallable(replaceValue).
|
||||||
|
6. If functionalReplace is false, then
|
||||||
|
a. Let replaceValue be ? ToString(replaceValue).
|
||||||
|
...
|
||||||
|
14. For each position in matchPositions, do
|
||||||
|
a. If functionalReplace is true, then
|
||||||
|
...
|
||||||
|
b. Else,
|
||||||
|
...
|
||||||
|
ii. Let captures be a new empty List.
|
||||||
|
iii. Let replacement be GetSubstitution(searchString, string, position, captures, undefined, replaceValue).
|
||||||
|
features: [String.prototype.replaceAll, Symbol.toPrimitive]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
var result;
|
||||||
|
|
||||||
|
var called;
|
||||||
|
var thisValue;
|
||||||
|
|
||||||
|
called = 0;
|
||||||
|
thisValue = {
|
||||||
|
[Symbol.toPrimitive](){
|
||||||
|
called += 1;
|
||||||
|
return 'aa';
|
||||||
|
},
|
||||||
|
toString() {
|
||||||
|
throw 'poison';
|
||||||
|
},
|
||||||
|
valueOf() {
|
||||||
|
throw 'poison';
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
result = ''.replaceAll.call(thisValue, 'a', 'z');
|
||||||
|
assert.sameValue(result, 'zz', 'object @@toPrimitive');
|
||||||
|
assert.sameValue(called, 1, '@@toPrimitive is called only once');
|
||||||
|
|
||||||
|
called = 0;
|
||||||
|
thisValue = {
|
||||||
|
[Symbol.toPrimitive]: undefined,
|
||||||
|
toString() {
|
||||||
|
called += 1;
|
||||||
|
return 'aa';
|
||||||
|
},
|
||||||
|
valueOf() {
|
||||||
|
throw 'poison';
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
result = ''.replaceAll.call(thisValue, 'a', 'z');
|
||||||
|
assert.sameValue(result, 'zz', 'object toString');
|
||||||
|
assert.sameValue(called, 1, 'toString is called only once');
|
||||||
|
|
||||||
|
called = 0;
|
||||||
|
thisValue = {
|
||||||
|
[Symbol.toPrimitive]: undefined,
|
||||||
|
toString: undefined,
|
||||||
|
valueOf() {
|
||||||
|
called += 1;
|
||||||
|
return 'aa';
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
result = ''.replaceAll.call(thisValue, 'a', 'z');
|
||||||
|
assert.sameValue(result, 'zz', 'object valueOf');
|
||||||
|
assert.sameValue(called, 1, 'valueOf is called only once');
|
||||||
|
|
||||||
|
thisValue = 4244;
|
||||||
|
result = ''.replaceAll.call(thisValue, '4', 'z');
|
||||||
|
assert.sameValue(result, 'z2zz', 'number');
|
||||||
|
|
||||||
|
thisValue = true;
|
||||||
|
result = ''.replaceAll.call(thisValue, 'ru', 'o m');
|
||||||
|
assert.sameValue(result, 'to me', 'Boolean true');
|
||||||
|
|
||||||
|
thisValue = false;
|
||||||
|
result = ''.replaceAll.call(thisValue, 'al', 'on');
|
||||||
|
assert.sameValue(result, 'fonse', 'Boolean false');
|
Loading…
x
Reference in New Issue
Block a user