Some test cases for switch expression
Brian Goetz
brian.goetz at oracle.com
Mon Apr 16 19:19:00 UTC 2018
I just pushed the start of a test framework, based on the existing javac
combo-test framework, for testing the nesting of constructs with
nonlocal control flow. I did the first few easy ones :)
It starts with some snippets:
private static final String RUNNABLE = "Runnable r = () -> { # };";
private static final String INT_FN =
"java.util.function.IntSupplier r = () -> { # };";
private static final String LABEL = "label: #";
private static final String FOR = "for (int i=0; i<10; i++) { # };";
private static final String WHILE = "while (cond) { # };";
private static final String DO = "do { # } while (cond);";
private static final String SSWITCH = "switch (x) { case 0: # };";
private static final String ESWITCH = "int res = switch (x) { case
0: # default -> 0; };";
private static final String IF = "if (cond) { # };";
private static final String BLOCK = "{ # };";
private static final String BREAK_Z = "break 0;";
private static final String BREAK_N = "break;";
private static final String BREAK_L = "break label;";
private static final String RETURN_Z = "return 0;";
private static final String RETURN_N = "return;";
private static final String CONTINUE_N = "continue;";
private static final String CONTINUE_L = "continue label;";
private static final String NOTHING = "System.out.println();";
where # means "expand the next snippet here". This lets you set up
chains of nesting, like "LABEL, FOR, ESWITCH, BREAK_L", which means
"labeled-break in expr-switch in for-loop in labeled-statement".
Then you can assert whether things compile or not, and if not, with what
diagnostic. Here's the rules for lambdas:
public void testLambda() {
assertOK(RUNNABLE, RETURN_N);
assertOK(RUNNABLE, NOTHING);
assertOK(INT_FN, RETURN_Z);
assertFail("compiler.err.break.outside.switch.loop", RUNNABLE,
BREAK_N);
assertFail("compiler.err.break.complex.value.no.switch.expression",
INT_FN, BREAK_Z);
assertFail("compiler.err.cont.outside.loop", RUNNABLE, CONTINUE_N);
assertFail("compiler.err.undef.label", RUNNABLE, BREAK_L);
assertFail("compiler.err.undef.label", RUNNABLE, CONTINUE_L);
assertFail("compiler.err.undef.label", LABEL, BLOCK, RUNNABLE,
BREAK_L);
assertFail("compiler.err.undef.label", LABEL, BLOCK, RUNNABLE,
CONTINUE_L);
}
which means that its OK to return out of a lambda, but not to break or
continue.
Here's the rules for expression switch:
public void testEswitch() {
assertOK(ESWITCH, BREAK_Z);
assertOK(LABEL, BLOCK, ESWITCH, BREAK_Z);
assertFail("compiler.err.break.missing.value", ESWITCH, BREAK_N);
assertFail("compiler.err.cant.resolve.location", ESWITCH, BREAK_L);
assertFail("compiler.err.break.outside.switch.expression",
LABEL, BLOCK, ESWITCH, BREAK_L);
assertFail("compiler.err.undef.label", ESWITCH, CONTINUE_L);
assertFail("compiler.err.cont.outside.loop", ESWITCH, CONTINUE_N);
assertFail("compiler.err.return.outside.switch.expression", ESWITCH,
RETURN_N);
assertFail("compiler.err.return.outside.switch.expression", ESWITCH,
RETURN_Z);
}
It's a good start.
More information about the amber-dev
mailing list