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