Merge pull request #402 from bocoup/symbol-replace

Add tests for well-known Symbol: @@replace
This commit is contained in:
Rick Waldron 2015-09-02 17:20:17 -04:00
commit a2a92d0765
48 changed files with 1511 additions and 0 deletions

View File

@ -0,0 +1,24 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Behavior when error thrown while type coercing first argument
es6id: 21.2.5.8
info: >
21.2.5.8 RegExp.prototype [ @@replace ] ( string, replaceValue )
[...]
3. Let S be ToString(string).
4. ReturnIfAbrupt(S).
features: [Symbol.replace]
---*/
var arg = {
toString: function() {
throw new Test262Error();
}
};
assert.throws(Test262Error, function() {
/./[Symbol.replace](arg);
});

View File

@ -0,0 +1,25 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Type coercion of first argument
es6id: 21.2.5.8
info: >
21.2.5.8 RegExp.prototype [ @@replace ] ( string, replaceValue )
[...]
3. Let S be ToString(string).
[...]
features: [Symbol.replace]
---*/
var arg = {
valueOf: function() {
$ERROR('This method should not be invoked.');
},
toString: function() {
return 'toString value';
}
};
assert.sameValue(/./[Symbol.replace](arg, 'x'), 'xoString value');

View File

@ -0,0 +1,26 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Behavior when error thrown while type coercing second argument
es6id: 21.2.5.8
info: >
21.2.5.8 RegExp.prototype [ @@replace ] ( string, replaceValue )
[...]
6. Let functionalReplace be IsCallable(replaceValue).
7. If functionalReplace is false, then
a. Let replaceValue be ToString(replaceValue).
b. ReturnIfAbrupt(replaceValue).
features: [Symbol.replace]
---*/
var arg = {
toString: function() {
throw new Test262Error();
}
};
assert.throws(Test262Error, function() {
/./[Symbol.replace]('', arg);
});

View File

@ -0,0 +1,27 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Type coercion of second argument
es6id: 21.2.5.8
info: >
21.2.5.8 RegExp.prototype [ @@replace ] ( string, replaceValue )
[...]
6. Let functionalReplace be IsCallable(replaceValue).
7. If functionalReplace is false, then
a. Let replaceValue be ToString(replaceValue).
[...]
features: [Symbol.replace]
---*/
var arg = {
valueOf: function() {
$ERROR('This method should not be invoked.');
},
toString: function() {
return 'toString value';
}
};
assert.sameValue(/./[Symbol.replace]('string', arg), 'toString valuetring');

View File

@ -0,0 +1,47 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Boolean coercion of `global` property
es6id: 21.2.5.8
info: >
21.2.5.6 RegExp.prototype [ @@replace ] ( string )
[...]
8. Let global be ToBoolean(Get(rx, "global")).
[...]
features: [Symbol.replace]
---*/
var r = /a/;
Object.defineProperty(r, 'global', { writable: true });
r.global = undefined;
assert.sameValue(r[Symbol.replace]('aa', 'b'), 'ba');
r.global = null;
assert.sameValue(r[Symbol.replace]('aa', 'b'), 'ba');
r.global = false;
assert.sameValue(r[Symbol.replace]('aa', 'b'), 'ba');
r.global = NaN;
assert.sameValue(r[Symbol.replace]('aa', 'b'), 'ba');
r.global = 0;
assert.sameValue(r[Symbol.replace]('aa', 'b'), 'ba');
r.global = '';
assert.sameValue(r[Symbol.replace]('aa', 'b'), 'ba');
r.global = true;
assert.sameValue(r[Symbol.replace]('aa', 'b'), 'bb');
r.global = 86;
assert.sameValue(r[Symbol.replace]('aa', 'b'), 'bb');
r.global = Symbol.replace;
assert.sameValue(r[Symbol.replace]('aa', 'b'), 'bb');
r.global = {};
assert.sameValue(r[Symbol.replace]('aa', 'b'), 'bb');

View File

