|
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
|
2 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
3 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 |
|
6 //----------------------------------------------------------------------------- |
|
7 var BUGNUMBER = "336376"; |
|
8 var summary = "Tests reserved words in contexts in which they are not reserved"; |
|
9 var actual, expect; |
|
10 |
|
11 printBugNumber(BUGNUMBER); |
|
12 printStatus(summary); |
|
13 |
|
14 /************** |
|
15 * TEST SETUP * |
|
16 **************/ |
|
17 |
|
18 // |
|
19 // New tests go in Tester.prototype._tests. A test is called with a single |
|
20 // argument, the keyword to test in the syntax tested by that test. Tests |
|
21 // should not return anything, and they should signal failure by throwing an |
|
22 // explanatory exception and success by not throwing one. |
|
23 // |
|
24 // If you define a new test, make sure to name it using an informative string |
|
25 // for ease of use if any keywords ever manually define the array of tests they |
|
26 // should pass, and add it as a string to ALL_TESTS. |
|
27 // |
|
28 |
|
29 // all tests |
|
30 const ALL_TESTS = |
|
31 [ |
|
32 "CONTEXT_OBJECT_LITERAL_PROPERTY", |
|
33 "CONTEXT_OBJECT_PROPERTY_DOT_REFERENCE", |
|
34 "CONTEXT_OBJECT_PROPERTY_DOT_REFERENCE_IS_FUNCTION", |
|
35 "CONTEXT_OBJECT_PROPERTY_DOT_GET", |
|
36 "CONTEXT_OBJECT_PROPERTY_DOT_SET", |
|
37 ]; |
|
38 |
|
39 function r(keyword, tests) |
|
40 { |
|
41 /** |
|
42 * @param keyword |
|
43 * the keyword as a string |
|
44 * @param tests |
|
45 * array of test numbers against it, or leave undefined to run all tests |
|
46 * against it |
|
47 */ |
|
48 function Reserved(keyword, tests) |
|
49 { |
|
50 this.keyword = keyword; |
|
51 if (tests) |
|
52 this.tests = tests; |
|
53 else |
|
54 this.tests = ALL_TESTS; |
|
55 } |
|
56 Reserved.prototype = |
|
57 { |
|
58 toString: |
|
59 function() |
|
60 { |
|
61 return "'" + this.keyword + "' being run against tests " + |
|
62 this.tests; |
|
63 } |
|
64 }; |
|
65 return new Reserved(keyword, tests); |
|
66 } |
|
67 |
|
68 // ECMA-262, 3rd. ed. keywords -- see 7.5.2 |
|
69 const ECMA_262_3_KEYWORD = |
|
70 [ |
|
71 r("break"), |
|
72 r("case"), |
|
73 r("catch"), |
|
74 r("continue"), |
|
75 r("default"), |
|
76 r("delete"), |
|
77 r("do"), |
|
78 r("else"), |
|
79 r("finally"), |
|
80 r("for"), |
|
81 r("function"), |
|
82 r("if"), |
|
83 r("in"), |
|
84 r("instanceof"), |
|
85 r("new"), |
|
86 r("return"), |
|
87 r("switch"), |
|
88 r("this"), |
|
89 r("throw"), |
|
90 r("try"), |
|
91 r("typeof"), |
|
92 r("var"), |
|
93 r("void"), |
|
94 r("while"), |
|
95 r("with"), |
|
96 ]; |
|
97 |
|
98 // ECMA-262, 3rd. ed. future reserved keywords -- see 7.5.3 |
|
99 const ECMA_262_3_FUTURERESERVEDKEYWORD = |
|
100 [ |
|
101 r("abstract"), |
|
102 r("boolean"), |
|
103 r("byte"), |
|
104 r("char"), |
|
105 r("class"), |
|
106 r("const"), |
|
107 r("debugger"), |
|
108 r("double"), |
|
109 r("enum"), |
|
110 r("export"), |
|
111 r("extends"), |
|
112 r("final"), |
|
113 r("float"), |
|
114 r("goto"), |
|
115 r("implements"), |
|
116 r("import"), |
|
117 r("int"), |
|
118 r("interface"), |
|
119 r("long"), |
|
120 r("native"), |
|
121 r("package"), |
|
122 r("private"), |
|
123 r("protected"), |
|
124 r("public"), |
|
125 r("short"), |
|
126 r("static"), |
|
127 r("super"), |
|
128 r("synchronized"), |
|
129 r("throws"), |
|
130 r("transient"), |
|
131 r("volatile"), |
|
132 ]; |
|
133 |
|
134 // like reserved words, but not quite reserved words |
|
135 const PSEUDO_RESERVED = |
|
136 [ |
|
137 r("true"), |
|
138 r("false"), |
|
139 r("null"), |
|
140 r("each"), // |for each| |
|
141 ]; |
|
142 |
|
143 // new-in-ES4 reserved words -- fill this as each is implemented |
|
144 const ECMA_262_4_RESERVED_WORDS = |
|
145 [ |
|
146 r("let") |
|
147 ]; |
|
148 |
|
149 |
|
150 |
|
151 /** |
|
152 * @param keyword |
|
153 * string containing the tested keyword |
|
154 * @param test |
|
155 * the number of the failing test |
|
156 * @param error |
|
157 * the exception thrown when running the test |
|
158 */ |
|
159 function Failure(keyword, test, error) |
|
160 { |
|
161 this.keyword = keyword; |
|
162 this.test = test; |
|
163 this.error = error; |
|
164 } |
|
165 Failure.prototype = |
|
166 { |
|
167 toString: |
|
168 function() |
|
169 { |
|
170 return "*** FAILURE on '" + this.keyword + "'!\n" + |
|
171 "* test: " + this.test + "\n" + |
|
172 "* error: " + this.error + "\n"; |
|
173 } |
|
174 }; |
|
175 |
|
176 function Tester() |
|
177 { |
|
178 this._failedTests = []; |
|
179 } |
|
180 Tester.prototype = |
|
181 { |
|
182 testReservedWords: |
|
183 function(reservedArray) |
|
184 { |
|
185 var rv; |
|
186 for (var i = 0, sz = reservedArray.length; i < sz; i++) |
|
187 { |
|
188 var res = reservedArray[i]; |
|
189 if (!res) |
|
190 continue; |
|
191 |
|
192 var tests = res.tests; |
|
193 for (var j = 0, sz2 = tests.length; j < sz2; j++) |
|
194 { |
|
195 var test = tests[j]; |
|
196 if (!test) |
|
197 continue; |
|
198 |
|
199 try |
|
200 { |
|
201 this._tests[test](res.keyword); |
|
202 } |
|
203 catch (e) |
|
204 { |
|
205 this._failedTests.push(new Failure(res.keyword, test, e)); |
|
206 } |
|
207 } |
|
208 } |
|
209 }, |
|
210 flushErrors: |
|
211 function () |
|
212 { |
|
213 if (this._failedTests.length > 0) { |
|
214 var except = "*************************\n" + |
|
215 "* FAILURES ENCOUNTERED! *\n" + |
|
216 "*************************\n"; |
|
217 for (var i = 0, sz = this._failedTests.length; i < sz; i++) |
|
218 except += this._failedTests[i]; |
|
219 throw except; |
|
220 } |
|
221 }, |
|
222 _tests: |
|
223 { |
|
224 CONTEXT_OBJECT_LITERAL_PROPERTY: |
|
225 function(keyword) |
|
226 { |
|
227 try |
|
228 { |
|
229 eval("var o = { " + keyword + ": 17 };\n" + |
|
230 "if (o['" + keyword + "'] != 17)\n" + |
|
231 "throw \"o['" + keyword + "'] == 17\";"); |
|
232 } |
|
233 catch (e) |
|
234 { |
|
235 throw e; |
|
236 } |
|
237 }, |
|
238 CONTEXT_OBJECT_PROPERTY_DOT_REFERENCE: |
|
239 function(keyword) |
|
240 { |
|
241 try |
|
242 { |
|
243 eval("var o = { \"" + keyword + "\": 17, baz: null };\n" + |
|
244 "if (o." + keyword + " != 17)\n" + |
|
245 "throw \"o." + keyword + " == 17\";"); |
|
246 } |
|
247 catch (e) |
|
248 { |
|
249 throw e; |
|
250 } |
|
251 }, |
|
252 CONTEXT_OBJECT_PROPERTY_DOT_REFERENCE_IS_FUNCTION: |
|
253 function(keyword) |
|
254 { |
|
255 try |
|
256 { |
|
257 eval("var o = { '" + keyword + "': function() { return 17; }, baz: null };\n" + |
|
258 "if (o." + keyword + "() != 17)\n" + |
|
259 "throw \"o." + keyword + " == 17\";"); |
|
260 } |
|
261 catch (e) |
|
262 { |
|
263 throw e; |
|
264 } |
|
265 }, |
|
266 CONTEXT_OBJECT_PROPERTY_DOT_GET: |
|
267 function(keyword) |
|
268 { |
|
269 try |
|
270 { |
|
271 var o = {}; |
|
272 eval("o['" + keyword + "'] = 17;\n" + |
|
273 "if (o." + keyword + " != 17)\n" + |
|
274 "throw \"'o." + keyword + " != 17' failed!\";"); |
|
275 } |
|
276 catch (e) |
|
277 { |
|
278 throw e; |
|
279 } |
|
280 }, |
|
281 CONTEXT_OBJECT_PROPERTY_DOT_SET: |
|
282 function(keyword) |
|
283 { |
|
284 try |
|
285 { |
|
286 var o = {}; |
|
287 eval("o." + keyword + " = 17;\n" + |
|
288 "if (o['" + keyword + "'] != 17)\n" + |
|
289 "throw \"'o." + keyword + " = 17' failed!\";"); |
|
290 } |
|
291 catch (e) |
|
292 { |
|
293 throw e; |
|
294 } |
|
295 }, |
|
296 } |
|
297 }; |
|
298 |
|
299 |
|
300 /*************** |
|
301 * BEGIN TESTS * |
|
302 ***************/ |
|
303 |
|
304 var failed = false; |
|
305 |
|
306 try |
|
307 { |
|
308 var tester = new Tester(); |
|
309 tester.testReservedWords(ECMA_262_3_KEYWORD); |
|
310 tester.testReservedWords(ECMA_262_3_FUTURERESERVEDKEYWORD); |
|
311 tester.testReservedWords(PSEUDO_RESERVED); |
|
312 tester.testReservedWords(ECMA_262_4_RESERVED_WORDS); |
|
313 tester.flushErrors(); |
|
314 } |
|
315 catch (e) |
|
316 { |
|
317 failed = e; |
|
318 } |
|
319 |
|
320 expect = false; |
|
321 actual = failed; |
|
322 |
|
323 reportCompare(expect, actual, summary); |