| /* -*- tab-width: 2; indent-tabs-mode: nil; js-indent-level: 2 -*- */ |
| /* This Source Code Form is subject to the terms of the Mozilla Public |
| * License, v. 2.0. If a copy of the MPL was not distributed with this |
| * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
| |
| //----------------------------------------------------------------------------- |
| var BUGNUMBER = "336376"; |
| var summary = "Tests reserved words in contexts in which they are not reserved"; |
| var actual, expect; |
| |
| printBugNumber(BUGNUMBER); |
| printStatus(summary); |
| |
| /************** |
| * TEST SETUP * |
| **************/ |
| |
| // |
| // New tests go in Tester.prototype._tests. A test is called with a single |
| // argument, the keyword to test in the syntax tested by that test. Tests |
| // should not return anything, and they should signal failure by throwing an |
| // explanatory exception and success by not throwing one. |
| // |
| // If you define a new test, make sure to name it using an informative string |
| // for ease of use if any keywords ever manually define the array of tests they |
| // should pass, and add it as a string to ALL_TESTS. |
| // |
| |
| // all tests |
| const ALL_TESTS = |
| [ |
| "CONTEXT_OBJECT_LITERAL_PROPERTY", |
| "CONTEXT_OBJECT_PROPERTY_DOT_REFERENCE", |
| "CONTEXT_OBJECT_PROPERTY_DOT_REFERENCE_IS_FUNCTION", |
| "CONTEXT_OBJECT_PROPERTY_DOT_GET", |
| "CONTEXT_OBJECT_PROPERTY_DOT_SET", |
| ]; |
| |
| function r(keyword, tests) |
| { |
| /** |
| * @param keyword |
| * the keyword as a string |
| * @param tests |
| * array of test numbers against it, or leave undefined to run all tests |
| * against it |
| */ |
| function Reserved(keyword, tests) |
| { |
| this.keyword = keyword; |
| if (tests) |
| this.tests = tests; |
| else |
| this.tests = ALL_TESTS; |
| } |
| Reserved.prototype = |
| { |
| toString: |
| function() |
| { |
| return "'" + this.keyword + "' being run against tests " + |
| this.tests; |
| } |
| }; |
| return new Reserved(keyword, tests); |
| } |
| |
| // ECMA-262, 3rd. ed. keywords -- see 7.5.2 |
| const ECMA_262_3_KEYWORD = |
| [ |
| r("break"), |
| r("case"), |
| r("catch"), |
| r("continue"), |
| r("default"), |
| r("delete"), |
| r("do"), |
| r("else"), |
| r("finally"), |
| r("for"), |
| r("function"), |
| r("if"), |
| r("in"), |
| r("instanceof"), |
| r("new"), |
| r("return"), |
| r("switch"), |
| r("this"), |
| r("throw"), |
| r("try"), |
| r("typeof"), |
| r("var"), |
| r("void"), |
| r("while"), |
| r("with"), |
| ]; |
| |
| // ECMA-262, 3rd. ed. future reserved keywords -- see 7.5.3 |
| const ECMA_262_3_FUTURERESERVEDKEYWORD = |
| [ |
| r("abstract"), |
| r("boolean"), |
| r("byte"), |
| r("char"), |
| r("class"), |
| r("const"), |
| r("debugger"), |
| r("double"), |
| r("enum"), |
| r("export"), |
| r("extends"), |
| r("final"), |
| r("float"), |
| r("goto"), |
| r("implements"), |
| r("import"), |
| r("int"), |
| r("interface"), |
| r("long"), |
| r("native"), |
| r("package"), |
| r("private"), |
| r("protected"), |
| r("public"), |
| r("short"), |
| r("static"), |
| r("super"), |
| r("synchronized"), |
| r("throws"), |
| r("transient"), |
| r("volatile"), |
| ]; |
| |
| // like reserved words, but not quite reserved words |
| const PSEUDO_RESERVED = |
| [ |
| r("true"), |
| r("false"), |
| r("null"), |
| r("each"), // |for each| |
| ]; |
| |
| // new-in-ES4 reserved words -- fill this as each is implemented |
| const ECMA_262_4_RESERVED_WORDS = |
| [ |
| r("let") |
| ]; |
| |
| |
| |
| /** |
| * @param keyword |
| * string containing the tested keyword |
| * @param test |
| * the number of the failing test |
| * @param error |
| * the exception thrown when running the test |
| */ |
| function Failure(keyword, test, error) |
| { |
| this.keyword = keyword; |
| this.test = test; |
| this.error = error; |
| } |
| Failure.prototype = |
| { |
| toString: |
| function() |
| { |
| return "*** FAILURE on '" + this.keyword + "'!\n" + |
| "* test: " + this.test + "\n" + |
| "* error: " + this.error + "\n"; |
| } |
| }; |
| |
| function Tester() |
| { |
| this._failedTests = []; |
| } |
| Tester.prototype = |
| { |
| testReservedWords: |
| function(reservedArray) |
| { |
| var rv; |
| for (var i = 0, sz = reservedArray.length; i < sz; i++) |
| { |
| var res = reservedArray[i]; |
| if (!res) |
| continue; |
| |
| var tests = res.tests; |
| for (var j = 0, sz2 = tests.length; j < sz2; j++) |
| { |
| var test = tests[j]; |
| if (!test) |
| continue; |
| |
| try |
| { |
| this._tests[test](res.keyword); |
| } |
| catch (e) |
| { |
| this._failedTests.push(new Failure(res.keyword, test, e)); |
| } |
| } |
| } |
| }, |
| flushErrors: |
| function () |
| { |
| if (this._failedTests.length > 0) { |
| var except = "*************************\n" + |
| "* FAILURES ENCOUNTERED! *\n" + |
| "*************************\n"; |
| for (var i = 0, sz = this._failedTests.length; i < sz; i++) |
| except += this._failedTests[i]; |
| throw except; |
| } |
| }, |
| _tests: |
| { |
| CONTEXT_OBJECT_LITERAL_PROPERTY: |
| function(keyword) |
| { |
| try |
| { |
| eval("var o = { " + keyword + ": 17 };\n" + |
| "if (o['" + keyword + "'] != 17)\n" + |
| "throw \"o['" + keyword + "'] == 17\";"); |
| } |
| catch (e) |
| { |
| throw e; |
| } |
| }, |
| CONTEXT_OBJECT_PROPERTY_DOT_REFERENCE: |
| function(keyword) |
| { |
| try |
| { |
| eval("var o = { \"" + keyword + "\": 17, baz: null };\n" + |
| "if (o." + keyword + " != 17)\n" + |
| "throw \"o." + keyword + " == 17\";"); |
| } |
| catch (e) |
| { |
| throw e; |
| } |
| }, |
| CONTEXT_OBJECT_PROPERTY_DOT_REFERENCE_IS_FUNCTION: |
| function(keyword) |
| { |
| try |
| { |
| eval("var o = { '" + keyword + "': function() { return 17; }, baz: null };\n" + |
| "if (o." + keyword + "() != 17)\n" + |
| "throw \"o." + keyword + " == 17\";"); |
| } |
| catch (e) |
| { |
| throw e; |
| } |
| }, |
| CONTEXT_OBJECT_PROPERTY_DOT_GET: |
| function(keyword) |
| { |
| try |
| { |
| var o = {}; |
| eval("o['" + keyword + "'] = 17;\n" + |
| "if (o." + keyword + " != 17)\n" + |
| "throw \"'o." + keyword + " != 17' failed!\";"); |
| } |
| catch (e) |
| { |
| throw e; |
| } |
| }, |
| CONTEXT_OBJECT_PROPERTY_DOT_SET: |
| function(keyword) |
| { |
| try |
| { |
| var o = {}; |
| eval("o." + keyword + " = 17;\n" + |
| "if (o['" + keyword + "'] != 17)\n" + |
| "throw \"'o." + keyword + " = 17' failed!\";"); |
| } |
| catch (e) |
| { |
| throw e; |
| } |
| }, |
| } |
| }; |
| |
| |
| /*************** |
| * BEGIN TESTS * |
| ***************/ |
| |
| var failed = false; |
| |
| try |
| { |
| var tester = new Tester(); |
| tester.testReservedWords(ECMA_262_3_KEYWORD); |
| tester.testReservedWords(ECMA_262_3_FUTURERESERVEDKEYWORD); |
| tester.testReservedWords(PSEUDO_RESERVED); |
| tester.testReservedWords(ECMA_262_4_RESERVED_WORDS); |
| tester.flushErrors(); |
| } |
| catch (e) |
| { |
| failed = e; |
| } |
| |
| expect = false; |
| actual = failed; |
| |
| reportCompare(expect, actual, summary); |