@ -0,0 +1,48 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Boolean coercion of `unicode` property
es6id: 21.2.5.8
info: >
21.2.5.6 RegExp.prototype [ @@replace ] ( string )
[...]
10. If global is true, then
a. Let fullUnicode be ToBoolean(Get(rx, "unicode")).
[...]
features: [Symbol.replace]
---*/
var r = /^|\udf06/g;
Object.defineProperty(r, 'unicode', { writable: true });
r.unicode = undefined;
assert.sameValue(r[Symbol.replace]('\ud834\udf06', 'XXX'), 'XXX\ud834XXX');
r.unicode = null;
assert.sameValue(r[Symbol.replace]('\ud834\udf06', 'XXX'), 'XXX\ud834XXX');
r.unicode = false;
assert.sameValue(r[Symbol.replace]('\ud834\udf06', 'XXX'), 'XXX\ud834XXX');
r.unicode = NaN;
assert.sameValue(r[Symbol.replace]('\ud834\udf06', 'XXX'), 'XXX\ud834XXX');
r.unicode = 0;
assert.sameValue(r[Symbol.replace]('\ud834\udf06', 'XXX'), 'XXX\ud834XXX');
r.unicode = '';
assert.sameValue(r[Symbol.replace]('\ud834\udf06', 'XXX'), 'XXX\ud834XXX');
r.unicode = true;
assert.sameValue(r[Symbol.replace]('\ud834\udf06', 'XXX'), 'XXX\ud834\udf06');
r.unicode = 86;
assert.sameValue(r[Symbol.replace]('\ud834\udf06', 'XXX'), 'XXX\ud834\udf06');
r.unicode = Symbol.replace;
assert.sameValue(r[Symbol.replace]('\ud834\udf06', 'XXX'), 'XXX\ud834\udf06');
r.unicode = {};
assert.sameValue(r[Symbol.replace]('\ud834\udf06', 'XXX'), 'XXX\ud834\udf06');

View File

@ -0,0 +1,33 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Behavior when error is thrown by `exec` method
es6id: 21.2.5.8
info: >
21.2.5.8 RegExp.prototype [ @@replace ] ( string, replaceValue )
[...]
13. Repeat, while done is false
a. Let result be RegExpExec(rx, S).
b. ReturnIfAbrupt(result).
21.2.5.2.1 Runtime Semantics: RegExpExec ( R, S )
[...]
3. Let exec be Get(R, "exec").
4. ReturnIfAbrupt(exec).
5. If IsCallable(exec) is true, then
a. Let result be Call(exec, R, «S»).
b. ReturnIfAbrupt(result).
features: [Symbol.replace]
---*/
var r = /./;
r.exec = function() {
throw new Test262Error();
};
assert.throws(Test262Error, function() {
r[Symbol.replace]('', '');
});

View File

@ -0,0 +1,44 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Invocation of `exec` method
es6id: 21.2.5.8
info: >
[...]
13. Repeat, while done is false
a. Let result be RegExpExec(rx, S).
[...]
21.2.5.2.1 Runtime Semantics: RegExpExec ( R, S )
[...]
3. Let exec be Get(R, "exec").
4. ReturnIfAbrupt(exec).
5. If IsCallable(exec) is true, then
a. Let result be Call(exec, R, «S»).
features: [Symbol.match]
---*/
var r = /./;
var callCount = 0;
var arg = {
toString: function() {
return 'string form';
}
};
var thisValue, args;
r.exec = function() {
thisValue = this;
args = arguments;
callCount += 1;
return null;
};
r[Symbol.replace](arg, '');
assert.sameValue(callCount, 1);
assert.sameValue(thisValue, r);
assert.sameValue(args.length, 1);
assert.sameValue(args[0], 'string form');

View File

@ -0,0 +1,34 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
Behavior when error is thrown during string coercion of the value returned
by functional replaceValue
es6id: 21.2.5.8
info: >
16. Repeat, for each result in results,
[...]
m. If functionalReplace is true, then
i. Let replacerArgs be «matched».
ii. Append in list order the elements of captures to the end of the
List replacerArgs.
iii. Append position and S as the last two elements of replacerArgs.
iv. Let replValue be Call(replaceValue, undefined, replacerArgs).
v. Let replacement be ToString(replValue).
[...]
o. ReturnIfAbrupt(replacement).
features: [Symbol.replace]
---*/
var replacer = function() {
return {
toString: function() {
throw new Test262Error();
}
};
};
assert.throws(Test262Error, function() {
/x/[Symbol.replace]('[x]', replacer);
});

View File

@ -0,0 +1,29 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: String coercion of the value returned by functional replaceValue
es6id: 21.2.5.8
info: >
16. Repeat, for each result in results,
[...]
m. If functionalReplace is true, then
i. Let replacerArgs be «matched».
ii. Append in list order the elements of captures to the end of the
List replacerArgs.
iii. Append position and S as the last two elements of replacerArgs.
iv. Let replValue be Call(replaceValue, undefined, replacerArgs).
v. Let replacement be ToString(replValue).
[...]
features: [Symbol.replace]
---*/
var replacer = function() {
return {
toString: function() {
return 'toString value';
}
};
};
assert.sameValue(/x/[Symbol.replace]('[x]', replacer), '[toString value]');

View File

@ -0,0 +1,29 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
Behavior when error is thrown by functional replaceValue.
es6id: 21.2.5.8
info: >
16. Repeat, for each result in results,
[...]
m. If functionalReplace is true, then
i. Let replacerArgs be «matched».
ii. Append in list order the elements of captures to the end of the
List replacerArgs.
iii. Append position and S as the last two elements of replacerArgs.
iv. Let replValue be Call(replaceValue, undefined, replacerArgs).
v. Let replacement be ToString(replValue).
[...]
o. ReturnIfAbrupt(replacement).
features: [Symbol.replace]
---*/
var replacer = function() {
throw new Test262Error();
};
assert.throws(Test262Error, function() {
/./[Symbol.replace]('a', replacer);
});

