blob: e54b1d8f81f9d5c4326754e271121ad0fbdcee4f [file] [log] [blame]
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is JavaScript Engine testing utilities.
*
* The Initial Developer of the Original Code is
* Jeff Walden <jwalden+code@mit.edu>.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
var gTestfile = 'regress-336376-01.js';
//-----------------------------------------------------------------------------
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",
"CONTEXT_XML_DESCENDANTS",
"CONTEXT_XML_NAMESPACE_QUALIFIED_ELEMENT",
"CONTEXT_XML_NAMESPACE_QUALIFIED_ATTR",
"CONTEXT_XML_ATTRIBUTE_SELECTOR",
];
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;
}
},
CONTEXT_XML_DESCENDANTS:
function(keyword)
{
try
{
eval("var x = <foo><biz><" + keyword + " id='1'/></biz><" + keyword + " f='g'/></foo>;\n" +
"if (x.." + keyword + ".length() != 2 ||\n" +
" x.." + keyword + " != \n" +
" <><" + keyword + " id='1'/><" + keyword + " f='g'/></>)\n" +
"throw \"'x.." + keyword + ".length()' failed!\";");
}
catch (e)
{
throw e;
}
},
CONTEXT_XML_NAMESPACE_QUALIFIED_ELEMENT:
function(keyword)
{
try
{
var bar = new Namespace("http://localhost/");
eval("var x = <foo xmlns:bar='http://localhost/'>\n\
<bar>\n\
<baz/>\n\
</bar>\n\
<bar:" + keyword + " id='17'/>\n\
<quiz>\n\
<bar:" + keyword + ">\n\
<bunk/>\n\
</bar:" + keyword + ">\n\
</quiz>\n\
</foo>;\n\
if (x.quiz.bar::" + keyword + " != \n\
<bar:" + keyword + " xmlns:bar='http://localhost/'>\n\
<bunk/>\n\
</bar:" + keyword + "> ||\n\
x..bar::" + keyword + " != \n\
<><bar:" + keyword + "\n\
xmlns:bar='http://localhost/' id='17'/>\n\
<bar:" + keyword + " xmlns:bar='http://localhost/'>\n\
<bunk/>\n\
</bar:" + keyword + "></>)\n\
throw 'reserved names in XML namespace-qualified stuff are broken!';");
}
catch (e)
{
throw e;
}
},
CONTEXT_XML_NAMESPACE_QUALIFIED_ATTR:
function(keyword)
{
try
{
var bar = new Namespace("http://localhost/");
eval("var x = <foo xmlns:bar='http://localhost/'>\
<fin bar:" + keyword + "='5'/>\
</foo>;\n\
if (x.fin.@bar::" + keyword + " != 5)\n\
throw 'namespaced attributes which are keywords are broken!';");
}
catch (e)
{
throw e;
}
},
CONTEXT_XML_ATTRIBUTE_SELECTOR:
function(keyword)
{
try
{
eval("var x = <foo " + keyword + "='idref'/>;\n\
if (x.@" + keyword + " != 'idref')\n\
throw 'keywords on the right of the @ E4X selector are broken!';");
}
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);