summaryrefslogtreecommitdiffstats
path: root/js/src/tests/test262/built-ins/String/prototype/replaceAll/searchValue-replacer-method-abrupt.js
blob: 1556a15ef10eeacc704016f6802d6b30084aa535 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// Copyright (C) 2019 Leo Balter. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-string.prototype.replaceall
description: >
  Return abrupt completion from GetMethod(searchValue.@@replace)
info: |
  String.prototype.replaceAll ( searchValue, replaceValue )

  1. Let O be RequireObjectCoercible(this value).
  2. If searchValue is neither undefined nor null, then
    a. Let isRegExp be ? IsRegExp(searchString).
    b. If isRegExp is true, then
      i. Let flags be ? Get(searchValue, "flags").
      ii. Perform ? RequireObjectCoercible(flags).
      iii. If ? ToString(flags) does not contain "g", throw a TypeError exception.
    c. Let replacer be ? GetMethod(searchValue, @@replace).
  ...

  GetMethod ( V, P )

  ...
  2. Let func be ? GetV(V, P).
  3. If func is either undefined or null, return undefined.
  4. If IsCallable(func) is false, throw a TypeError exception.
  5. Return func. 
features: [String.prototype.replaceAll, Symbol, Symbol.match, Symbol.replace]
---*/

var poisoned = 0;
var poison = {
  toString() {
    poisoned += 1;
    throw 'Should not call toString on this/replaceValue';
  },
};

var searchValue = {
  [Symbol.match]: false,
  flags: 'g',
  get [Symbol.replace]() {
    throw new Test262Error();
  },
};

assert.throws(Test262Error, function() {
  ''.replaceAll.call(poison, searchValue, poison);
}, 'custom abrupt');

searchValue = {
  [Symbol.match]: false,
  flags: 'g',
  [Symbol.replace]: {},
  toString() {
    throw 'Should not call toString on searchValue';
  }
};

assert.throws(TypeError, function() {
  ''.replaceAll.call(poison, searchValue, poison);
}, '@@replace is an object (not callable)');

searchValue = {
  [Symbol.match]: false,
  flags: 'g',
  [Symbol.replace]: '',
  toString() {
    throw 'Should not call toString on searchValue';
  }
};

assert.throws(TypeError, function() {
  ''.replaceAll.call(poison, searchValue, poison);
}, '@@replace is a string');

searchValue = {
  [Symbol.match]: false,
  flags: 'g',
  [Symbol.replace]: 42,
  toString() {
    throw 'Should not call toString on searchValue';
  }
};

assert.throws(TypeError, function() {
  ''.replaceAll.call(poison, searchValue, poison);
}, '@@replace is a number');

searchValue = {
  [Symbol.match]: false,
  flags: 'g',
  [Symbol.replace]: Symbol(),
  toString() {
    throw 'Should not call toString on searchValue';
  }
};

assert.throws(TypeError, function() {
  ''.replaceAll.call(poison, searchValue, poison);
}, '@@replace is a symbol');

searchValue = {
  [Symbol.match]: false,
  flags: 'g',
  [Symbol.replace]: true,
  toString() {
    throw 'Should not call toString on searchValue';
  }
};

assert.throws(TypeError, function() {
  ''.replaceAll.call(poison, searchValue, poison);
}, '@@replace is true');

searchValue = {
  [Symbol.match]: false,
  flags: 'g',
  [Symbol.replace]: false,
  toString() {
    throw 'Should not call toString on searchValue';
  }
};

assert.throws(TypeError, function() {
  ''.replaceAll.call(poison, searchValue, poison);
}, '@@replace is false');

assert.sameValue(poisoned, 0);

reportCompare(0, 0);