View File

@ -0,0 +1,33 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Arguments of functional replaceValue
es6id: 21.2.5.8
info: >
16. Repeat, for each result in results,
[...]
m. If functionalReplace is true, then
i. Let replacerArgs be «matched».
ii. Append in list order the elements of captures to the end of the
List replacerArgs.
iii. Append position and S as the last two elements of replacerArgs.
iv. Let replValue be Call(replaceValue, undefined, replacerArgs).
[...]
features: [Symbol.replace]
---*/
var args;
var replacer = function() {
args = arguments;
};
/b(.).(.)/[Symbol.replace]('abcdef', replacer);
assert.notSameValue(args, undefined);
assert.sameValue(args.length, 5);
assert.sameValue(args[0], 'bcde');
assert.sameValue(args[1], 'c');
assert.sameValue(args[2], 'e');
assert.sameValue(args[3], 1);
assert.sameValue(args[4], 'abcdef');

View File

@ -0,0 +1,30 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
`this` value of functional replaceValue (outside of strict mode)
es6id: 21.2.5.8
info: >
16. Repeat, for each result in results,
[...]
m. If functionalReplace is true, then
i. Let replacerArgs be «matched».
ii. Append in list order the elements of captures to the end of the
List replacerArgs.
iii. Append position and S as the last two elements of replacerArgs.
iv. Let replValue be Call(replaceValue, undefined, replacerArgs).
[...]
flags: [noStrict]
includes: [fnGlobalObject.js]
features: [Symbol.replace]
---*/
var thisVal;
var replacer = function() {
thisVal = this;
};
/./[Symbol.replace]('x', replacer);
assert.sameValue(thisVal, fnGlobalObject());

View File

@ -0,0 +1,29 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
`this` value of functional replaceValue (within strict mode)
es6id: 21.2.5.8
info: >
16. Repeat, for each result in results,
[...]
m. If functionalReplace is true, then
i. Let replacerArgs be «matched».
ii. Append in list order the elements of captures to the end of the
List replacerArgs.
iii. Append position and S as the last two elements of replacerArgs.
iv. Let replValue be Call(replaceValue, undefined, replacerArgs).
[...]
flags: [onlyStrict]
features: [Symbol.replace]
---*/
var thisVal = null;
var replacer = function() {
thisVal = this;
};
/./[Symbol.replace]('x', replacer);
assert.sameValue(thisVal, undefined);

View File

@ -0,0 +1,29 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
Behavior when error is thrown while initializing `lastIndex` property for
"global" instances
es6id: 21.2.5.8
info: >
21.2.5.8 RegExp.prototype [ @@replace ] ( string, replaceValue )
[...]
10. If global is true, then
[...]
c. Let setStatus be Set(rx, "lastIndex", 0, true).
d. ReturnIfAbrupt(setStatus).
features: [Symbol.replace]
---*/
var r = /./g;
// Avoid false positives from unrelated TypeErrors
r[Symbol.replace]('x', 'x');
Object.defineProperty(r, 'lastIndex', { writable: false });
assert.throws(TypeError, function() {
r[Symbol.replace]('x', 'x');
});

View File

@ -0,0 +1,22 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Initialization of `lastIndex` property for "global" instances
es6id: 21.2.5.8
info: >
21.2.5.8 RegExp.prototype [ @@replace ] ( string, replaceValue )
[...]
10. If global is true, then
[...]
c. Let setStatus be Set(rx, "lastIndex", 0, true).
[...]
features: [Symbol.replace]
---*/
var r = /./g;
r.lastIndex = 1;
assert.sameValue(r[Symbol.replace]('aa', 'x'), 'xx');

View File

@ -0,0 +1,41 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
Behavior when position is decremented during result accumulation
es6id: 21.2.5.8
info: >
16. Repeat, for each result in results,
[...]
p. If position nextSourcePosition, then
i. NOTE position should not normally move backwards. If it does, it
is an indication of an ill-behaving RegExp subclass or use of an
access triggered side-effect to change the global flag or other
characteristics of rx. In such cases, the corresponding
substitution is ignored.
ii. Let accumulatedResult be the String formed by concatenating the
code units of the current value of accumulatedResult with the
substring of S consisting of the code units from
nextSourcePosition (inclusive) up to position (exclusive) and
with the code units of replacement.
iii. Let nextSourcePosition be position + matchLength.
features: [Symbol.replace]
---*/
var r = /./g;
var callCount = 0;
r.exec = function() {
callCount += 1;
if (callCount === 1) {
return { index: 3, length: 1, 0: 0 };
} else if (callCount === 2) {
return { index: 1, length: 1, 0: 0 };
}
return null;
};
assert.sameValue(r[Symbol.replace]('abcde', 'X'), 'abcXe');
assert.sameValue(callCount, 3);

