blob: 2880b2abea94d3d505239ec4ca622dcec4626b87 [file] [log] [blame]
/*
* Copyright 2013 Google Inc.
*
* 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.gwt.dev.jjs.test;
import com.google.gwt.junit.client.GWTTestCase;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* Tests Java 7 features.
*/
public class Java7Test extends GWTTestCase {
@Override
public String getModuleName() {
return "com.google.gwt.dev.jjs.CompilerSuite";
}
// new style class literals
int million = 1_000_000;
int five = 0b101;
public void testNewStyleLiterals() {
assertEquals(1000000, million);
assertEquals(5, five);
}
public void testSwitchOnString() {
String s = "AA";
int result = -1;
switch (s) {
case "BB":
result = 0;
break;
case "CC":
case "AA":
result = 1;
break;
}
assertEquals(1, result);
}
final List<String> log = new ArrayList<String>();
enum ThrowsWhen {
NEVER, ONCONSTRUCTOR, ONCLOSE;
}
class Resource implements AutoCloseable {
final String name;
final ThrowsWhen throwsWhen;
public Resource(String name) throws E1 {
this(name, ThrowsWhen.NEVER);
}
public Resource(String name, ThrowsWhen throwsWhen) throws E1 {
this.name = name;
this.throwsWhen = throwsWhen;
log.add("Open " + name);
if (throwsWhen == ThrowsWhen.ONCONSTRUCTOR) {
throwException("ExceptionOnConstructor");
}
}
public void doSomething() {
log.add("doSomething " + name);
}
public void throwException(String text) throws E1 {
throw new E1(text + " in " + name);
}
public void close() throws Exception {
log.add("Close " + name);
if (throwsWhen == ThrowsWhen.ONCLOSE) {
throwException("ExceptionOnClose");
}
}
}
private void logException(Exception e) {
log.add(e.getMessage());
for (Throwable t : e.getSuppressed()) {
log.add("Suppressed: " + t.getMessage());
}
}
public void testTryWithResources_noExceptions() throws Exception {
log.clear();
try (
Resource rA = new Resource("A");
Resource rB = new Resource("B");
Resource rC = new Resource("C")) {
rA.doSomething();
rB.doSomething();
rC.doSomething();
}
assertContentsInOrder(log,
"Open A",
"Open B",
"Open C",
"doSomething A",
"doSomething B",
"doSomething C",
"Close C",
"Close B",
"Close A"
);
}
public void testTryWithResources_exceptions() throws Exception {
log.clear();
try (
Resource rA = new Resource("A");
Resource rB = new Resource("B", ThrowsWhen.ONCLOSE);
Resource rC = new Resource("C")) {
rA.doSomething();
rB.doSomething();
rC.doSomething();
} catch (Exception e) {
log.add(e.getMessage());
} finally {
log.add("finally");
}
assertContentsInOrder(log,
"Open A",
"Open B",
"Open C",
"doSomething A",
"doSomething B",
"doSomething C",
"Close C",
"Close B",
"Close A",
"ExceptionOnClose in B",
"finally"
);
}
public void testTryWithResources_suppressedExceptions() throws Exception {
log.clear();
try (
Resource rA = new Resource("A", ThrowsWhen.ONCLOSE);
Resource rB = new Resource("B");
Resource rC = new Resource("C", ThrowsWhen.ONCLOSE)) {
rA.doSomething();
rB.doSomething();
rC.doSomething();
} catch (Exception e) {
logException(e);
}
assertContentsInOrder(log,
"Open A",
"Open B",
"Open C",
"doSomething A",
"doSomething B",
"doSomething C",
"Close C",
"Close B",
"Close A",
"ExceptionOnClose in C",
"Suppressed: ExceptionOnClose in A"
);
log.clear();
try (
Resource rA = new Resource("A");
Resource rB = new Resource("B", ThrowsWhen.ONCLOSE);
Resource rC = new Resource("C")) {
rA.doSomething();
rB.throwException("E1 here");
rC.doSomething();
} catch (Exception e) {
logException(e);
} finally {
log.add("finally");
}
assertContentsInOrder(log,
"Open A",
"Open B",
"Open C",
"doSomething A",
"Close C",
"Close B",
"Close A",
"E1 here in B",
"Suppressed: ExceptionOnClose in B",
"finally"
);
}
public void testTryWithResources_exceptionInAcquisition() {
log.clear();
try (
Resource rA = new Resource("A", ThrowsWhen.ONCLOSE);
Resource rB = new Resource("B", ThrowsWhen.ONCONSTRUCTOR);
Resource rC = new Resource("C", ThrowsWhen.ONCLOSE)) {
rA.doSomething();
rB.doSomething();
rC.doSomething();
} catch (Exception e) {
logException(e);
}
assertContentsInOrder(log,
"Open A",
"Open B",
"Close A",
"ExceptionOnConstructor in B",
"Suppressed: ExceptionOnClose in A"
);
}
public void testAddSuppressedExceptions() {
Throwable throwable = new Throwable("primary");
assertNotNull(throwable.getSuppressed());
assertEquals(0, throwable.getSuppressed().length);
Throwable suppressed1 = new Throwable("suppressed1");
throwable.addSuppressed(suppressed1);
assertEquals(1, throwable.getSuppressed().length);
assertEquals(suppressed1, throwable.getSuppressed()[0]);
Throwable suppressed2 = new Throwable("suppressed2");
throwable.addSuppressed(suppressed2);
assertEquals(2, throwable.getSuppressed().length);
assertEquals(suppressed1, throwable.getSuppressed()[0]);
assertEquals(suppressed2, throwable.getSuppressed()[1]);
}
static class E1 extends Exception {
String name;
public E1(String name) {
this.name = name;
}
public int methodE1() {
return 0;
}
@Override
public String getMessage() {
return name;
}
}
static class E2 extends E1 {
public E2(String name) {
super(name);
}
public int methodE2() {
return 1;
}
}
static class E3 extends E1 {
public E3(String name) {
super(name);
}
public int methodE3() {
return 2;
}
}
public void testMultiExceptions() {
int choose = 0;
try {
if (choose == 0) {
throw new E1("e1");
} else if (choose == 1) {
throw new E2("e2");
}
fail("Exception was not trown");
} catch (E2 | E3 x) {
// The compiler will assign x a common supertype/superinterface of E2 and E3.
// Here we make sure that this clause is not entered when the supertype is thrown.
fail("Caught E1 instead of E2|E3");
} catch (E1 x) {
}
}
private Object unoptimizableId(Object o) {
if (Math.random() > -10) {
return o;
}
return null;
}
public void testPrimitiveCastsFromObject() {
Object o = unoptimizableId((byte) 2);
assertEquals((byte) 2, (byte) o);
o = unoptimizableId((short) 3);
assertEquals((short) 3, (short) o);
o = unoptimizableId(1);
assertEquals(1, (int) o);
o = unoptimizableId(1L);
assertEquals(1L, (long) o);
o = unoptimizableId(0.1f);
assertEquals(0.1f, (float) o);
o = unoptimizableId(0.1);
assertEquals(0.1, (double) o);
o = unoptimizableId(true);
assertEquals(true, (boolean) o);
o = unoptimizableId('a');
assertEquals('a', (char) o);
// Test cast from supers.
Number n = (Number) unoptimizableId(5);
assertEquals(5, (int) n);
Serializable s = (Serializable) unoptimizableId(6);
assertEquals(6, (int) s);
Comparable<Integer> c = (Comparable<Integer>) unoptimizableId(7);
assertEquals(7, (int) c);
// Failing casts.
try {
Object boxedChar = unoptimizableId('a');
boolean b = (boolean) boxedChar;
fail("Should have thrown a ClassCastException");
} catch (ClassCastException e) {
// Expected.
}
try {
Object string = unoptimizableId("string");
int num = (int) string;
fail("Should have thrown a ClassCastException");
} catch (ClassCastException e) {
// Expected.
}
}
private void assertContentsInOrder(Iterable<String> contents, String... elements) {
assertEquals(Arrays.asList(elements).toString(), contents.toString());
}
}