mirror of https://github.com/tc39/test262.git
parent
7040938bd0
commit
3682ddd7e3
|
@ -158,6 +158,10 @@ Intl.DisplayNames
|
|||
Promise.any
|
||||
AggregateError
|
||||
|
||||
# String.prototype.replaceAll
|
||||
# https://github.com/tc39/proposal-string-replaceall
|
||||
String.prototype.replaceAll
|
||||
|
||||
## Standard language features
|
||||
#
|
||||
# Language features that have been included in a published version of the
|
||||
|
|
|
@ -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.');
|
|
@ -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.');
|
|
@ -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.');
|
|
@ -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($<$<)');
|
||||
|
|
@ -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.');
|
|
@ -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.');
|
|
@ -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) ---');
|
||||
|
|
@ -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)');
|
||||
|
|
@ -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,
|
||||
});
|
|
@ -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,
|
||||
});
|
|
@ -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,
|
||||
});
|
|
@ -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);
|
||||
});
|
|
@ -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');
|
|
@ -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');
|
|
@ -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');
|
|
@ -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_');
|
|
@ -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);
|
|
@ -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);
|
|
@ -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);
|
|
@ -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);
|
|
@ -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);
|
|
@ -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');
|
|
@ -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);
|
||||
});
|
||||
|
|
@ -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);
|
||||
});
|
|
@ -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);
|
|
@ -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…
Reference in New Issue