View File

@ -0,0 +1,41 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
Behavior when position is incremented during result accumulation
es6id: 21.2.5.8
info: >
16. Repeat, for each result in results,
[...]
p. If position nextSourcePosition, then
i. NOTE position should not normally move backwards. If it does, it
is an indication of an ill-behaving RegExp subclass or use of an
access triggered side-effect to change the global flag or other
characteristics of rx. In such cases, the corresponding
substitution is ignored.
ii. Let accumulatedResult be the String formed by concatenating the
code units of the current value of accumulatedResult with the
substring of S consisting of the code units from
nextSourcePosition (inclusive) up to position (exclusive) and
with the code units of replacement.
iii. Let nextSourcePosition be position + matchLength.
features: [Symbol.replace]
---*/
var r = /./g;
var callCount = 0;
r.exec = function() {
callCount += 1;
if (callCount === 1) {
return { index: 1, length: 1, 0: 0 };
} else if (callCount === 2) {
return { index: 3, length: 1, 0: 0 };
}
return null;
};
assert.sameValue(r[Symbol.replace]('abcde', 'X'), 'aXcXe');
assert.sameValue(callCount, 3);

View File

@ -0,0 +1,33 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
Behavior when there is an error thrown while accessing the `exec` method of
"global" instances
es6id: 21.2.5.8
info: >
[...]
13. Repeat, while done is false
a. Let result be RegExpExec(rx, S).
ES6 21.2.5.2.1 Runtime Semantics: RegExpExec ( R, S )
[...]
3. Let exec be Get(R, "exec").
4. ReturnIfAbrupt(exec).
features: [Symbol.match]
---*/
var r = { global: true };
Object.defineProperty(r, 'exec', {
get: function() {
throw new Test262Error();
}
});
assert.throws(Test262Error, function() {
RegExp.prototype[Symbol.replace].call(r, '', '');
});
assert.sameValue(r.lastIndex, 0, 'Error thrown after setting `lastIndex`');

View File

@ -0,0 +1,23 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
Behavior when error is thrown during retrieval of `global` property
es6id: 21.2.5.8
info: >
[...]
8. Let global be ToBoolean(Get(rx, "global")).
9. ReturnIfAbrupt(global).
features: [Symbol.replace]
---*/
var obj = {
get global() {
throw new Test262Error();
}
};
assert.throws(Test262Error, function() {
RegExp.prototype[Symbol.replace].call(obj);
});

View File

@ -0,0 +1,25 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
es6id: 21.2.5.8
description: RegExp.prototype[Symbol.replace] `length` property
info: >
ES6 Section 17:
Every built-in Function object, including constructors, has a length
property whose value is an integer. Unless otherwise specified, this value
is equal to the largest number of named arguments shown in the subclause
headings for the function description, including optional parameters.
[...]
Unless otherwise specified, the length property of a built-in Function
object has the attributes { [[Writable]]: false, [[Enumerable]]: false,
[[Configurable]]: true }.
includes: [propertyHelper.js]
---*/
assert.sameValue(RegExp.prototype[Symbol.replace].length, 2);
verifyNotEnumerable(RegExp.prototype[Symbol.replace], 'length');
verifyNotWritable(RegExp.prototype[Symbol.replace], 'length');
verifyConfigurable(RegExp.prototype[Symbol.replace], 'length');

View File

@ -0,0 +1,27 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Return original string when no matches occur
es6id: 21.2.5.8
info: >
21.2.5.8 RegExp.prototype [ @@replace ] ( string, replaceValue )
[...]
12. Let done be false.
13. Repeat, while done is false
a. Let result be RegExpExec(rx, S).
b. ReturnIfAbrupt(result).
c. If result is null, set done to true.
[...]
14. Let accumulatedResult be the empty String value.
15. Let nextSourcePosition be 0.
[...]
18. Return the String formed by concatenating the code units of
accumulatedResult with the substring of S consisting of the code units
from nextSourcePosition (inclusive) up through the final code unit of S
(inclusive).
features: [Symbol.replace]
---*/
assert.sameValue(/x/[Symbol.replace]('abc', 'X'), 'abc');

View File

@ -0,0 +1,23 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
es6id: 21.2.5.8
description: RegExp.prototype[Symbol.replace] `name` property
info: >
The value of the name property of this function is "[Symbol.replace]".
ES6 Section 17:
[...]
Unless otherwise specified, the name property of a built-in Function
object, if it exists, has the attributes { [[Writable]]: false,
[[Enumerable]]: false, [[Configurable]]: true }.
includes: [propertyHelper.js]
---*/
assert.sameValue(RegExp.prototype[Symbol.replace].name, '[Symbol.replace]');
verifyNotEnumerable(RegExp.prototype[Symbol.replace], 'name');
verifyNotWritable(RegExp.prototype[Symbol.replace], 'name');
verifyConfigurable(RegExp.prototype[Symbol.replace], 'name');

