Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 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 | })(); |