/* * -\-\- * DataEnum * -- * Copyright (c) 2017 Spotify AB * -- * 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.spotify.dataenum.processor; import static com.google.testing.compile.CompilationSubject.assertThat; import static com.google.testing.compile.Compiler.javac; import com.google.testing.compile.Compilation; import com.google.testing.compile.JavaFileObjects; import java.util.ArrayList; import java.util.List; import javax.tools.JavaFileObject; import org.junit.Test; public class IntegrationTest { private static void assertThatEnumGeneratedMatchingFile(String className, String... extraFiles) { List<JavaFileObject> files = new ArrayList<>(extraFiles.length + 1); files.add(JavaFileObjects.forResource(className + "_dataenum.java")); for (String file : extraFiles) { files.add(JavaFileObjects.forResource(file)); } Compilation compilation = javac() .withOptions("-implicit:class") .withProcessors(new DataEnumProcessor()) .compile(files); assertThat(compilation).succeededWithoutWarnings(); assertThat(compilation) .generatedSourceFile(className) .hasSourceEquivalentTo(JavaFileObjects.forResource(className + ".java")); } @Test public void conflictingFieldNames() throws Exception { assertThatEnumGeneratedMatchingFile("ConflictingFieldNames"); } @Test public void emptyEnum() throws Exception { assertThatEnumGeneratedMatchingFile("Empty"); } @Test public void emptyValueEnum() throws Exception { assertThatEnumGeneratedMatchingFile("EmptyValue"); } @Test public void primitiveValueEnum() throws Exception { assertThatEnumGeneratedMatchingFile("PrimitiveValue"); } @Test public void recursiveValueEnum() throws Exception { assertThatEnumGeneratedMatchingFile("RecursiveValue"); } @Test public void nullableValueEnum() throws Exception { assertThatEnumGeneratedMatchingFile("NullableValue"); } @Test public void multipleValuesEnum() throws Exception { assertThatEnumGeneratedMatchingFile("MultipleValues"); } @Test public void genericValuesEnum() throws Exception { assertThatEnumGeneratedMatchingFile("GenericValues"); } @Test public void privateConstructors() throws Exception { assertThatEnumGeneratedMatchingFile("hide/ctors/PrivateConstructors", "hide/package-info.java"); } @Test public void efficientEquals() throws Exception { assertThatEnumGeneratedMatchingFile("EfficientEquals", "MyEnum.java"); } @Test public void genericValuesGeneratedCodeCompiles() throws Exception { Compilation compilation = javac() .withOptions("-Xlint:all") .compile(JavaFileObjects.forResource("GenericValues.java")); assertThat(compilation).succeededWithoutWarnings(); } @Test public void recursiveGenericValueEnum() throws Exception { assertThatEnumGeneratedMatchingFile("RecursiveGenericValue"); } @Test public void innerGenericValueEnum() throws Exception { assertThatEnumGeneratedMatchingFile("InnerGenericValue"); } @Test public void outputHasTheSamePackage() throws Exception { assertThatEnumGeneratedMatchingFile("just/some/pkg/InPackage"); } @Test public void varargValueEnum() throws Exception { Compilation compilation = javac() .withProcessors(new DataEnumProcessor()) .compile(JavaFileObjects.forResource("VarargValue_dataenum.java")); assertThat(compilation).failed(); assertThat(compilation).hadErrorCount(1); assertThat(compilation).hadErrorContaining("Vararg parameters not permitted"); } @Test public void enumAsInner() throws Exception { assertThatEnumGeneratedMatchingFile("EnumAsInner"); } @Test public void arrayFields() throws Exception { assertThatEnumGeneratedMatchingFile("ArrayFields"); } @Test public void redactedStrings() throws Exception { assertThatEnumGeneratedMatchingFile("Redacted"); } @Test public void referenceOtherDataenum() throws Exception { Compilation compilation = javac() .withOptions("-implicit:class") .withProcessors(new DataEnumProcessor()) .compile(JavaFileObjects.forResource("ReferencesOther_dataenum.java")); assertThat(compilation).succeededWithoutWarnings(); assertThat(compilation) .generatedSourceFile("ReferencesOther") .hasSourceEquivalentTo(JavaFileObjects.forResource("ReferencesOther" + ".java")); } @Test public void shouldNotWarnAboutPublicSpec() throws Exception { Compilation compilation = javac() .withProcessors(new DataEnumProcessor()) .compile(JavaFileObjects.forResource("PublicSpec_dataenum.java")); assertThat(compilation).succeeded(); assertThat(compilation).hadWarningCount(0); } @Test public void shouldReportBadValueSpecs() throws Exception { Compilation compilation = javac() .withProcessors(new DataEnumProcessor()) .compile(JavaFileObjects.forResource("BadValueSpecs_dataenum.java")); assertThat(compilation).failed(); assertThat(compilation).hadErrorCount(2); assertThat(compilation).hadErrorContaining("Value specs must be methods, found interface"); assertThat(compilation).hadErrorContaining("Value specs must return dataenum_case, found void"); } @Test public void shouldReportGenericsOnValueSpecs() throws Exception { Compilation compilation = javac() .withProcessors(new DataEnumProcessor()) .compile(JavaFileObjects.forResource("GenericDeclarationOnValues_dataenum.java")); assertThat(compilation).failed(); assertThat(compilation).hadErrorCount(1); assertThat(compilation) .hadErrorContaining( "Type parameters must be specified on the top-level interface, found: <T>Just(T)"); } @Test public void shouldReportNonInterfaceSpecs() throws Exception { Compilation compilation = javac() .withProcessors(new DataEnumProcessor()) .compile(JavaFileObjects.forResource("NonInterfaceSpec_dataenum.java")); assertThat(compilation).failed(); assertThat(compilation).hadErrorCount(1); assertThat(compilation).hadErrorContaining("@DataEnum can only be used on interfaces"); } @Test public void shouldReportDuplicateCaseNames() throws Exception { Compilation compilation = javac() .withProcessors(new DataEnumProcessor()) .compile(JavaFileObjects.forResource("DuplicateCases_dataenum.java")); assertThat(compilation).failed(); assertThat(compilation).hadErrorCount(2); assertThat(compilation).hadErrorContaining("Duplicate case name 'value'"); assertThat(compilation).hadErrorContaining("Duplicate case name 'caseisimportant'"); } @Test public void shouldGenerateLinkToSourceAsJavadocComment() { Compilation compilation = javac() .withOptions("-implicit:class") .withProcessors(new DataEnumProcessor()) .compile(JavaFileObjects.forResource("javadoc/Javadoc_dataenum.java")); assertThat(compilation).succeededWithoutWarnings(); assertThat(compilation) .generatedSourceFile("javadoc.Javadoc") .contentsAsUtf8String() .contains(" * Generated from {@link Javadoc_dataenum}"); } @Test public void shouldGenerateLinkToCaseSourceAsJavadocCommentOnFactoryMethod() { Compilation compilation = javac() .withOptions("-implicit:class") .withProcessors(new DataEnumProcessor()) .compile(JavaFileObjects.forResource("javadoc/Javadoc_dataenum.java")); assertThat(compilation).succeededWithoutWarnings(); assertThat(compilation) .generatedSourceFile("javadoc.Javadoc") .contentsAsUtf8String() .contains(" * @return a {@link Value} (see {@link Javadoc_dataenum#Value} for source)"); } @Test public void shouldCopyDocFromCaseSourceToJavadocCommentOnFactoryMethod() { Compilation compilation = javac() .withOptions("-implicit:class") .withProcessors(new DataEnumProcessor()) .compile(JavaFileObjects.forResource("javadoc/Javadoc_dataenum.java")); assertThat(compilation).succeededWithoutWarnings(); assertThat(compilation) .generatedSourceFile("javadoc.Javadoc") .contentsAsUtf8String() .contains( "/**\n" + " * Some documentation about this case.\n" + " *\n" + " * @return a {@link Documented} (see {@link Javadoc_dataenum#Documented} for source)\n" + " */\n"); } @Test public void shouldCopyAnnotationsFromCaseSourceToFactoryMethod() { assertThatEnumGeneratedMatchingFile("annotation/Annotation", "annotation/MyAnnotation.java"); } }