View File

@ -0,0 +1,18 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
es6id: 21.2.5.8
description: RegExp.prototype[Symbol.replace] property descriptor
info: >
ES6 Section 17
Every other data property described in clauses 18 through 26 and in Annex
B.2 has the attributes { [[Writable]]: true, [[Enumerable]]: false,
[[Configurable]]: true } unless otherwise specified.
includes: [propertyHelper.js]
---*/
verifyNotEnumerable(RegExp.prototype, Symbol.replace);
verifyWritable(RegExp.prototype, Symbol.replace);
verifyConfigurable(RegExp.prototype, Symbol.replace);

View File

@ -0,0 +1,24 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
Return value when replacement pattern does not match final code point
es6id: 21.2.5.8
info: >
[...]
18. Return the String formed by concatenating the code units of
accumulatedResult with the substring of S consisting of the code units
from nextSourcePosition (inclusive) up through the final code unit of S
(inclusive).
features: [Symbol.replace]
---*/
assert.sameValue(/abc/[Symbol.replace]('abcd', 'X'), 'Xd');
assert.sameValue(/bc/[Symbol.replace]('abcd', 'X'), 'aXd');
assert.sameValue(/c/[Symbol.replace]('abcd', 'X'), 'abXd');
assert.sameValue(/ab/[Symbol.replace]('abcd', 'X'), 'Xcd');
assert.sameValue(/b/[Symbol.replace]('abcd', 'X'), 'aXcd');
assert.sameValue(/a/[Symbol.replace]('abcd', 'X'), 'Xbcd');

View File

@ -0,0 +1,16 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Return value when replacement pattern matches final code point
es6id: 21.2.5.8
info: >
[...]
17. If nextSourcePosition lengthS, return accumulatedResult.
features: [Symbol.replace]
---*/
assert.sameValue(/abcd/[Symbol.replace]('abcd', 'X'), 'X');
assert.sameValue(/bcd/[Symbol.replace]('abcd', 'X'), 'aX');
assert.sameValue(/cd/[Symbol.replace]('abcd', 'X'), 'abX');
assert.sameValue(/d/[Symbol.replace]('abcd', 'X'), 'abcX');

View File

@ -0,0 +1,39 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
Behavior when error is thrown while type coercing `1` property of result
es6id: 21.2.5.8
info: >
[...]
13. Repeat, while done is false
a. Let result be RegExpExec(rx, S).
[...]
16. Repeat, for each result in results,
[...]
l. Repeat while n nCaptures
i. Let capN be Get(result, ToString(n)).
ii. ReturnIfAbrupt(capN).
iii. If capN is not undefined, then
1. Let capN be ToString(capN).
2. ReturnIfAbrupt(capN).
features: [Symbol.replace]
---*/
var r = /./;
var uncoercibleValue = {
length: 2,
1: {
toString: function() {
throw new Test262Error();
}
}
};
r.exec = function() {
return uncoercibleValue;
};
assert.throws(Test262Error, function() {
r[Symbol.replace]('a', 'b');
});

View File

@ -0,0 +1,38 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Type coercion of `1` property of result
es6id: 21.2.5.8
info: >
[...]
13. Repeat, while done is false
a. Let result be RegExpExec(rx, S).
[...]
16. Repeat, for each result in results,
[...]
l. Repeat while n nCaptures
i. Let capN be Get(result, ToString(n)).
ii. ReturnIfAbrupt(capN).
iii. If capN is not undefined, then
1. Let capN be ToString(capN).
[...]
features: [Symbol.replace]
---*/
var r = /./;
var coercibleValue = {
length: 4,
3: {
toString: function() {
return 'toString value';
}
}
};
r.exec = function() {
return coercibleValue;
};
assert.sameValue(
r[Symbol.replace]('', 'foo[$3]bar'), 'foo[toString value]bar'
);

View File

@ -0,0 +1,35 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
Behavior when error is thrown while type coercing `index` property of
result
es6id: 21.2.5.8
info: >
[...]
13. Repeat, while done is false
a. Let result be RegExpExec(rx, S).
[...]
16. Repeat, for each result in results,
[...]
g. Let position be ToInteger(Get(result, "index")).
h. ReturnIfAbrupt(position).
features: [Symbol.replace]
---*/
var r = /./;
var uncoercibleIndex = {
index: {
valueOf: function() {
throw new Test262Error();
}
}
};
r.exec = function() {
return uncoercibleIndex;
};
assert.throws(Test262Error, function() {
r[Symbol.replace]('a', 'b');
});

