Commit 116a2632 authored by Daniel Bluhm's avatar Daniel Bluhm
Browse files

Add input, golden output style tests



For DataElement Annotation Processing
Signed-off-by: Daniel Bluhm's avatarDaniel Bluhm <bluhmdj@ornl.gov>
parent 7e29d719
......@@ -87,6 +87,12 @@
<version>5.6.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.testing.compile</groupId>
<artifactId>compile-testing</artifactId>
<version>0.18</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
......
......@@ -47,7 +47,7 @@ import com.google.auto.service.AutoService;
"org.eclipse.ice.dev.annotations.DataField.Default",
"org.eclipse.ice.dev.annotations.Persisted"
})
@SupportedSourceVersion(SourceVersion.RELEASE_8)
@SupportedSourceVersion(SourceVersion.RELEASE_11)
@AutoService(Processor.class)
public class DataElementProcessor extends AbstractProcessor {
......
package org.eclipse.ice.tests.dev.annotations.processors;
import static org.junit.jupiter.api.Assertions.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import static com.google.testing.compile.Compiler.*;
import static com.google.testing.compile.CompilationSubject.*;
import javax.annotation.processing.Processor;
import javax.tools.JavaFileObject;
import org.eclipse.ice.dev.annotations.processors.DataElementProcessor;
import org.junit.jupiter.api.Test;
import com.google.testing.compile.Compilation;
import com.google.testing.compile.JavaFileObjects;
import lombok.AllArgsConstructor;
class DataElementProcessorTest {
private static final String INTERFACE = "Test";
private static final String IMPLEMENTATION = "TestImplementation";
@AllArgsConstructor
private static enum Inputs {
HELLO_WORLD("HelloWorld.java"),
NAME_MISSING("DataElementNameMissing.java"),
ON_ENUM("DataElementOnEnum.java"),
ON_INTERFACE("DataElementOnInterface.java"),
NO_DATAFIELDS("NoDataFields.java"),
SINGLE("Single.java"),
MANY("Many.java"),
SINGLE_NON_PRIMITIVE("SingleNonPrimitive.java"),
MANY_NON_PRIMITIVE("ManyNonPrimitive.java"),
ACCESSIBILITY_PRESERVED("AccessibilityPreserved.java");
private static final String PARENT = "input/";
private String path;
public JavaFileObject get() {
return JavaFileObjects.forResource(PARENT + this.path);
}
}
@AllArgsConstructor
private static enum Patterns {
DEFAULTS_INT("Defaults.java"),
DEFAULTS_IMPL("DefaultsImplementation.java"),
SINGLE_INT("Single.java"),
SINGLE_IMPL("SingleImplementation.java"),
MANY_INT("Many.java"),
MANY_IMPL("ManyImplementation.java"),
SINGLE_NON_PRIMITIVE_INT("SingleNonPrimitive.java"),
SINGLE_NON_PRIMITIVE_IMPL("SingleNonPrimitiveImplementation.java"),
MANY_NON_PRIMITIVE_INT("ManyNonPrimitive.java"),
MANY_NON_PRIMITIVE_IMPL("ManyNonPrimitiveImplementation.java"),
ACCESSIBILITY_PRESERVED("AccessibilityPreserved.java");
private static final String PARENT = "patterns/";
private String path;
public JavaFileObject get() {
return JavaFileObjects.forResource(PARENT + this.path);
}
}
/**
* Retrieve an instance of Lombok's Annotation Processor.
*
* This is a nasty method that violates the accessibility of the Processor by
* reflection but is necessary to correctly process and test the generated code.
* @return lombok annotation processor
*/
private static Processor getLombokAnnotationProcessor() {
Processor p = null;
try {
Class<?> c = Class.forName("lombok.launch.AnnotationProcessorHider$AnnotationProcessor");
Constructor<?> constructor = c.getConstructor();
constructor.setAccessible(true);
p = (Processor) constructor.newInstance();
} catch (ClassNotFoundException | InstantiationException |
IllegalAccessException | IllegalArgumentException |
InvocationTargetException | NoSuchMethodException |
SecurityException e) {
System.err.println("Failed to get Lombok AnnotationProcessor!");
e.printStackTrace();
}
return p;
}
private static Compilation compile(JavaFileObject... sources) {
return javac()
.withProcessors(
getLombokAnnotationProcessor(),
new DataElementProcessor()
).compile(sources);
}
private static void assertInterfaceMatches(Compilation compilation, JavaFileObject inter) {
assertThat(compilation)
.generatedSourceFile(INTERFACE)
.containsElementsIn(inter);
}
private static void assertImplementationMatches(Compilation compilation, JavaFileObject impl) {
assertThat(compilation)
.generatedSourceFile(IMPLEMENTATION)
.containsElementsIn(impl);
}
private static void assertDefaultsPresent(Compilation compilation) {
assertInterfaceMatches(compilation, Patterns.DEFAULTS_INT.get());
assertImplementationMatches(compilation, Patterns.DEFAULTS_IMPL.get());
}
@Test
void testNoAnnotationsToProcessSucceeds() {
Compilation compilation = compile(Inputs.HELLO_WORLD.get());
assertThat(compilation).succeeded();
}
@Test
void testMissingNameFails() {
Compilation compilation = compile(Inputs.NAME_MISSING.get());
assertThat(compilation)
.hadErrorContaining(
"missing a default value for the element 'name'"
);
}
@Test
void testAnnotateInterfaceFails() {
Compilation compilation = compile(Inputs.ON_INTERFACE.get());
assertThat(compilation)
.hadErrorContaining("DataElementSpec must be class");
}
@Test
void testAnnotateEnumFails() {
Compilation compilation = compile(Inputs.ON_ENUM.get());
assertThat(compilation)
.hadErrorContaining("DataElementSpec must be class");
}
@Test
void testNoDataFieldsSucceeds() {
Compilation compilation = compile(Inputs.NO_DATAFIELDS.get());
assertDefaultsPresent(compilation);
}
@Test
void testWithSingleDataFieldSucceeds() {
Compilation compilation = compile(Inputs.SINGLE.get());
assertDefaultsPresent(compilation);
assertInterfaceMatches(compilation, Patterns.SINGLE_INT.get());
assertImplementationMatches(compilation, Patterns.SINGLE_IMPL.get());
}
@Test
void testWithManyDataFieldsSucceeds() {
Compilation compilation = compile(Inputs.MANY.get());
assertDefaultsPresent(compilation);
assertInterfaceMatches(compilation, Patterns.MANY_INT.get());
assertImplementationMatches(compilation, Patterns.MANY_IMPL.get());
}
@Test
void testSingleNonPrimitiveDataFieldSucceeds() {
Compilation compilation = compile(Inputs.SINGLE_NON_PRIMITIVE.get());
assertDefaultsPresent(compilation);
assertInterfaceMatches(compilation, Patterns.SINGLE_NON_PRIMITIVE_INT.get());
assertImplementationMatches(compilation, Patterns.SINGLE_NON_PRIMITIVE_IMPL.get());
}
@Test
void testManyNonPrimitiveDataFieldSucceeds() {
Compilation compilation = compile(Inputs.MANY_NON_PRIMITIVE.get());
assertDefaultsPresent(compilation);
assertInterfaceMatches(compilation, Patterns.MANY_NON_PRIMITIVE_INT.get());
assertImplementationMatches(compilation, Patterns.MANY_NON_PRIMITIVE_IMPL.get());
}
@Test
void testDocStringsPreserved() {
Compilation compilation = compile(Inputs.SINGLE.get());
assertThat(compilation).generatedSourceFile(IMPLEMENTATION)
.contentsAsUtf8String()
.contains("* A UNIQUE STRING IN THE DOC STRING.");
assertThat(compilation).generatedSourceFile(IMPLEMENTATION)
.contentsAsUtf8String()
.contains("* AND ANOTHER ON A NEW LINE.");
}
@Test
void testAccessibilityPreserved() {
Compilation compilation = compile(Inputs.ACCESSIBILITY_PRESERVED.get());
assertImplementationMatches(compilation, Patterns.ACCESSIBILITY_PRESERVED.get());
}
}
import org.eclipse.ice.dev.annotations.DataElement;
import org.eclipse.ice.dev.annotations.DataField;
@DataElement(name = "Test")
public class AccessibilityPreserved {
@DataField public int shouldBePublic;
@DataField protected int shouldBeProtected;
@DataField private int shouldBePrivate;
@DataField int shouldBePackage;
}
\ No newline at end of file
import org.eclipse.ice.dev.annotations.DataElement;
@DataElement
public class DataElementNameMissing {
public static void main(String[] args) {
System.out.println("Hello, world!");
}
}
\ No newline at end of file
import org.eclipse.ice.dev.annotations.DataElement;
@DataElement(name = "ShouldHaveBeenAClass")
public enum DataElementOnEnum {
HELLO, WORLD;
}
\ No newline at end of file
import org.eclipse.ice.dev.annotations.DataElement;
@DataElement(name = "ShouldHaveBeenAClass")
public interface DataElementOnInterface {
public static void main(String[] args);
}
\ No newline at end of file
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, world!");
}
}
import org.eclipse.ice.dev.annotations.DataElement;
import org.eclipse.ice.dev.annotations.DataField;
@DataElement(name = "Test")
public class Many {
@DataField public byte testByte;
@DataField public short testShort;
@DataField public int testInt;
@DataField public long testLong;
@DataField public float testFloat;
@DataField public double testDouble;
@DataField public boolean testBoolean;
@DataField public char testChar;
}
import org.eclipse.ice.dev.annotations.DataElement;
import org.eclipse.ice.dev.annotations.DataField;
@DataElement(name = "Test")
public class ManyNonPrimitive {
@DataField public java.util.UUID testUuid;
@DataField public java.lang.String testString;
@DataField public java.util.Date testDate;
}
\ No newline at end of file
import org.eclipse.ice.dev.annotations.DataElement;
@DataElement(name = "Test")
public class NoDataFields { }
\ No newline at end of file
import org.eclipse.ice.dev.annotations.DataElement;
import org.eclipse.ice.dev.annotations.DataField;
@DataElement(name = "Test")
public class Single {
/**
* A UNIQUE STRING IN THE DOC STRING.
*
* AND ANOTHER ON A NEW LINE.
*/
@DataField public int testInt;
}
import org.eclipse.ice.dev.annotations.DataElement;
import org.eclipse.ice.dev.annotations.DataField;
@DataElement(name = "Test")
public class SingleNonPrimitive {
@DataField public java.util.UUID testUuid;
}
\ No newline at end of file
@Data
@NoArgsConstructor
public class TestImplementation implements Test, Serializable {
public int shouldBePublic;
protected int shouldBeProtected;
private int shouldBePrivate;
int shouldBePackage;
}
\ No newline at end of file
import org.eclipse.ice.dev.annotations.IDataElement;
public interface Test extends IDataElement<Test> {}
\ No newline at end of file
@Data
@NoArgsConstructor
public class TestImplementation implements Test, Serializable {
@NonNull
@Getter(AccessLevel.NONE)
@Setter(AccessLevel.NONE)
protected java.util.UUID privateId = java.util.UUID.randomUUID();
protected long id = 0L;
@NonNull protected java.lang.String name = "name";
@NonNull protected java.lang.String description = "description";
@NonNull protected java.lang.String comment = "no comment";
@NonNull protected java.lang.String context = "default";
protected boolean required = false;
protected boolean secret = false;
protected org.eclipse.ice.dev.annotations.JavascriptValidator<Test> validator;
}
\ No newline at end of file
import org.eclipse.ice.dev.annotations.IDataElement;
public interface Test extends IDataElement<Test> {
public byte getTestByte();
public void setTestByte(byte testByte);
public short getTestShort();
public void setTestShort(short testShort);
public int getTestInt();
public void setTestInt(int testInt);
public long getTestLong();
public void setTestLong(long testLong);
public float getTestFloat();
public void setTestFloat(float testFloat);
public double getTestDouble();
public void setTestDouble(double testDouble);
public boolean isTestBoolean();
public void setTestBoolean(boolean testBoolean);
public char getTestChar();
public void setTestChar(char testChar);
}
\ No newline at end of file
@Data
@NoArgsConstructor
public class TestImplementation implements Test, Serializable {
public byte testByte;
public short testShort;
public int testInt;
public long testLong;
public float testFloat;
public double testDouble;
public boolean testBoolean;
public char testChar;
}
\ No newline at end of file
import org.eclipse.ice.dev.annotations.IDataElement;
public interface Test extends IDataElement<Test> {
public java.util.UUID getTestUuid();
public void setTestUuid(java.util.UUID testUuid);
public java.lang.String getTestString();
public void setTestString(java.lang.String testString);
public java.util.Date getTestDate();
public void setTestDate(java.util.Date testDate);
}
\ No newline at end of file
@Data
@NoArgsConstructor
public class TestImplementation implements Test, Serializable {
@NonNull public java.util.UUID testUuid;
@NonNull public java.lang.String testString;
@NonNull public java.util.Date testDate;
}
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment