diff options
author | Rick Waldron <waldron.rick@gmail.com> | 2015-09-02 17:20:17 -0400 |
---|---|---|
committer | Rick Waldron <waldron.rick@gmail.com> | 2015-09-02 17:20:17 -0400 |
commit | a2a92d0765c3898bde9b03234cc7824007630053 (patch) | |
tree | 252e80bb78d0dc7090636f105c0d1b26a14844b2 /test/built-ins/RegExp | |
parent | 574c87b1677c3f1b8bfee0d9cc4be3831ab31c4c (diff) | |
parent | bb0cbeb6556c1bd78d1617c1de7284569c91e98a (diff) | |
download | qtdeclarative-testsuites-a2a92d0765c3898bde9b03234cc7824007630053.tar.gz |
Merge pull request #402 from bocoup/symbol-replace
Add tests for well-known Symbol: @@replace
Diffstat (limited to 'test/built-ins/RegExp')
45 files changed, 1436 insertions, 0 deletions
diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/arg-1-coerce-err.js b/test/built-ins/RegExp/prototype/Symbol.replace/arg-1-coerce-err.js new file mode 100644 index 000000000..43eaded35 --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.replace/arg-1-coerce-err.js @@ -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); +}); diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/arg-1-coerce.js b/test/built-ins/RegExp/prototype/Symbol.replace/arg-1-coerce.js new file mode 100644 index 000000000..def76f2ba --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.replace/arg-1-coerce.js @@ -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'); diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/arg-2-coerce-err.js b/test/built-ins/RegExp/prototype/Symbol.replace/arg-2-coerce-err.js new file mode 100644 index 000000000..29beacad6 --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.replace/arg-2-coerce-err.js @@ -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); +}); diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/arg-2-coerce.js b/test/built-ins/RegExp/prototype/Symbol.replace/arg-2-coerce.js new file mode 100644 index 000000000..74da6902d --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.replace/arg-2-coerce.js @@ -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'); diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/coerce-global.js b/test/built-ins/RegExp/prototype/Symbol.replace/coerce-global.js new file mode 100644 index 000000000..c9467aec9 --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.replace/coerce-global.js @@ -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'); diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/coerce-unicode.js b/test/built-ins/RegExp/prototype/Symbol.replace/coerce-unicode.js new file mode 100644 index 000000000..edee4aa8b --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.replace/coerce-unicode.js @@ -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'); diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/exec-err.js b/test/built-ins/RegExp/prototype/Symbol.replace/exec-err.js new file mode 100644 index 000000000..bad4d02d2 --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.replace/exec-err.js @@ -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]('', ''); +}); diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/exec-invocation.js b/test/built-ins/RegExp/prototype/Symbol.replace/exec-invocation.js new file mode 100644 index 000000000..0669de385 --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.replace/exec-invocation.js @@ -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'); diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/fn-coerce-replacement-err.js b/test/built-ins/RegExp/prototype/Symbol.replace/fn-coerce-replacement-err.js new file mode 100644 index 000000000..d4f70ef93 --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.replace/fn-coerce-replacement-err.js @@ -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); +}); diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/fn-coerce-replacement.js b/test/built-ins/RegExp/prototype/Symbol.replace/fn-coerce-replacement.js new file mode 100644 index 000000000..6c087c6c0 --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.replace/fn-coerce-replacement.js @@ -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]'); diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/fn-err.js b/test/built-ins/RegExp/prototype/Symbol.replace/fn-err.js new file mode 100644 index 000000000..1ca987b4b --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.replace/fn-err.js @@ -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); +}); diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/fn-invoke-args.js b/test/built-ins/RegExp/prototype/Symbol.replace/fn-invoke-args.js new file mode 100644 index 000000000..287b79548 --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.replace/fn-invoke-args.js @@ -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'); diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/fn-invoke-this-no-strict.js b/test/built-ins/RegExp/prototype/Symbol.replace/fn-invoke-this-no-strict.js new file mode 100644 index 000000000..654d7b7ef --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.replace/fn-invoke-this-no-strict.js @@ -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()); diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/fn-invoke-this-strict.js b/test/built-ins/RegExp/prototype/Symbol.replace/fn-invoke-this-strict.js new file mode 100644 index 000000000..50acd5f86 --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.replace/fn-invoke-this-strict.js @@ -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); diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/g-init-lastindex-err.js b/test/built-ins/RegExp/prototype/Symbol.replace/g-init-lastindex-err.js new file mode 100644 index 000000000..e941c3999 --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.replace/g-init-lastindex-err.js @@ -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'); +}); diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/g-init-lastindex.js b/test/built-ins/RegExp/prototype/Symbol.replace/g-init-lastindex.js new file mode 100644 index 000000000..1f0e4bfcf --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.replace/g-init-lastindex.js @@ -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'); diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/g-pos-decrement.js b/test/built-ins/RegExp/prototype/Symbol.replace/g-pos-decrement.js new file mode 100644 index 000000000..eafb47d8c --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.replace/g-pos-decrement.js @@ -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); diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/g-pos-increment.js b/test/built-ins/RegExp/prototype/Symbol.replace/g-pos-increment.js new file mode 100644 index 000000000..5370241ec --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.replace/g-pos-increment.js @@ -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); diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/get-exec-err.js b/test/built-ins/RegExp/prototype/Symbol.replace/get-exec-err.js new file mode 100644 index 000000000..45f30bd2d --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.replace/get-exec-err.js @@ -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`'); diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/get-global-err.js b/test/built-ins/RegExp/prototype/Symbol.replace/get-global-err.js new file mode 100644 index 000000000..efb1efc6a --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.replace/get-global-err.js @@ -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); +}); diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/length.js b/test/built-ins/RegExp/prototype/Symbol.replace/length.js new file mode 100644 index 000000000..1686a1bd2 --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.replace/length.js @@ -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'); diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/match-failure.js b/test/built-ins/RegExp/prototype/Symbol.replace/match-failure.js new file mode 100644 index 000000000..fae47dc0e --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.replace/match-failure.js @@ -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'); diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/name.js b/test/built-ins/RegExp/prototype/Symbol.replace/name.js new file mode 100644 index 000000000..67eba90a1 --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.replace/name.js @@ -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'); diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/prop-desc.js b/test/built-ins/RegExp/prototype/Symbol.replace/prop-desc.js new file mode 100644 index 000000000..eb4f5f082 --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.replace/prop-desc.js @@ -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); diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/replace-with-trailing.js b/test/built-ins/RegExp/prototype/Symbol.replace/replace-with-trailing.js new file mode 100644 index 000000000..12b44b8c4 --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.replace/replace-with-trailing.js @@ -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'); diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/replace-without-trailing.js b/test/built-ins/RegExp/prototype/Symbol.replace/replace-without-trailing.js new file mode 100644 index 000000000..0789ef097 --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.replace/replace-without-trailing.js @@ -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'); diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/result-coerce-capture-err.js b/test/built-ins/RegExp/prototype/Symbol.replace/result-coerce-capture-err.js new file mode 100644 index 000000000..849797f30 --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.replace/result-coerce-capture-err.js @@ -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'); +}); diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/result-coerce-capture.js b/test/built-ins/RegExp/prototype/Symbol.replace/result-coerce-capture.js new file mode 100644 index 000000000..044e9916c --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.replace/result-coerce-capture.js @@ -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' +); diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/result-coerce-index-err.js b/test/built-ins/RegExp/prototype/Symbol.replace/result-coerce-index-err.js new file mode 100644 index 000000000..1b230905d --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.replace/result-coerce-index-err.js @@ -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'); +}); diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/result-coerce-index.js b/test/built-ins/RegExp/prototype/Symbol.replace/result-coerce-index.js new file mode 100644 index 000000000..21bf3ee90 --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.replace/result-coerce-index.js @@ -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'); diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/result-coerce-length-err.js b/test/built-ins/RegExp/prototype/Symbol.replace/result-coerce-length-err.js new file mode 100644 index 000000000..55d4a6948 --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.replace/result-coerce-length-err.js @@ -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'); +}); diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/result-coerce-length.js b/test/built-ins/RegExp/prototype/Symbol.replace/result-coerce-length.js new file mode 100644 index 000000000..de4a28a37 --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.replace/result-coerce-length.js @@ -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'); diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/result-coerce-matched-err.js b/test/built-ins/RegExp/prototype/Symbol.replace/result-coerce-matched-err.js new file mode 100644 index 000000000..044935b4d --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.replace/result-coerce-matched-err.js @@ -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'); +}); diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/result-coerce-matched.js b/test/built-ins/RegExp/prototype/Symbol.replace/result-coerce-matched.js new file mode 100644 index 000000000..ba72d7aa9 --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.replace/result-coerce-matched.js @@ -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' +); diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/result-get-capture-err.js b/test/built-ins/RegExp/prototype/Symbol.replace/result-get-capture-err.js new file mode 100644 index 000000000..1f7f141cb --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.replace/result-get-capture-err.js @@ -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'); +}); diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/result-get-index-err.js b/test/built-ins/RegExp/prototype/Symbol.replace/result-get-index-err.js new file mode 100644 index 000000000..7d4e384a2 --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.replace/result-get-index-err.js @@ -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'); +}); diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/result-get-length-err.js b/test/built-ins/RegExp/prototype/Symbol.replace/result-get-length-err.js new file mode 100644 index 000000000..40f9d11d0 --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.replace/result-get-length-err.js @@ -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'); +}); diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/result-get-matched-err.js b/test/built-ins/RegExp/prototype/Symbol.replace/result-get-matched-err.js new file mode 100644 index 000000000..a8cd33399 --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.replace/result-get-matched-err.js @@ -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'); +}); diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/subst-after.js b/test/built-ins/RegExp/prototype/Symbol.replace/subst-after.js new file mode 100644 index 000000000..828f57585 --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.replace/subst-after.js @@ -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'); diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/subst-before.js b/test/built-ins/RegExp/prototype/Symbol.replace/subst-before.js new file mode 100644 index 000000000..8061ec93f --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.replace/subst-before.js @@ -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'); diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/subst-capture-idx-1.js b/test/built-ins/RegExp/prototype/Symbol.replace/subst-capture-idx-1.js new file mode 100644 index 000000000..6073c7ec8 --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.replace/subst-capture-idx-1.js @@ -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 n≤m 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'); diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/subst-capture-idx-2.js b/test/built-ins/RegExp/prototype/Symbol.replace/subst-capture-idx-2.js new file mode 100644 index 000000000..d57eb3aae --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.replace/subst-capture-idx-2.js @@ -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 nn≤m 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' +); diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/subst-dollar.js b/test/built-ins/RegExp/prototype/Symbol.replace/subst-dollar.js new file mode 100644 index 000000000..e47762846 --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.replace/subst-dollar.js @@ -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"' +); diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/subst-matched.js b/test/built-ins/RegExp/prototype/Symbol.replace/subst-matched.js new file mode 100644 index 000000000..f253c0d4a --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.replace/subst-matched.js @@ -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'); diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/this-val-non-obj.js b/test/built-ins/RegExp/prototype/Symbol.replace/this-val-non-obj.js new file mode 100644 index 000000000..25fa93807 --- /dev/null +++ b/test/built-ins/RegExp/prototype/Symbol.replace/this-val-non-obj.js @@ -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); +}); |