View File

@ -0,0 +1,33 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
Type coercion of `index` property of result
es6id: 21.2.5.8
info: >
[...]
13. Repeat, while done is false
a. Let result be RegExpExec(rx, S).
[...]
16. Repeat, for each result in results,
[...]
g. Let position be ToInteger(Get(result, "index")).
[...]
features: [Symbol.replace]
---*/
var r = /./;
var counter = 0;
var coercibleIndex = {
index: {
valueOf: function() {
return 2.9;
}
}
};
r.exec = function() {
return coercibleIndex;
};
assert.sameValue(r[Symbol.replace]('abcd', ''), 'ab');

View File

@ -0,0 +1,34 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
Behavior when error is thrown while type coercing `length` property of
result
es6id: 21.2.5.8
info: >
[...]
13. Repeat, while done is false
a. Let result be RegExpExec(rx, S).
[...]
16. Repeat, for each result in results,
a. Let nCaptures be ToLength(Get(result, "length")).
b. ReturnIfAbrupt(nCaptures).
features: [Symbol.match]
---*/
var r = /./;
var uncoercibleLength = {
length: {
valueOf: function() {
throw new Test262Error();
}
}
};
r.exec = function() {
return uncoercibleLength;
};
assert.throws(Test262Error, function() {
r[Symbol.replace]('a', 'b');
});

View File

@ -0,0 +1,36 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
Type coercion of `length` property of result
es6id: 21.2.5.8
info: >
[...]
13. Repeat, while done is false
a. Let result be RegExpExec(rx, S).
[...]
16. Repeat, for each result in results,
a. Let nCaptures be ToLength(Get(result, "length")).
[...]
features: [Symbol.replace]
---*/
var r = /./;
var counter = 0;
var coercibleIndex = {
length: {
valueOf: function() {
return 3.9;
}
},
0: '',
1: 'foo',
2: 'bar',
3: 'baz'
};
r.exec = function() {
return coercibleIndex;
};
assert.sameValue(r[Symbol.replace]('', '$1$2$3'), 'foobar$3');

View File

@ -0,0 +1,34 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
Behavior when error is thrown while type coercing `0` property of result
es6id: 21.2.5.8
info: >
[...]
13. Repeat, while done is false
a. Let result be RegExpExec(rx, S).
[...]
16. Repeat, for each result in results,
[...]
d. Let matched be ToString(Get(result, "0")).
e. ReturnIfAbrupt(matched).
features: [Symbol.replace]
---*/
var r = /./;
var uncoercibleValue = {
0: {
toString: function() {
throw new Test262Error();
}
}
};
r.exec = function() {
return uncoercibleValue;
};
assert.throws(Test262Error, function() {
r[Symbol.replace]('a', 'b');
});

View File

@ -0,0 +1,33 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Type coercion of `0` property of result
es6id: 21.2.5.8
info: >
[...]
13. Repeat, while done is false
a. Let result be RegExpExec(rx, S).
[...]
16. Repeat, for each result in results,
[...]
d. Let matched be ToString(Get(result, "0")).
[...]
features: [Symbol.replace]
---*/
var r = /./;
var coercibleValue = {
0: {
toString: function() {
return 'toString value';
}
}
};
r.exec = function() {
return coercibleValue;
};
assert.sameValue(
r[Symbol.replace]('', 'foo[$&]bar'), 'foo[toString value]bar'
);

View File

@ -0,0 +1,34 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
Behavior when error is thrown while accessing `1` property of result
es6id: 21.2.5.8
info: >
[...]
13. Repeat, while done is false
a. Let result be RegExpExec(rx, S).
[...]
16. Repeat, for each result in results,
[...]
l. Repeat while n nCaptures
i. Let capN be Get(result, ToString(n)).
ii. ReturnIfAbrupt(capN).
features: [Symbol.replace]
---*/
var r = /./;
var poisonedValue = {
length: 2,
get 1() {
throw new Test262Error();
}
};
r.exec = function() {
return poisonedValue;
};
assert.throws(Test262Error, function() {
r[Symbol.replace]('a', 'b');
});

View File

@ -0,0 +1,32 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
Behavior when error is thrown while accessing `index` property of result
es6id: 21.2.5.8
info: >
[...]
13. Repeat, while done is false
a. Let result be RegExpExec(rx, S).
[...]
16. Repeat, for each result in results,
[...]
g. Let position be ToInteger(Get(result, "index")).
h. ReturnIfAbrupt(position).
features: [Symbol.replace]
---*/
var r = /./;
var poisonedIndex = {
get index() {
throw new Test262Error();
}
};
r.exec = function() {
return poisonedIndex;
};
assert.throws(Test262Error, function() {
r[Symbol.replace]('a', 'b');
});

View File

