148 lines
4 KiB
Java
148 lines
4 KiB
Java
|
/*
|
||
|
* Copyright 2008 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;
|
||
|
|
||
|
/**
|
||
|
* Test for the control structure verification.
|
||
|
*
|
||
|
*/
|
||
|
public class ControlStructureCheckTest extends CompilerTestCase {
|
||
|
// Rhino parse error message text
|
||
|
final String UNLABELED_BREAK =
|
||
|
"unlabelled break must be inside loop or switch";
|
||
|
|
||
|
final String UNEXPECTED_CONTINUE = "continue must be inside loop";
|
||
|
|
||
|
final String UNEXPECTED_LABLED_CONTINUE =
|
||
|
"continue can only use labeles of iteration statements";
|
||
|
|
||
|
final String UNDEFINED_LABEL = "undefined label";
|
||
|
|
||
|
@Override
|
||
|
public CompilerPass getProcessor(Compiler compiler) {
|
||
|
return new ControlStructureCheck(compiler);
|
||
|
}
|
||
|
|
||
|
public void testWhile() {
|
||
|
assertNoError("while(1) { break; }");
|
||
|
}
|
||
|
|
||
|
public void testNextedWhile() {
|
||
|
assertNoError("while(1) { while(1) { break; } }");
|
||
|
}
|
||
|
|
||
|
public void testBreak() {
|
||
|
assertInvalidBreak("break;");
|
||
|
}
|
||
|
|
||
|
public void testContinue() {
|
||
|
assertInvalidContinue("continue;");
|
||
|
}
|
||
|
|
||
|
public void testBreakCrossFunction() {
|
||
|
assertInvalidBreak("while(1) { function f() { break; } }");
|
||
|
}
|
||
|
|
||
|
public void testBreakCrossFunctionInFor() {
|
||
|
assertInvalidBreak("while(1) {for(var f = function () { break; };;) {}}");
|
||
|
}
|
||
|
|
||
|
public void testContinueToSwitch() {
|
||
|
assertInvalidContinue("switch(1) {case(1): continue; }");
|
||
|
}
|
||
|
|
||
|
public void testContinueToSwitchWithNoCases() {
|
||
|
assertNoError("switch(1){}");
|
||
|
}
|
||
|
|
||
|
public void testContinueToSwitchWithTwoCases() {
|
||
|
assertInvalidContinue("switch(1){case(1):break;case(2):continue;}");
|
||
|
}
|
||
|
|
||
|
public void testContinueToSwitchWithDefault() {
|
||
|
assertInvalidContinue("switch(1){case(1):break;case(2):default:continue;}");
|
||
|
}
|
||
|
|
||
|
public void testContinueToLabelSwitch() {
|
||
|
assertInvalidLabeledContinue(
|
||
|
"while(1) {a: switch(1) {case(1): continue a; }}");
|
||
|
}
|
||
|
|
||
|
public void testContinueOutsideSwitch() {
|
||
|
assertNoError("b: while(1) { a: switch(1) { case(1): continue b; } }");
|
||
|
}
|
||
|
|
||
|
public void testContinueNotCrossFunction1() {
|
||
|
assertNoError("a:switch(1){case(1):function f(){a:while(1){continue a;}}}");
|
||
|
}
|
||
|
|
||
|
public void testContinueNotCrossFunction2() {
|
||
|
assertUndefinedLabel(
|
||
|
"a:switch(1){case(1):function f(){while(1){continue a;}}}");
|
||
|
}
|
||
|
|
||
|
public void testUseOfWith1() {
|
||
|
testSame("with(a){}", ControlStructureCheck.USE_OF_WITH);
|
||
|
}
|
||
|
|
||
|
public void testUseOfWith2() {
|
||
|
testSame("/** @suppress {with} */" +
|
||
|
"with(a){}");
|
||
|
}
|
||
|
|
||
|
public void testUseOfWith3() {
|
||
|
testSame(
|
||
|
"function f(expr, context) {\n" +
|
||
|
" try {\n" +
|
||
|
" /** @suppress{with} */ with (context) {\n" +
|
||
|
" return eval('[' + expr + '][0]');\n" +
|
||
|
" }\n" +
|
||
|
" } catch (e) {\n" +
|
||
|
" return null;\n" +
|
||
|
" }\n" +
|
||
|
"};\n");
|
||
|
}
|
||
|
|
||
|
private void assertNoError(String js) {
|
||
|
testSame(js);
|
||
|
}
|
||
|
|
||
|
private void assertInvalidBreak(String js) {
|
||
|
testParseError(js, UNLABELED_BREAK);
|
||
|
}
|
||
|
|
||
|
private void assertInvalidContinue(String js) {
|
||
|
testParseError(js, UNEXPECTED_CONTINUE);
|
||
|
}
|
||
|
|
||
|
private void assertInvalidLabeledContinue(String js) {
|
||
|
testParseError(js, UNEXPECTED_LABLED_CONTINUE);
|
||
|
}
|
||
|
|
||
|
private void assertUndefinedLabel(String js) {
|
||
|
testParseError(js, UNDEFINED_LABEL);
|
||
|
}
|
||
|
|
||
|
private void testParseError(String js, String errorText) {
|
||
|
Compiler compiler = new Compiler();
|
||
|
compiler.parseTestCode(js);
|
||
|
assertTrue(compiler.getErrorCount() == 1);
|
||
|
String msg = compiler.getErrors()[0].toString();
|
||
|
assertTrue(msg.contains(errorText));
|
||
|
}
|
||
|
}
|