diff --git a/java/dagger/testing/compile/BUILD b/java/dagger/testing/compile/BUILD index 9a4070440e6..d90a6815d0b 100644 --- a/java/dagger/testing/compile/BUILD +++ b/java/dagger/testing/compile/BUILD @@ -32,6 +32,7 @@ java_library( "//third_party/java/compile_testing", "//third_party/java/junit", "//java/dagger/internal/codegen:processor", + "//java/dagger/internal/codegen/xprocessing", "//java/dagger/internal/codegen/xprocessing:xprocessing-testing", ], ) diff --git a/java/dagger/testing/compile/CompilerTests.java b/java/dagger/testing/compile/CompilerTests.java index a89585b062d..9d2c55ac08b 100644 --- a/java/dagger/testing/compile/CompilerTests.java +++ b/java/dagger/testing/compile/CompilerTests.java @@ -21,6 +21,9 @@ import static com.google.common.collect.Streams.stream; import static com.google.testing.compile.Compiler.javac; +import androidx.room.compiler.processing.XProcessingEnvConfig; +import androidx.room.compiler.processing.util.CompilationResultSubject; +import androidx.room.compiler.processing.util.ProcessorTestExtKt; import androidx.room.compiler.processing.util.Source; import androidx.room.compiler.processing.util.compiler.TestCompilationArguments; import androidx.room.compiler.processing.util.compiler.TestCompilationResult; @@ -42,7 +45,14 @@ /** A helper class for working with java compiler tests. */ public final class CompilerTests { - private CompilerTests() {} + // TODO(bcorso): Share this with java/dagger/internal/codegen/DelegateComponentProcessor.java + private static final XProcessingEnvConfig PROCESSING_ENV_CONFIG = + new XProcessingEnvConfig.Builder().disableAnnotatedElementValidation(true).build(); + + // TODO(bcorso): Share this with javatests/dagger/internal/codegen/Compilers.java + private static final ImmutableMap DEFAULT_PROCESSOR_OPTIONS = + ImmutableMap.of( + "dagger.experimentalDaggerErrorMessages", "enabled"); /** Returns the {@plainlink File jar file} containing the compiler deps. */ public static File compilerDepsJar() { @@ -87,30 +97,26 @@ public static void compileWithKapt( onCompilationResult.accept(result); } - public static void compileWithKsp( - List sources, - TemporaryFolder tempFolder, - Consumer onCompilationResult) { - compileWithKsp(sources, ImmutableMap.of(), tempFolder, onCompilationResult); - } - - public static void compileWithKsp( - List sources, - Map processorOptions, - TemporaryFolder tempFolder, - Consumer onCompilationResult) { - TestCompilationResult result = TestKotlinCompilerKt.compile( - tempFolder.getRoot(), - new TestCompilationArguments( - sources, - /*classpath=*/ ImmutableList.of(compilerDepsJar()), - /*inheritClasspath=*/ false, - /*javacArguments=*/ ImmutableList.of(), - /*kotlincArguments=*/ ImmutableList.of(), - /*kaptProcessors=*/ ImmutableList.of(), - /*symbolProcessorProviders=*/ ImmutableList.of(new KspComponentProcessor.Provider()), - /*processorOptions=*/ processorOptions)); - onCompilationResult.accept(result); + // TODO(bcorso): For Java users we may want to have a builder, similar to + // "com.google.testing.compile.Compiler", so that users can easily add custom options or + // processors along with their sources. + public static void compile( + ImmutableList sources, Consumer onCompilationResult) { + ProcessorTestExtKt.runProcessorTest( + sources, + /*classpath=*/ ImmutableList.of(compilerDepsJar()), + /*options=*/ DEFAULT_PROCESSOR_OPTIONS, + /*javacArguments=*/ ImmutableList.of(), + /*kotlincArguments=*/ ImmutableList.of(), + /*config=*/ PROCESSING_ENV_CONFIG, + /*javacProcessors=*/ ImmutableList.of(new ComponentProcessor()), + /*symbolProcessorProviders=*/ ImmutableList.of(new KspComponentProcessor.Provider()), + // TODO(bcorso): Typically, we would return a CompilationResult here and users would wrap + // that in an "assertThat" method to get the CompilationResultSubject. + result -> { + onCompilationResult.accept(result); + return null; + }); } private static File getRunfilesDir() { @@ -136,4 +142,6 @@ private static Path getRunfilesPath(Map map) { String runfilesPath = (String) map.get("TEST_SRCDIR"); return isNullOrEmpty(runfilesPath) ? null : Paths.get(runfilesPath); } + + private CompilerTests() {} } diff --git a/javatests/dagger/internal/codegen/kotlin/KspComponentProcessorTest.java b/javatests/dagger/internal/codegen/kotlin/KspComponentProcessorTest.java index 98035850444..1d8def8eeb1 100644 --- a/javatests/dagger/internal/codegen/kotlin/KspComponentProcessorTest.java +++ b/javatests/dagger/internal/codegen/kotlin/KspComponentProcessorTest.java @@ -16,24 +16,18 @@ package dagger.internal.codegen.kotlin; -import static com.google.common.truth.Truth.assertThat; -import static dagger.testing.compile.CompilerTests.compileWithKsp; +import static dagger.testing.compile.CompilerTests.compile; import androidx.room.compiler.processing.util.Source; import com.google.common.collect.ImmutableList; -import org.junit.Rule; import org.junit.Test; -import org.junit.rules.TemporaryFolder; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @RunWith(JUnit4.class) public final class KspComponentProcessorTest { - - @Rule public TemporaryFolder tempFolderRule = new TemporaryFolder(); - @Test - public void componentTest() throws Exception { + public void emptyComponentTest() throws Exception { Source componentSrc = Source.Companion.kotlin( "MyComponent.kt", @@ -47,9 +41,59 @@ public void componentTest() throws Exception { "@Component", "interface MyComponent {}")); - compileWithKsp( + compile( ImmutableList.of(componentSrc), - tempFolderRule, - result -> assertThat(result.getSuccess()).isTrue()); + subject -> { + subject.hasErrorCount(0); + subject.generatedSource( + Source.Companion.java( + "test/DaggerMyComponent", + String.join( + "\n", + "package test;", + "", + "import dagger.internal.DaggerGenerated;", + "import javax.annotation.processing.Generated;", + "", + "@DaggerGenerated", + "@Generated(", + " value = \"dagger.internal.codegen.ComponentProcessor\",", + " comments = \"https://dagger.dev\"", + ")", + "@SuppressWarnings({", + " \"unchecked\",", + " \"rawtypes\"", + "})", + "public final class DaggerMyComponent {", + " private DaggerMyComponent() {", + " }", + "", + " public static Builder builder() {", + " return new Builder();", + " }", + "", + " public static MyComponent create() {", + " return new Builder().build();", + " }", + "", + " public static final class Builder {", + " private Builder() {", + " }", + "", + " public MyComponent build() {", + " return new MyComponentImpl();", + " }", + " }", + "", + " private static final class MyComponentImpl implements MyComponent {", + " private final MyComponentImpl myComponentImpl = this;", + "", + " private MyComponentImpl() {", + "", + "", + " }", + " }", + "}"))); + }); } }