1// Copyright 2014 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5(function testStringRawArity() {
6  assertEquals(1, String.raw.length);
7})();
8
9
10(function testStringRawCallSiteToObject() {
11  assertThrows("String.raw()", TypeError);
12})();
13
14
15(function testStringRawCallSiteRawToObject() {
16  assertThrows("String.raw([])", TypeError);
17})();
18
19
20(function testStringRawUndefinedLength() {
21  var callSiteObj = [];
22  callSiteObj.raw = {};
23  assertEquals("", String.raw(callSiteObj));
24
25  callSiteObj.raw = { lengt: 0 };
26  assertEquals("", String.raw(callSiteObj));
27})();
28
29
30(function testStringRawZeroLength() {
31  var callSiteObj = [];
32  callSiteObj.raw = { length: 0 };
33  assertEquals("", String.raw(callSiteObj));
34  assertEquals("", String.raw(callSiteObj, "a", "b", "c"));
35
36  callSiteObj.raw = [];
37  assertEquals("", String.raw(callSiteObj));
38  assertEquals("", String.raw(callSiteObj, "a", "b", "c"));
39})();
40
41
42(function testStringRawNegativeLength() {
43  var callSiteObj = [];
44  callSiteObj.raw = { length: -85 };
45  assertEquals("", String.raw(callSiteObj));
46  assertEquals("", String.raw(callSiteObj, "a", "b", "c"));
47
48  callSiteObj.raw = [];
49  assertEquals("", String.raw(callSiteObj));
50  assertEquals("", String.raw(callSiteObj, "a", "b", "c"));
51})();
52
53
54(function testStringRawNaNLength() {
55  var callSiteObj = [];
56  callSiteObj.raw = { length: NaN };
57  assertEquals("", String.raw(callSiteObj));
58  assertEquals("", String.raw(callSiteObj, "a", "b", "c"));
59
60  callSiteObj.raw = [];
61  assertEquals("", String.raw(callSiteObj));
62  assertEquals("", String.raw(callSiteObj, "a", "b", "c"));
63})();
64
65
66(function testStringRawBasic() {
67  var callSiteObj = [];
68  callSiteObj.raw = ["a"];
69  assertEquals("a", String.raw(callSiteObj));
70})();
71
72
73(function testStringRawNoSubst() {
74  var callSiteObj = [];
75  callSiteObj.raw = ["a", "b"];
76  assertEquals("ab", String.raw(callSiteObj));
77})();
78
79
80(function testStringRawSubst() {
81  var callSiteObj = [];
82  callSiteObj.raw = ["a", "b"];
83  assertEquals("a!b", String.raw(callSiteObj, "!"));
84
85  callSiteObj.raw = ["a", "b", "c"];
86  assertEquals("abc", String.raw(callSiteObj));
87
88  callSiteObj.raw = ["a", "b", "c"];
89  assertEquals("a!bc", String.raw(callSiteObj, "!"));
90
91  callSiteObj.raw = ["a", "b", "c"];
92  assertEquals("a!b?c", String.raw(callSiteObj, "!", "?"));
93
94  callSiteObj.raw = ["\n", "\r\n", "\r"];
95  assertEquals("\nx\r\ny\r", String.raw(callSiteObj, "x", "y"));
96
97  callSiteObj.raw = ["\n", "\r\n", "\r"];
98  assertEquals("\n\r\r\r\n\n\r", String.raw(callSiteObj, "\r\r", "\n"));
99})();
100
101
102(function testStringRawArrayLikeSubst() {
103  var callSiteObj = [];
104  callSiteObj.raw = {"length": 2, "0": "a", "1": "b", "2": "c"};
105  assertEquals("axb", String.raw(callSiteObj, "x", "y"));
106
107  callSiteObj.raw = {"length": 4, "0": "a", "1": "b", "2": "c"};
108  assertEquals("axbycundefined", String.raw(callSiteObj, "x", "y"));
109})();
110
111
112(function testStringRawAccessors() {
113  var callSiteObj = {};
114  callSiteObj.raw = {};
115  Object.defineProperties(callSiteObj, {
116    "length": {
117      get: function() { assertUnreachable(); },
118      set: function(v) { assertUnreachable(); }
119    },
120    "0": {
121      get: function() { assertUnreachable(); },
122      set: function(v) { assertUnreachable(); }
123    },
124    "1": {
125      get: function() { assertUnreachable(); },
126      set: function(v) { assertUnreachable(); }
127    }
128  });
129  Object.defineProperties(callSiteObj.raw, {
130    "length": {
131      get: function() { return 2; },
132      set: function(v) { assertUnreachable(); }
133    },
134    "0": {
135      get: function() { return "getter values"; },
136      set: function(v) { assertUnreachable(); }
137    },
138    "1": {
139      get: function() { return "are nice"; },
140      set: function(v) { assertUnreachable(); }
141    }
142  });
143  assertEquals("getter values are nice", String.raw(callSiteObj, " "));
144})();
145
146
147(function testStringRawHoleyArray() {
148  var callSiteObj = [];
149  callSiteObj.raw = ["1."];
150  callSiteObj.raw[2] = ".2";
151  assertEquals("1.undefined.2", String.raw(callSiteObj));
152})();
153
154
155(function testStringRawAccessorThrows() {
156  var callSiteObj = [];
157  callSiteObj.raw = [1];
158  function MyError() {}
159  Object.defineProperty(callSiteObj.raw, "0", {
160    get: function() { throw new MyError(); }
161  });
162  assertThrows(function() { String.raw(callSiteObj); }, MyError);
163})();
164
165
166(function testStringRawToStringSafe() {
167  var callSiteObj = [];
168  callSiteObj.raw = [null, undefined, 1, "str", true, false, NaN, Infinity, {}];
169  assertEquals("nullundefined1strtruefalseNaNInfinity[object Object]",
170               String.raw(callSiteObj));
171
172  callSiteObj.raw = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"];
173  assertEquals("0null1undefined213str4true5false6NaN7Infinity8[object Object]9",
174               String.raw(callSiteObj, null, void 0, 1, "str", true, false,
175               NaN, Infinity, {}));
176})();
177
178
179(function testStringRawToStringSymbolThrows() {
180  var callSiteObj = [];
181  callSiteObj.raw = [Symbol("foo")];
182  assertThrows(function() {
183    String.raw(callSiteObj);
184  }, TypeError);
185
186  callSiteObj.raw = ["1", "2"];
187  assertThrows(function() {
188    String.raw(callSiteObj, Symbol("foo"));
189  }, TypeError);
190})();
191
192
193(function testStringRawToStringThrows() {
194  var callSiteObj = [];
195  var thrower = {};
196  function MyError() {}
197  thrower.toString = function() {
198    throw new MyError();
199  }
200
201  callSiteObj.raw = [thrower];
202  assertThrows(function() {
203    String.raw(callSiteObj);
204  }, MyError);
205
206  callSiteObj.raw = ["1", "2"];
207  assertThrows(function() {
208    String.raw(callSiteObj, thrower);
209  }, MyError);
210})();
211
212
213(function testStringRawToStringValueOfThrows() {
214  var callSiteObj = [];
215  var thrower = {};
216  function MyError() {}
217  thrower.toString = null;
218  thrower.valueOf = function() {
219    throw new MyError();
220  }
221
222  callSiteObj.raw = [thrower];
223  assertThrows(function() {
224    String.raw(callSiteObj);
225  }, MyError);
226
227  callSiteObj.raw = ["1", "2"];
228  assertThrows(function() {
229    String.raw(callSiteObj, thrower);
230  }, MyError);
231})();
232
233
234(function testStringRawOrder() {
235  var order = [];
236  var callSiteObj = [];
237  callSiteObj.raw = {};
238  function arg(v) {
239    var result = {};
240    result.toString = null;
241    result.valueOf = function() { order.push("arg" + v); return v; }
242    return result;
243  }
244
245  Object.defineProperty(callSiteObj.raw, "length", {
246    get: function() { order.push("length"); return 3; }
247  });
248  [1, 3, 5].forEach(function(v, i) {
249    Object.defineProperty(callSiteObj.raw, i, {
250      get: function() { order.push("raw" + v); return v; }
251    });
252  });
253
254  assertEquals("12345", String.raw(callSiteObj, arg(2), arg(4), arg(6)));
255  assertEquals(["length", "raw1", "arg2", "raw3", "arg4", "raw5"], order);
256})();
257
258
259(function testStringRawToStringSubstitutionsOrder() {
260  var subs = [];
261  var log = [];
262  function stringify(toString) {
263    var valueOf = "_" + toString + "_";
264    return {
265      toString: function() { return toString; },
266      valueOf: function() { return valueOf; }
267    };
268  }
269  function getter(name, value) {
270    return {
271      get: function() {
272        log.push("get" + name);
273        return value;
274      },
275      set: function(v) {
276        log.push("set" + name);
277      }
278    };
279  }
280  Object.defineProperties(subs, {
281    0: getter(0, stringify("a")),
282    1: getter(1, stringify("b")),
283    2: getter(2, stringify("c"))
284  });
285
286  assertEquals("-a-b-c-", String.raw`-${subs[0]}-${subs[1]}-${subs[2]}-`);
287  assertArrayEquals(["get0", "get1", "get2"], log);
288
289  log.length = 0;
290  assertEquals("-a-", String.raw`-${subs[0]}-`);
291  assertArrayEquals(["get0"], log);
292})();
293