package spoon.test.snippets; import org.junit.Test; import spoon.Launcher; import spoon.compiler.SpoonResource; import spoon.reflect.code.CtBinaryOperator; import spoon.reflect.code.CtBlock; import spoon.reflect.code.CtCodeSnippetExpression; import spoon.reflect.code.CtExpression; import spoon.reflect.code.CtReturn; import spoon.reflect.declaration.CtClass; import spoon.reflect.declaration.CtElement; import spoon.reflect.declaration.CtMethod; import spoon.reflect.factory.Factory; import spoon.support.compiler.SnippetCompilationHelper; import spoon.support.compiler.VirtualFile; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static spoon.testing.utils.ModelUtils.createFactory; public class SnippetTest { Factory factory = createFactory(); @Test public void testSnippetFullClass() { CtClass<?> clazz = factory .Code() .createCodeSnippetStatement( "" + "class X {" + "public void foo() {" + " int x=0;" + "}" + "};").compile(); CtMethod<?> foo = (CtMethod<?>) clazz.getMethods().toArray()[0]; assertEquals(1, foo.getBody().getStatements().size()); } @Test public void testSnippetWihErrors() { try { factory.Code() .createCodeSnippetStatement( "" + "class X {" + "public void foo() {" + " int x=0 sdfsdf;" + "}" + "};") .compile(); fail(); } catch (Exception e) { // we expect an exception the code is incorrect } } @Test public void testCompileSnippetSeveralTimes() throws Exception { // contract: a snippet object can be reused several times final Factory factory = createFactory(); final CtCodeSnippetExpression<Object> snippet = factory.Code().createCodeSnippetExpression("1 > 2"); // Compile a first time the snippet. final CtExpression<Object> compile = snippet.compile(); // Compile a second time the same snippet. final CtExpression<Object> secondCompile = snippet.compile(); assertTrue(compile instanceof CtBinaryOperator); assertEquals("1 > 2", compile.toString()); assertTrue(secondCompile instanceof CtBinaryOperator); assertEquals("1 > 2", secondCompile.toString()); // Compile a third time a snippet but with an expression set. snippet.setValue("1 > 3"); final CtExpression<Object> thirdCompile = snippet.compile(); assertTrue(thirdCompile instanceof CtBinaryOperator); assertEquals("1 > 3", thirdCompile.toString()); } @Test public void testCompileSnippetWithContext() throws Exception { // contract: a snippet object can be compiled with a context in the factory. try { // Add a class in the context. factory.Class().create("AClass"); // Try to compile a snippet with a context. factory.Code().createCodeSnippetStatement("int i = 1;").compile(); } catch (ClassCastException e) { fail(); } } @Test public void testCompileStatementWithReturn() throws Exception { // contract: a snippet with return can be compiled. CtElement el = SnippetCompilationHelper.compileStatement( factory.Code().createCodeSnippetStatement("return 3"), factory.Type().INTEGER ); assertTrue(CtReturn.class.isAssignableFrom(el.getClass())); assertEquals("return 3", el.toString()); } @Test public void testIssue981() throws Exception { // contract: one can get the package of a string Launcher spoon = new Launcher(); spoon.getEnvironment().setNoClasspath(true); SpoonResource input = new VirtualFile("package foo.bar; class X {}"); spoon.addInputResource(input); spoon.buildModel(); assertEquals("foo.bar", spoon.getFactory().Type().get("foo.bar.X").getPackage().getQualifiedName()); } }