@ -0,0 +1,31 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
Behavior when error is thrown while accessing `length` property of result
es6id: 21.2.5.8
info: >
[...]
13. Repeat, while done is false
a. Let result be RegExpExec(rx, S).
[...]
16. Repeat, for each result in results,
a. Let nCaptures be ToLength(Get(result, "length")).
b. ReturnIfAbrupt(nCaptures).
features: [Symbol.match]
---*/
var r = /./;
var poisonedLength = {
get length() {
throw new Test262Error();
}
};
r.exec = function() {
return poisonedLength;
};
assert.throws(Test262Error, function() {
r[Symbol.replace]('a', 'b');
});

View File

@ -0,0 +1,32 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
Behavior when error is thrown while accessing `0` property of result
es6id: 21.2.5.8
info: >
[...]
13. Repeat, while done is false
a. Let result be RegExpExec(rx, S).
[...]
16. Repeat, for each result in results,
[...]
d. Let matched be ToString(Get(result, "0")).
e. ReturnIfAbrupt(matched).
features: [Symbol.replace]
---*/
var r = /./;
var poisonedValue = {
get 0() {
throw new Test262Error();
}
};
r.exec = function() {
return poisonedValue;
};
assert.throws(Test262Error, function() {
r[Symbol.replace]('a', 'b');
});

View File

@ -0,0 +1,32 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
Substitution pattern: text after match
es6id: 21.2.5.8
info: >
16. Repeat, for each result in results,
[...]
m. If functionalReplace is true, then
[...]
n. Else,
i. Let replacement be GetSubstitution(matched, S, position,
captures, replaceValue).
[...]
21.1.3.14.1 Runtime Semantics: GetSubstitution
Code units: 0x0024, 0x0027
Unicode Characters: $'
Replacement text:
If tailPos stringLength, the replacement is the empty String. Otherwise
the replacement is the substring of str that starts at index tailPos and
continues to the end of str.
features: [Symbol.replace]
---*/
assert.sameValue(/c/[Symbol.replace]('abc', '[$\']'), 'ab[]');
assert.sameValue(/b/[Symbol.replace]('abc', '[$\']'), 'a[c]c');

View File

@ -0,0 +1,32 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
Substitution pattern: text before match
es6id: 21.2.5.8
info: >
16. Repeat, for each result in results,
[...]
m. If functionalReplace is true, then
[...]
n. Else,
i. Let replacement be GetSubstitution(matched, S, position,
captures, replaceValue).
[...]
21.1.3.14.1 Runtime Semantics: GetSubstitution
Code units: 0x0024, 0x0060
Unicode Characters: $`
Replacement text:
If position is 0, the replacement is the empty String. Otherwise the
replacement is the substring of str that starts at index 0 and whose last
code unit is at index `position-1`.
features: [Symbol.replace]
---*/
assert.sameValue(/a/[Symbol.replace]('abc', '[$`]'), '[]bc');
assert.sameValue(/b/[Symbol.replace]('abc', '[$`]'), 'a[a]c');

View File

@ -0,0 +1,35 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
Substitution pattern: one-digit capturing group reference
es6id: 21.2.5.8
info: >
16. Repeat, for each result in results,
[...]
m. If functionalReplace is true, then
[...]
n. Else,
i. Let replacement be GetSubstitution(matched, S, position,
captures, replaceValue).
[...]
21.1.3.14.1 Runtime Semantics: GetSubstitution
Code units:
0x0024, N
Where 0x0031 N 0x0039
Unicode Characters:
$n where
n is one of 1 2 3 4 5 6 7 8 9 and $n is not followed by a decimal digit
Replacement text:
The nth element of captures, where n is a single digit in the range 1 to 9.
If nm and the nth element of captures is undefined, use the empty String
instead. If n>m, the result is implementation-defined.
features: [Symbol.replace]
---*/
assert.sameValue(/b(c)(z)?(.)/[Symbol.replace]('abcde', '[$1$2$3]'), 'a[cd]e');

View File

@ -0,0 +1,38 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
Substitution pattern: two-digit capturing group reference
es6id: 21.2.5.8
info: >
16. Repeat, for each result in results,
[...]
m. If functionalReplace is true, then
[...]
n. Else,
i. Let replacement be GetSubstitution(matched, S, position,
captures, replaceValue).
[...]
21.1.3.14.1 Runtime Semantics: GetSubstitution
Code units:
0x0024, N, N
Where 0x0030 N 0x0039
Unicode Characters:
$nn where
n is one of 0 1 2 3 4 5 6 7 8 9
Replacement text:
The nnth element of captures, where nn is a two-digit decimal number in the
range 01 to 99. If nnm and the nnth element of captures is undefined, use
the empty String instead. If nn is 00 or nn>m, the result is
implementation-defined.
features: [Symbol.replace]
---*/
assert.sameValue(
/b(c)(z)?(.)/[Symbol.replace]('abcde', '[$01$02$03]'), 'a[cd]e'
);

