package spoon.test.trycatch;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static spoon.testing.utils.ModelUtils.build;
import static spoon.testing.utils.ModelUtils.createFactory;
import java.io.File;
import java.util.List;
import java.util.Set;
import org.junit.Test;
import spoon.Launcher;
import spoon.SpoonModelBuilder;
import spoon.reflect.code.CtCatch;
import spoon.reflect.code.CtTry;
import spoon.reflect.code.CtTryWithResource;
import spoon.reflect.declaration.CtClass;
import spoon.reflect.declaration.CtMethod;
import spoon.reflect.factory.Factory;
import spoon.reflect.reference.CtCatchVariableReference;
import spoon.reflect.reference.CtTypeReference;
import spoon.reflect.visitor.filter.AbstractFilter;
import spoon.reflect.visitor.filter.TypeFilter;
import spoon.test.trycatch.testclasses.Foo;
public class TryCatchTest {
@Test
public void testModelBuildingInitializer() throws Exception {
CtClass<Main> type = build("spoon.test.trycatch", "Main");
assertEquals("Main", type.getSimpleName());
CtMethod<Void> m = type.getMethod("test");
assertNotNull(m);
assertEquals(2, m.getBody().getStatements().size());
assertTrue(m.getBody().getStatements().get(0) instanceof CtTry);
assertTrue(m.getBody().getStatements().get(1) instanceof CtTryWithResource);
CtTryWithResource t2 = m.getBody().getStatement(1);
assertNotNull(t2.getResources());
}
@Test
public void testFullyQualifiedException() {
Factory factory = createFactory();
// test the order of the model
CtClass<?> clazz = factory
.Code()
.createCodeSnippetStatement(
"" + "class X {" + "public void foo() {"
+ " try{}catch(java.lang.RuntimeException e){}"
+ "}};").compile();
CtTry tryStmt = (CtTry) clazz.getElements(new TypeFilter<>(CtTry.class)).get(
0);
assertEquals(1, tryStmt.getCatchers().size());
}
@Test
public void testCatchOrder() {
Factory factory = createFactory();
// test the order of the model
CtClass<?> clazz = factory
.Code()
.createCodeSnippetStatement(
"" + "class X {" + "public void foo() {"
+ " try{}catch(RuntimeException e){java.lang.System.exit(0);}"
+ " catch(Exception e){}" + "}"
+ "};").compile();
CtTry tryStmt = (CtTry) clazz.getElements(new TypeFilter<>(CtTry.class)).get(
0);
// the first caught exception is RuntimeException
assertEquals(
RuntimeException.class,
tryStmt.getCatchers().get(0).getParameter().getType().getActualClass());
assertEquals("java.lang.System.exit(0)", tryStmt.getCatchers().get(0).getBody().getStatement(0).toString());
assertEquals(
Exception.class,
tryStmt.getCatchers().get(1).getParameter().getType().getActualClass());
}
@Test
public void testExceptionJava7() {
Factory factory = createFactory();
CtClass<?> clazz = factory
.Code()
.createCodeSnippetStatement(
"" + "class X {" + "public void foo() {"
+ " try{}catch(RuntimeException | Error e){System.exit(0);}" + "}"
+ "};").compile();
CtTry tryStmt = (CtTry) clazz.getElements(new TypeFilter<>(CtTry.class)).get(0);
List<CtCatch> catchers = tryStmt.getCatchers();
assertEquals(1, catchers.size());
assertEquals(
Throwable.class,
catchers.get(0).getParameter().getType().getActualClass());
assertEquals(2, catchers.get(0).getParameter().getMultiTypes().size());
assertEquals(
RuntimeException.class,
catchers.get(0).getParameter().getMultiTypes().get(0).getActualClass());
assertEquals(
Error.class,
catchers.get(0).getParameter().getMultiTypes().get(1).getActualClass());
// the code of the catch block is duplicated
assertEquals("java.lang.System.exit(0)", catchers.get(0).getBody().getStatement(0).toString());
}
@Test
public void testRethrowingExceptionsJava7() throws Exception {
CtClass<?> clazz = build("spoon.test.trycatch", "RethrowingClass");
CtMethod<?> method = (CtMethod<?>) clazz.getMethods().toArray()[0];
Set<CtTypeReference<? extends Throwable>> thrownTypes = method
.getThrownTypes();
// Checks we throw 2 exceptions and not one.
assertEquals(2, thrownTypes.size());
CtTry ctTry = clazz.getElements(new TypeFilter<CtTry>(CtTry.class))
.get(0);
Class<? extends CtCatchVariableReference> exceptionClass = ctTry
.getCatchers().get(0).getParameter().getReference().getClass();
// Checks the exception in the catch isn't on the signature of the method.
for (CtTypeReference<? extends Throwable> thrownType : thrownTypes) {
assertNotEquals(thrownType.getClass(), exceptionClass);
}
}
@Test
public void testTryWithOneResource() throws Exception {
CtClass<?> clazz = build("spoon.test.trycatch", "TryCatchResourceClass");
CtMethod<?> method = clazz.getMethodsByName("readFirstLineFromFile").get(0);
CtTryWithResource ctTryWithResource = method.getElements(
new TypeFilter<CtTryWithResource>(CtTryWithResource.class)).get(0);
// Checks try has only one resource.
assertTrue(ctTryWithResource.getResources().size() == 1);
}
@Test
public void testTryWithResources() throws Exception {
CtClass<?> clazz = build("spoon.test.trycatch", "TryCatchResourceClass");
CtMethod<?> method = clazz.getMethodsByName("writeToFileZipFileContents").get(0);
CtTryWithResource ctTryWithResource = method.getElements(
new TypeFilter<CtTryWithResource>(CtTryWithResource.class)).get(0);
// Checks try has more than one resource.
assertTrue(ctTryWithResource.getResources().size() > 1);
}
@Test
public void testMultiTryCatchWithCustomExceptions() throws Exception {
final Launcher launcher = new Launcher();
final SpoonModelBuilder compiler = launcher.createCompiler();
compiler.addInputSource(new File("./src/test/java/spoon/test/trycatch/testclasses/"));
compiler.build();
Factory factory = compiler.getFactory();
final CtClass<?> foo = (CtClass<?>) factory.Type().get(Foo.class);
final CtCatch ctCatch = foo.getElements(new AbstractFilter<CtCatch>(CtCatch.class) {
@Override
public boolean matches(CtCatch element) {
return true;
}
}).get(0);
final String expected = " catch (spoon.test.trycatch.testclasses.internal.MyException | spoon.test.trycatch.testclasses.internal.MyException2 ignore) {" + System.lineSeparator() + "}";
assertEquals(expected, ctCatch.toString());
}
@Test
public void testCompileMultiTryCatchWithCustomExceptions() throws Exception {
spoon.Launcher.main(new String[] {
"-i", "src/test/java/spoon/test/trycatch/testclasses",
"-o", "target/spooned"
});
final Launcher launcher = new Launcher();
final SpoonModelBuilder newCompiler = launcher.createCompiler();
newCompiler.addInputSource(new File("./target/spooned/spoon/test/trycatch/testclasses/"));
try {
assertTrue(newCompiler.build());
} catch (Exception e) {
fail(e.getMessage());
}
}
}