AnnotationProcessingTests.java
/*******************************************************************************
* Copyright (c) 2014 Contributors
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt
*
* Contributors:
* Andy Clement - initial API and implementation
*******************************************************************************/
package org.aspectj.systemtest.incremental.tools;
import java.io.File;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import org.aspectj.util.FileUtil;
public class AnnotationProcessingTests extends AbstractMultiProjectIncrementalAjdeInteractionTestbed {
@Override
protected void tearDown() throws Exception {
super.tearDown();
new File("Advise_aaa.java").delete();
new File("Advise_ccc.java").delete();
new File("Advise_boo.java").delete();
new File("Advise_too.java").delete();
new File("AroundAdvise_aaa.java").delete();
new File("AroundAdvise_ccc.java").delete();
if (new File("../run-all-junit-tests/generated/test/SomeCallbacks.java").exists()) {
FileUtil.deleteContents(new File("../run-all-junit-tests/generated"));
new File("../run-all-junit-tests/generated").delete();
}
}
// Basic test: turns on annotation processing and tries to run the DemoProcessor
public void testAnnotationProcessing1() throws Exception {
createAndBuildAnnotationProcessorProject("ProcessorProject");
initialiseProject("ProcessorConsumer1");
configureProcessorOptions("ProcessorConsumer1","DemoProcessor");
configureNonStandardCompileOptions("ProcessorConsumer1", "-showWeaveInfo");
Map<String, String> javaOptions = new Hashtable<>();
javaOptions.put("org.eclipse.jdt.core.compiler.compliance", "1.8");
javaOptions.put("org.eclipse.jdt.core.compiler.codegen.targetPlatform", "1.8");
javaOptions.put("org.eclipse.jdt.core.compiler.source", "1.8");
javaOptions.put("org.eclipse.jdt.core.compiler.processAnnotations","enabled");
configureJavaOptionsMap("ProcessorConsumer1", javaOptions);
configureNewProjectDependency("ProcessorConsumer1", "ProcessorProject");
configureNonStandardCompileOptions("ProcessorConsumer1", "-showWeaveInfo");
build("ProcessorConsumer1");
checkWasFullBuild();
checkCompiledFiles("ProcessorConsumer1","Advise_ccc.java","Advise_aaa.java","Code.java");
assertEquals(2,getWeavingMessages("ProcessorConsumer1").size());
String out = runMethod("ProcessorConsumer1", "Code", "runner");
assertEquals("aaa running\nccc running\n",out.replace("\r",""));
}
// services file in processor project
public void testAnnotationProcessing2() throws Exception {
createAndBuildAnnotationProcessorProject("ProcessorProject2"); // This has a META-INF services entry for DemoProcessor
initialiseProject("ProcessorConsumer2");
// Paths here are the path to DemoProcessor (compiled into the output folder of the ProcessorProject2) and the path to
// the META-INF file declaring DemoProcessor (since it is not copied to that same output folder) - this exists in the test src
// folder for ProcessorProject2
configureProcessorPath("ProcessorConsumer2", getCompilerForProjectWithName("ProcessorProject2").getCompilerConfiguration().getOutputLocationManager().getDefaultOutputLocation().toString()+File.pathSeparator+
new File(testdataSrcDir + File.separatorChar + "ProcessorProject2" + File.separatorChar + "base"+File.separatorChar+"src").toString());
Map<String, String> javaOptions = new Hashtable<>();
javaOptions.put("org.eclipse.jdt.core.compiler.compliance", "1.8");
javaOptions.put("org.eclipse.jdt.core.compiler.codegen.targetPlatform", "1.8");
javaOptions.put("org.eclipse.jdt.core.compiler.source", "1.8");
javaOptions.put("org.eclipse.jdt.core.compiler.processAnnotations","enabled");
configureJavaOptionsMap("ProcessorConsumer2", javaOptions);
initialiseProject("ProcessorConsumer2");
configureNewProjectDependency("ProcessorConsumer2", "ProcessorProject");
configureNonStandardCompileOptions("ProcessorConsumer2", "-showWeaveInfo");
build("ProcessorConsumer2");
checkWasFullBuild();
checkCompiledFiles("ProcessorConsumer2","Advise_ccc.java","Advise_aaa.java","Code.java");
assertEquals(2,getWeavingMessages("ProcessorConsumer2").size());
String out = runMethod("ProcessorConsumer2", "Code", "runner");
assertEquals("aaa running\nccc running\n",out.replace("\r",""));
}
// Two processors
public void testAnnotationProcessing3() throws Exception {
createAndBuildAnnotationProcessorProject("ProcessorProject2");
createAndBuildAnnotationProcessorProject("ProcessorProject3");
initialiseProject("ProcessorConsumer1");
// Paths here are the path to DemoProcessor/DemoProcessor2 compiled code and the path to
// the META-INF file declaring DemoProcessor/DemoProcessor2 (since they are not copied to that same output folder) -
// these exists in the test src folders for ProcessorProject2/ProcessorProject3
configureProcessorPath("ProcessorConsumer1",
getCompilerForProjectWithName("ProcessorProject3").getCompilerConfiguration().getOutputLocationManager().getDefaultOutputLocation().toString()+File.pathSeparator+
new File(testdataSrcDir + File.separatorChar + "ProcessorProject3" + File.separatorChar + "base"+File.separatorChar+"src").toString()
+File.pathSeparator+
getCompilerForProjectWithName("ProcessorProject2").getCompilerConfiguration().getOutputLocationManager().getDefaultOutputLocation().toString()+File.pathSeparator+
new File(testdataSrcDir + File.separatorChar + "ProcessorProject2" + File.separatorChar + "base"+File.separatorChar+"src").toString()
);
// The order here is DemoProcessor2 then DemoProcessor - to get the second one to run I changed DemoProcessor2 to operate on a
// specific annotation (java.lang.SuppressWarnings) and return false at the end
configureNonStandardCompileOptions("ProcessorConsumer1", "-showWeaveInfo");
Map<String, String> javaOptions = new Hashtable<>();
javaOptions.put("org.eclipse.jdt.core.compiler.compliance", "1.8");
javaOptions.put("org.eclipse.jdt.core.compiler.codegen.targetPlatform", "1.8");
javaOptions.put("org.eclipse.jdt.core.compiler.source", "1.8");
javaOptions.put("org.eclipse.jdt.core.compiler.processAnnotations","enabled");
configureJavaOptionsMap("ProcessorConsumer1", javaOptions);
configureNewProjectDependency("ProcessorConsumer1", "ProcessorProject");
configureNonStandardCompileOptions("ProcessorConsumer1", "-showWeaveInfo");
build("ProcessorConsumer1");
checkWasFullBuild();
checkCompiledFiles("ProcessorConsumer1","Advise_ccc.java","Advise_aaa.java","Code.java","AroundAdvise_ccc.java","AroundAdvise_aaa.java");
assertEquals(4,getWeavingMessages("ProcessorConsumer1").size());
String out = runMethod("ProcessorConsumer1", "Code", "runner");
assertEquals("aaa running\nAround advice on aaa running\nccc running\nAround advice on ccc running\n",out.replace("\r",""));
}
// Tests:
// TODO Incremental compilation - what does that mean with annotation processors?
// ---
private void createAndBuildAnnotationProcessorProject(String processorProjectName) {
initialiseProject(processorProjectName);
build(processorProjectName);
checkWasFullBuild();
assertNoErrors(processorProjectName);
}
private void configureProcessorOptions(String projectName, String processor) {
configureProcessor(projectName, "DemoProcessor");
// Assume all processors from processor project
configureProcessorPath(projectName, getCompilerForProjectWithName("ProcessorProject").getCompilerConfiguration().getOutputLocationManager().getDefaultOutputLocation().toString());
}
private void checkCompiledFiles(String projectName, String... expectedCompiledFiles) {
List<String> compiledFiles = new ArrayList<>(getCompiledFiles(projectName));
if (compiledFiles.size()!=expectedCompiledFiles.length) {
fail("Expected #"+expectedCompiledFiles.length+" files to be compiled but found that #"+compiledFiles.size()+" files were compiled.\nCompiled="+compiledFiles);
}
for (String expectedCompiledFile: expectedCompiledFiles) {
String toRemove = null;
for (String compiledFile: compiledFiles) {
String cfile = compiledFile.substring(compiledFile.lastIndexOf(File.separator)+1);
if (cfile.equals(expectedCompiledFile)) {
toRemove = compiledFile;
break;
}
}
if (toRemove!=null) compiledFiles.remove(toRemove);
}
// Anything left in compiledFiles wasn't expected to be built
if (compiledFiles.size()!=0) {
fail("These were not expected to be compiled: "+compiledFiles);
}
}
}