View File

@ -0,0 +1,43 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
Substitution pattern: dollar sign
es6id: 21.2.5.8
info: >
16. Repeat, for each result in results,
[...]
m. If functionalReplace is true, then
[...]
n. Else,
i. Let replacement be GetSubstitution(matched, S, position,
captures, replaceValue).
[...]
21.1.3.14.1 Runtime Semantics: GetSubstitution
Code units: 0x0024, 0x0024
Unicode Characters: $$
Replacement text: $
[...]
Code units: 0x0024
Unicode Characters: $ in any context that does not match any of the above.
Replacement text: $
features: [Symbol.replace]
---*/
assert.sameValue(/./[Symbol.replace]('abc', '$$'), '$bc', '"escaped" version');
assert.sameValue(
/./[Symbol.replace]('abc', '$'), '$bc', '"unescaped" version'
);
assert.sameValue(
/./[Symbol.replace]('abc', '\\$'), '\\$bc', 'backslash-prefixed'
);
assert.sameValue(
/./[Symbol.replace]('abc', '$$$'),
'$$bc',
'"escaped" followed by "unuescaped"'
);

View File

@ -0,0 +1,26 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
Substitution pattern: matched string
es6id: 21.2.5.8
info: >
16. Repeat, for each result in results,
[...]
m. If functionalReplace is true, then
[...]
n. Else,
i. Let replacement be GetSubstitution(matched, S, position,
captures, replaceValue).
[...]
21.1.3.14.1 Runtime Semantics: GetSubstitution
Code units: 0x0024, 0x0026
Unicode Characters: $&
Replacement text: matched
features: [Symbol.replace]
---*/
assert.sameValue(/.4?./[Symbol.replace]('abc', '[$&]'), '[ab]c');

View File

@ -0,0 +1,39 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: The `this` value must be an object
es6id: 21.2.5.8
info: >
1. Let rx be the this value.
2. If Type(rx) is not Object, throw a TypeError exception.
features: [Symbol.replace]
---*/
assert.throws(TypeError, function() {
RegExp.prototype[Symbol.replace].call();
});
assert.throws(TypeError, function() {
RegExp.prototype[Symbol.replace].call(undefined);
});
assert.throws(TypeError, function() {
RegExp.prototype[Symbol.replace].call(null);
});
assert.throws(TypeError, function() {
RegExp.prototype[Symbol.replace].call(true);
});
assert.throws(TypeError, function() {
RegExp.prototype[Symbol.replace].call('string');
});
assert.throws(TypeError, function() {
RegExp.prototype[Symbol.replace].call(Symbol.replace);
});
assert.throws(TypeError, function() {
RegExp.prototype[Symbol.replace].call(86);
});

View File

@ -0,0 +1,24 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Behavior when error is thrown accessing @@replace property
es6id: 21.1.3.14
info: >
[...]
3. If searchValue is neither undefined nor null, then
a. Let replacer be GetMethod(searchValue, @@replace).
b. ReturnIfAbrupt(replacer).
features: [Symbol.replace]
---*/
var poisonedReplace = {};
Object.defineProperty(poisonedReplace, Symbol.replace, {
get: function() {
throw new Test262Error();
}
});
assert.throws(Test262Error, function() {
''.replace(poisonedReplace);
});

View File

@ -0,0 +1,34 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Invocation of @@replace property of user-supplied objects
es6id: 21.1.3.14
info: >
[...]
3. If searchValue is neither undefined nor null, then
a. Let replacer be GetMethod(searchValue, @@replace).
b. ReturnIfAbrupt(replacer).
c. If replacer is not undefined, then
i. Return Call(replacer, searchValue, «O, replaceValue»).
features: [Symbol.replace]
---*/
var searchValue = {};
var returnVal = {};
var callCount = 0;
var thisVal, args;
searchValue[Symbol.replace] = function() {
callCount += 1;
thisVal = this;
args = arguments;
return returnVal;
};
assert.sameValue(''.replace(searchValue, 'replace value'), returnVal);
assert.sameValue(thisVal, searchValue);
assert.notSameValue(args, undefined);
assert.sameValue(args.length, 2);
assert.sameValue(args[0], '');
assert.sameValue(args[1], 'replace value');

View File

@ -0,0 +1,17 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
es6id: 19.4.2.8
description: >
`Symbol.replace` property descriptor
info: >
This property has the attributes { [[Writable]]: false, [[Enumerable]]:
false, [[Configurable]]: false }.
includes: [propertyHelper.js]
features: [Symbol.replace]
---*/
assert.sameValue(typeof Symbol.replace, 'symbol');
verifyNotEnumerable(Symbol, 'replace');
verifyNotWritable(Symbol, 'replace');
verifyNotConfigurable(Symbol, 'replace');