246 lines
6.8 KiB
Java
246 lines
6.8 KiB
Java
/*
|
|
* Copyright 2009 The Closure Compiler Authors.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
package com.google.javascript.jscomp;
|
|
|
|
public class StrictModeCheckTest extends CompilerTestCase {
|
|
private static final String EXTERNS = "var arguments; function eval(str) {}";
|
|
|
|
private boolean noVarCheck;
|
|
private boolean noCajaChecks;
|
|
|
|
public StrictModeCheckTest() {
|
|
super(EXTERNS);
|
|
}
|
|
|
|
@Override
|
|
protected void setUp() throws Exception {
|
|
super.setUp();
|
|
noVarCheck = false;
|
|
noCajaChecks = false;
|
|
}
|
|
|
|
@Override
|
|
protected CompilerPass getProcessor(Compiler compiler) {
|
|
return new StrictModeCheck(compiler, noVarCheck, noCajaChecks);
|
|
}
|
|
|
|
@Override
|
|
protected int getNumRepetitions() {
|
|
return 1;
|
|
}
|
|
|
|
public void testEval() {
|
|
test("function foo() { eval('a'); }", null,
|
|
StrictModeCheck.EVAL_USE);
|
|
}
|
|
|
|
public void testEval2() {
|
|
testSame("function foo(eval) {}",
|
|
StrictModeCheck.EVAL_DECLARATION);
|
|
}
|
|
|
|
public void testEval3() {
|
|
testSame("function foo() {} foo.eval = 3;");
|
|
}
|
|
|
|
public void testEval4() {
|
|
testSame("function foo() { var eval = 3; }",
|
|
StrictModeCheck.EVAL_DECLARATION);
|
|
}
|
|
|
|
public void testEval5() {
|
|
testSame("function eval() {}", StrictModeCheck.EVAL_DECLARATION);
|
|
}
|
|
|
|
public void testEval6() {
|
|
testSame("try {} catch (eval) {}", StrictModeCheck.EVAL_DECLARATION);
|
|
}
|
|
|
|
public void testEval7() {
|
|
testSame("var o = {eval: 3};");
|
|
}
|
|
|
|
public void testEval8() {
|
|
testSame("var a; eval: while (true) { a = 3; }");
|
|
}
|
|
|
|
public void testUnknownVariable() {
|
|
testSame("function foo(a) { a = b; }", StrictModeCheck.UNKNOWN_VARIABLE);
|
|
}
|
|
|
|
public void testUnknownVariable2() {
|
|
testSame("a: while (true) { a = 3; }", StrictModeCheck.UNKNOWN_VARIABLE);
|
|
}
|
|
|
|
public void testUnknownVariable3() {
|
|
testSame("try {} catch (ex) { ex = 3; }");
|
|
}
|
|
|
|
public void testArguments() {
|
|
testSame("function foo(arguments) {}",
|
|
StrictModeCheck.ARGUMENTS_DECLARATION);
|
|
}
|
|
|
|
public void testArguments2() {
|
|
testSame("function foo() { var arguments = 3; }",
|
|
StrictModeCheck.ARGUMENTS_DECLARATION);
|
|
}
|
|
|
|
public void testArguments3() {
|
|
testSame("function arguments() {}",
|
|
StrictModeCheck.ARGUMENTS_DECLARATION);
|
|
}
|
|
|
|
public void testArguments4() {
|
|
testSame("try {} catch (arguments) {}",
|
|
StrictModeCheck.ARGUMENTS_DECLARATION);
|
|
}
|
|
|
|
public void testArguments5() {
|
|
testSame("var o = {arguments: 3};");
|
|
}
|
|
|
|
public void testEvalAssignment() {
|
|
noCajaChecks = true;
|
|
testSame("function foo() { eval = []; }",
|
|
StrictModeCheck.EVAL_ASSIGNMENT);
|
|
}
|
|
|
|
public void testEvalAssignment2() {
|
|
test("function foo() { eval = []; }", null, StrictModeCheck.EVAL_USE);
|
|
}
|
|
|
|
public void testAssignToArguments() {
|
|
testSame("function foo() { arguments = []; }",
|
|
StrictModeCheck.ARGUMENTS_ASSIGNMENT);
|
|
}
|
|
|
|
public void testDeleteVar() {
|
|
testSame("var a; delete a", StrictModeCheck.DELETE_VARIABLE);
|
|
}
|
|
|
|
public void testDeleteFunction() {
|
|
testSame("function a() {} delete a", StrictModeCheck.DELETE_VARIABLE);
|
|
}
|
|
|
|
public void testDeleteArgument() {
|
|
testSame("function b(a) { delete a; }",
|
|
StrictModeCheck.DELETE_VARIABLE);
|
|
}
|
|
|
|
public void testDeleteProperty() {
|
|
testSame("function f(obj) { delete obj.a; }");
|
|
}
|
|
|
|
public void testIllegalName() {
|
|
test("var a__ = 3;", null, StrictModeCheck.ILLEGAL_NAME);
|
|
}
|
|
|
|
public void testIllegalName2() {
|
|
test("function a__() {}", null, StrictModeCheck.ILLEGAL_NAME);
|
|
}
|
|
|
|
public void testIllegalName3() {
|
|
test("function f(a__) {}", null, StrictModeCheck.ILLEGAL_NAME);
|
|
}
|
|
|
|
public void testIllegalName4() {
|
|
test("try {} catch (a__) {}", null, StrictModeCheck.ILLEGAL_NAME);
|
|
}
|
|
|
|
public void testIllegalName5() {
|
|
noVarCheck = true;
|
|
test("var a = b__;", null, StrictModeCheck.ILLEGAL_NAME);
|
|
}
|
|
|
|
public void testIllegalName6() {
|
|
test("function f(obj) { return obj.a__; }", null,
|
|
StrictModeCheck.ILLEGAL_NAME);
|
|
}
|
|
|
|
public void testIllegalName7() {
|
|
noCajaChecks = true;
|
|
testSame("var a__ = 3;");
|
|
}
|
|
|
|
public void testIllegalName8() {
|
|
test("var o = {a__: 3};", null, StrictModeCheck.ILLEGAL_NAME);
|
|
test("var o = {b: 3, a__: 4};", null, StrictModeCheck.ILLEGAL_NAME);
|
|
test("var o = {b: 3, get a__() {}};", null, StrictModeCheck.ILLEGAL_NAME);
|
|
test("var o = {b: 3, set a__(c) {}};", null, StrictModeCheck.ILLEGAL_NAME);
|
|
}
|
|
|
|
public void testIllegalName9() {
|
|
test("a__: while (true) { var b = 3; }", null,
|
|
StrictModeCheck.ILLEGAL_NAME);
|
|
}
|
|
|
|
public void testIllegalName10() {
|
|
// Validate that number as objlit key
|
|
testSame("var o = {1: 3, 2: 4};");
|
|
}
|
|
|
|
public void testDuplicateObjectLiteralKey() {
|
|
testSame("var o = {a: 1, b: 2, c: 3};");
|
|
testSame("var x = { get a() {}, set a(p) {} };");
|
|
|
|
testSame("var o = {a: 1, b: 2, a: 3};",
|
|
StrictModeCheck.DUPLICATE_OBJECT_KEY);
|
|
testSame("var x = { get a() {}, get a() {} };",
|
|
StrictModeCheck.DUPLICATE_OBJECT_KEY);
|
|
testSame("var x = { get a() {}, a: 1 };",
|
|
StrictModeCheck.DUPLICATE_OBJECT_KEY);
|
|
testSame("var x = { set a(p) {}, a: 1 };",
|
|
StrictModeCheck.DUPLICATE_OBJECT_KEY);
|
|
|
|
testSame(
|
|
"'use strict';\n" +
|
|
"function App() {}\n" +
|
|
"App.prototype = {\n" +
|
|
" get appData() { return this.appData_; },\n" +
|
|
" set appData(data) { this.appData_ = data; }\n" +
|
|
"};");
|
|
}
|
|
|
|
public void testFunctionDecl() {
|
|
testSame("function g() {}");
|
|
testSame("var g = function() {};");
|
|
testSame("(function() {})();");
|
|
testSame("(function() {});");
|
|
testSame(inFn("function g() {}"));
|
|
testSame(inFn("var g = function() {};"));
|
|
testSame(inFn("(function() {})();"));
|
|
testSame(inFn("(function() {});"));
|
|
|
|
test("{function g() {}}", null, StrictModeCheck.BAD_FUNCTION_DECLARATION);
|
|
testSame("{var g = function () {}}");
|
|
testSame("{(function g() {})()}");
|
|
|
|
test("var x;if (x) { function g(){} }", null,
|
|
StrictModeCheck.BAD_FUNCTION_DECLARATION);
|
|
testSame("var x;if (x) {var g = function () {}}");
|
|
testSame("var x;if (x) {(function g() {})()}");
|
|
}
|
|
|
|
public void testFunctionDecl2() {
|
|
test("{function g() {}}", null, StrictModeCheck.BAD_FUNCTION_DECLARATION);
|
|
}
|
|
|
|
private String inFn(String body) {
|
|
return "function func() {" + body + "}";
|
|
}
|
|
}
|