From bfdb10962bbd1cdf3c695f3d9fa8b87f8984a21d Mon Sep 17 00:00:00 2001 From: Brad Corso Date: Mon, 26 Apr 2021 17:08:32 -0700 Subject: [PATCH] Add flag to disable cross-compilation root validation. Fixes #2577 RELNOTES=Fixes #2577: Add flag to disable cross-compilation root validation. PiperOrigin-RevId: 370573954 --- .../AndroidEntryPointMetadata.java | 4 +- java/dagger/hilt/processor/internal/BUILD | 5 ++ .../internal/HiltCompilerOptions.java | 74 ++++++++++++++----- .../AggregatedDepsProcessor.java | 4 +- .../processor/internal/root/RootMetadata.java | 4 +- .../internal/root/RootProcessor.java | 55 +++++++------- .../dagger/hilt/processor/internal/root/BUILD | 3 + .../root/MyAppPreviousCompilationTest.java | 53 ++++++++++--- .../root/MyTestPreviousCompilationTest.java | 69 ++++++++++++----- .../root/RootProcessorErrorsTest.java | 32 +++++++- 10 files changed, 220 insertions(+), 83 deletions(-) diff --git a/java/dagger/hilt/android/processor/internal/androidentrypoint/AndroidEntryPointMetadata.java b/java/dagger/hilt/android/processor/internal/androidentrypoint/AndroidEntryPointMetadata.java index cdec4269a51..c94f6a977ab 100644 --- a/java/dagger/hilt/android/processor/internal/androidentrypoint/AndroidEntryPointMetadata.java +++ b/java/dagger/hilt/android/processor/internal/androidentrypoint/AndroidEntryPointMetadata.java @@ -16,7 +16,7 @@ package dagger.hilt.android.processor.internal.androidentrypoint; -import static dagger.hilt.processor.internal.HiltCompilerOptions.BooleanOption.DISABLE_ANDROID_SUPERCLASS_VALIDATION; +import static dagger.hilt.processor.internal.HiltCompilerOptions.isAndroidSuperclassValidationDisabled; import static dagger.internal.codegen.extension.DaggerStreams.toImmutableSet; import com.google.auto.common.MoreElements; @@ -245,7 +245,7 @@ private static AndroidEntryPointMetadata of( final TypeElement baseElement; final ClassName generatedClassName; boolean requiresBytecodeInjection = - DISABLE_ANDROID_SUPERCLASS_VALIDATION.get(env) + isAndroidSuperclassValidationDisabled(androidEntryPointElement, env) && MoreTypes.isTypeOf(Void.class, androidEntryPointClassValue.asType()); if (requiresBytecodeInjection) { baseElement = MoreElements.asType(env.getTypeUtils().asElement(androidEntryPointElement.getSuperclass())); diff --git a/java/dagger/hilt/processor/internal/BUILD b/java/dagger/hilt/processor/internal/BUILD index 93dba0fb70b..978655dea55 100644 --- a/java/dagger/hilt/processor/internal/BUILD +++ b/java/dagger/hilt/processor/internal/BUILD @@ -154,6 +154,11 @@ java_library( java_library( name = "compiler_options", srcs = ["HiltCompilerOptions.java"], + deps = [ + ":processor_errors", + "//java/dagger/internal/guava:collect", + "@google_bazel_common//third_party/java/javapoet", + ], ) filegroup( diff --git a/java/dagger/hilt/processor/internal/HiltCompilerOptions.java b/java/dagger/hilt/processor/internal/HiltCompilerOptions.java index 7cf82ee3f8a..0d248239bd9 100644 --- a/java/dagger/hilt/processor/internal/HiltCompilerOptions.java +++ b/java/dagger/hilt/processor/internal/HiltCompilerOptions.java @@ -16,36 +16,74 @@ package dagger.hilt.processor.internal; +import com.google.common.collect.ImmutableSet; import java.util.Arrays; import java.util.Set; import java.util.stream.Collectors; import javax.annotation.processing.ProcessingEnvironment; +import javax.lang.model.element.TypeElement; /** Hilt annotation processor options. */ // TODO(danysantiago): Consider consolidating with Dagger compiler options logic. public final class HiltCompilerOptions { + /** + * Returns {@code true} if the superclass validation is disabled for + * {@link dagger.hilt.android.AndroidEntryPoint}-annotated classes. + * + * This flag is for internal use only! The superclass validation checks that the super class is a + * generated {@code Hilt_} class. This flag is disabled by the Hilt Gradle plugin to enable + * bytecode transformation to change the superclass. + */ + public static boolean isAndroidSuperclassValidationDisabled( + TypeElement element, ProcessingEnvironment env) { + BooleanOption option = BooleanOption.DISABLE_ANDROID_SUPERCLASS_VALIDATION; + return option.get(env); + } + + /** + * Returns {@code true} if cross-compilation root validation is disabled. + * + *

This flag should rarely be needed, but may be used for legacy/migration purposes if + * tests require the use of {@link dagger.hilt.android.HiltAndroidApp} rather than + * {@link dagger.hilt.android.testing.HiltAndroidTest}. + * + *

Note that Hilt still does validation within a single compilation unit. In particular, + * a compilation unit that contains a {@code HiltAndroidApp} usage cannot have other + * {@code HiltAndroidApp} or {@code HiltAndroidTest} usages in the same compilation unit. + */ + public static boolean isCrossCompilationRootValidationDisabled( + ImmutableSet rootElements, ProcessingEnvironment env) { + BooleanOption option = BooleanOption.DISABLE_CROSS_COMPILATION_ROOT_VALIDATION; + return option.get(env); + } + + /** Returns {@code true} if the check for {@link dagger.hilt.InstallIn} is disabled. */ + public static boolean isModuleInstallInCheckDisabled(ProcessingEnvironment env) { + return BooleanOption.DISABLE_MODULES_HAVE_INSTALL_IN_CHECK.get(env); + } + + /** + * Returns {@code true} of unit tests should try to share generated components, rather than using + * separate generated components per Hilt test root. + * + *

Tests that provide their own test bindings (e.g. using {@link + * dagger.hilt.android.testing.BindValue} or a test {@link dagger.Module}) cannot use the shared + * component. In these cases, a component will be generated for the test. + */ + public static boolean isSharedTestComponentsEnabled(ProcessingEnvironment env) { + return BooleanOption.SHARE_TEST_COMPONENTS.get(env); + } + /** Processor options which can have true or false values. */ - public enum BooleanOption { - /** - * Flag that disables validating the superclass of @AndroidEntryPoint are Hilt_ generated, - * classes. This flag is to be used internally by the Gradle plugin, enabling the bytecode - * transformation to change the superclass. - */ + private enum BooleanOption { DISABLE_ANDROID_SUPERCLASS_VALIDATION( "android.internal.disableAndroidSuperclassValidation", false), - /** Flag that disables check on modules to be annotated with @InstallIn. */ + DISABLE_CROSS_COMPILATION_ROOT_VALIDATION("disableCrossCompilationRootValidation", false), + DISABLE_MODULES_HAVE_INSTALL_IN_CHECK("disableModulesHaveInstallInCheck", false), - /** - * Flag that enables unit tests to share a single generated Component, rather than using a - * separate generated Component per Hilt test root. - * - *

Tests that provide their own test bindings (e.g. using {@link - * dagger.hilt.android.testing.BindValue} or a test {@link dagger.Module}) cannot use the shared - * component. In these cases, a component will be generated for the test. - */ SHARE_TEST_COMPONENTS("shareTestComponents", false); private final String name; @@ -56,7 +94,7 @@ public enum BooleanOption { this.defaultValue = defaultValue; } - public boolean get(ProcessingEnvironment env) { + boolean get(ProcessingEnvironment env) { String value = env.getOptions().get(getQualifiedName()); if (value == null) { return defaultValue; @@ -65,7 +103,7 @@ public boolean get(ProcessingEnvironment env) { return Boolean.parseBoolean(value); } - public String getQualifiedName() { + String getQualifiedName() { return "dagger.hilt." + name; } } @@ -75,6 +113,4 @@ public static Set getProcessorOptions() { .map(BooleanOption::getQualifiedName) .collect(Collectors.toSet()); } - - private HiltCompilerOptions() {} } diff --git a/java/dagger/hilt/processor/internal/aggregateddeps/AggregatedDepsProcessor.java b/java/dagger/hilt/processor/internal/aggregateddeps/AggregatedDepsProcessor.java index c45b373cbb5..151401e6082 100644 --- a/java/dagger/hilt/processor/internal/aggregateddeps/AggregatedDepsProcessor.java +++ b/java/dagger/hilt/processor/internal/aggregateddeps/AggregatedDepsProcessor.java @@ -20,7 +20,7 @@ import static com.google.auto.common.MoreElements.asType; import static com.google.auto.common.MoreElements.getPackage; import static com.google.common.collect.Iterables.getOnlyElement; -import static dagger.hilt.processor.internal.HiltCompilerOptions.BooleanOption.DISABLE_MODULES_HAVE_INSTALL_IN_CHECK; +import static dagger.hilt.processor.internal.HiltCompilerOptions.isModuleInstallInCheckDisabled; import static dagger.internal.codegen.extension.DaggerStreams.toImmutableList; import static dagger.internal.codegen.extension.DaggerStreams.toImmutableSet; import static javax.lang.model.element.ElementKind.CLASS; @@ -398,7 +398,7 @@ private static boolean isValidKind(Element element) { } private boolean installInCheckDisabled(Element element) { - return DISABLE_MODULES_HAVE_INSTALL_IN_CHECK.get(getProcessingEnv()) + return isModuleInstallInCheckDisabled(getProcessingEnv()) || Processors.hasAnnotation(element, ClassNames.DISABLE_INSTALL_IN_CHECK); } diff --git a/java/dagger/hilt/processor/internal/root/RootMetadata.java b/java/dagger/hilt/processor/internal/root/RootMetadata.java index 1a115034ff1..b39b590efc6 100644 --- a/java/dagger/hilt/processor/internal/root/RootMetadata.java +++ b/java/dagger/hilt/processor/internal/root/RootMetadata.java @@ -18,7 +18,7 @@ import static com.google.common.base.Preconditions.checkState; import static com.google.common.base.Suppliers.memoize; -import static dagger.hilt.processor.internal.HiltCompilerOptions.BooleanOption.SHARE_TEST_COMPONENTS; +import static dagger.hilt.processor.internal.HiltCompilerOptions.isSharedTestComponentsEnabled; import static dagger.internal.codegen.extension.DaggerStreams.toImmutableSet; import static javax.lang.model.element.Modifier.ABSTRACT; import static javax.lang.model.element.Modifier.PRIVATE; @@ -133,7 +133,7 @@ public ImmutableSet modules(ClassName componentName) { // TODO(groakley): Allow more tests to share modules, e.g. tests that uninstall the same module. // In that case, this might instead return which shared dep grouping should be used. public boolean canShareTestComponents() { - return SHARE_TEST_COMPONENTS.get(env) + return isSharedTestComponentsEnabled(env) && root.isTestRoot() && !deps.includesTestDeps(root.classname()); } diff --git a/java/dagger/hilt/processor/internal/root/RootProcessor.java b/java/dagger/hilt/processor/internal/root/RootProcessor.java index 3ef8963641d..1ee4446d48c 100644 --- a/java/dagger/hilt/processor/internal/root/RootProcessor.java +++ b/java/dagger/hilt/processor/internal/root/RootProcessor.java @@ -17,7 +17,8 @@ package dagger.hilt.processor.internal.root; import static com.google.common.base.Preconditions.checkState; -import static dagger.hilt.processor.internal.HiltCompilerOptions.BooleanOption.SHARE_TEST_COMPONENTS; +import static dagger.hilt.processor.internal.HiltCompilerOptions.isCrossCompilationRootValidationDisabled; +import static dagger.hilt.processor.internal.HiltCompilerOptions.isSharedTestComponentsEnabled; import static dagger.internal.codegen.extension.DaggerStreams.toImmutableList; import static dagger.internal.codegen.extension.DaggerStreams.toImmutableSet; import static java.util.Comparator.comparing; @@ -136,7 +137,7 @@ public void postRoundProcess(RoundEnvironment roundEnv) throws Exception { boolean isTestEnv = rootsToProcess.stream().anyMatch(Root::isTestRoot); ComponentNames componentNames = - isTestEnv && SHARE_TEST_COMPONENTS.get(getProcessingEnv()) + isTestEnv && isSharedTestComponentsEnabled(getProcessingEnv()) ? ComponentNames.withRenamingIntoPackage( ClassNames.DEFAULT_ROOT.packageName(), rootsToProcess.stream().map(Root::element).collect(toImmutableList())) @@ -202,23 +203,6 @@ private void validateRoots(ImmutableSet allRoots, ImmutableSet roots .sorted(QUALIFIED_NAME_COMPARATOR) .collect(toImmutableSet()); - ImmutableSet processedTestRootElements = - allRoots.stream() - .filter(Root::isTestRoot) - .filter(root -> !rootsToProcess.contains(root)) - .map(Root::element) - .sorted(QUALIFIED_NAME_COMPARATOR) - .collect(toImmutableSet()); - - // TODO(b/185742783): Add an explanation or link to docs to explain why we're forbidding this. - ProcessorErrors.checkState( - processedTestRootElements.isEmpty(), - "Cannot process new roots when there are test roots from a previous compilation unit:" - + "\n\tTest roots from previous compilation unit: %s" - + "\n\tAll roots from this compilation unit: %s", - processedTestRootElements, - rootElementsToProcess); - ImmutableSet appRootElementsToProcess = rootsToProcess.stream() .filter(root -> !root.isTestRoot()) @@ -226,6 +210,7 @@ private void validateRoots(ImmutableSet allRoots, ImmutableSet roots .sorted(QUALIFIED_NAME_COMPARATOR) .collect(toImmutableSet()); + // Perform validation between roots in this compilation unit. if (!appRootElementsToProcess.isEmpty()) { ImmutableSet testRootElementsToProcess = rootsToProcess.stream() @@ -242,6 +227,31 @@ private void validateRoots(ImmutableSet allRoots, ImmutableSet roots appRootElementsToProcess, testRootElementsToProcess); + ProcessorErrors.checkState( + appRootElementsToProcess.size() == 1, + "Cannot process multiple app roots in the same compilation unit: %s", + appRootElementsToProcess); + } + + // Perform validation across roots previous compilation units. + if (!isCrossCompilationRootValidationDisabled(rootElementsToProcess, getProcessingEnv())) { + ImmutableSet processedTestRootElements = + allRoots.stream() + .filter(Root::isTestRoot) + .filter(root -> !rootsToProcess.contains(root)) + .map(Root::element) + .sorted(QUALIFIED_NAME_COMPARATOR) + .collect(toImmutableSet()); + + // TODO(b/185742783): Add an explanation or link to docs to explain why we're forbidding this. + ProcessorErrors.checkState( + processedTestRootElements.isEmpty(), + "Cannot process new roots when there are test roots from a previous compilation unit:" + + "\n\tTest roots from previous compilation unit: %s" + + "\n\tAll roots from this compilation unit: %s", + processedTestRootElements, + rootElementsToProcess); + ImmutableSet processedAppRootElements = allRoots.stream() .filter(root -> !root.isTestRoot()) @@ -251,18 +261,13 @@ private void validateRoots(ImmutableSet allRoots, ImmutableSet roots .collect(toImmutableSet()); ProcessorErrors.checkState( - processedAppRootElements.isEmpty(), + processedAppRootElements.isEmpty() || appRootElementsToProcess.isEmpty(), "Cannot process app roots in this compilation unit since there are app roots in a " + "previous compilation unit:" + "\n\tApp roots in previous compilation unit: %s" + "\n\tApp roots in this compilation unit: %s", processedAppRootElements, appRootElementsToProcess); - - ProcessorErrors.checkState( - appRootElementsToProcess.size() == 1, - "Cannot process multiple app roots in the same compilation unit: %s", - appRootElementsToProcess); } } diff --git a/javatests/dagger/hilt/processor/internal/root/BUILD b/javatests/dagger/hilt/processor/internal/root/BUILD index 084ad23ba5c..0dba875c760 100644 --- a/javatests/dagger/hilt/processor/internal/root/BUILD +++ b/javatests/dagger/hilt/processor/internal/root/BUILD @@ -40,6 +40,7 @@ compiler_test( "@maven//:androidx_test_core", ], deps = [ + "//java/dagger/internal/guava:collect", "//javatests/dagger/hilt/android/processor:android_compilers", "@google_bazel_common//third_party/java/compile_testing", "@google_bazel_common//third_party/java/junit", @@ -70,6 +71,7 @@ compiler_test( "@maven//:androidx_test_core", ], deps = [ + "//java/dagger/internal/guava:collect", "//javatests/dagger/hilt/android/processor:android_compilers", "@google_bazel_common//third_party/java/compile_testing", "@google_bazel_common//third_party/java/junit", @@ -90,6 +92,7 @@ compiler_test( "@maven//:androidx_test_core", ], deps = [ + "//java/dagger/internal/guava:collect", "//javatests/dagger/hilt/android/processor:android_compilers", "@google_bazel_common//third_party/java/compile_testing", "@google_bazel_common//third_party/java/junit", diff --git a/javatests/dagger/hilt/processor/internal/root/MyAppPreviousCompilationTest.java b/javatests/dagger/hilt/processor/internal/root/MyAppPreviousCompilationTest.java index 72b32f10835..adf6d9b2de1 100644 --- a/javatests/dagger/hilt/processor/internal/root/MyAppPreviousCompilationTest.java +++ b/javatests/dagger/hilt/processor/internal/root/MyAppPreviousCompilationTest.java @@ -17,17 +17,41 @@ package dagger.hilt.processor.internal.root; import static com.google.testing.compile.CompilationSubject.assertThat; -import static dagger.hilt.android.processor.AndroidCompilers.compiler; +import com.google.common.collect.ImmutableCollection; +import com.google.common.collect.ImmutableList; import com.google.testing.compile.Compilation; +import com.google.testing.compile.Compiler; import com.google.testing.compile.JavaFileObjects; +import dagger.hilt.android.processor.AndroidCompilers; import javax.tools.JavaFileObject; import org.junit.Test; import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; -@RunWith(JUnit4.class) +@RunWith(Parameterized.class) public final class MyAppPreviousCompilationTest { + + @Parameters(name = "{0}") + public static ImmutableCollection parameters() { + return ImmutableList.copyOf(new Object[][] {{true}, {false}}); + } + + private final boolean disableCrossCompilationRootValidation; + + public MyAppPreviousCompilationTest(boolean disableCrossCompilationRootValidation) { + this.disableCrossCompilationRootValidation = disableCrossCompilationRootValidation; + } + + private Compiler compiler() { + return AndroidCompilers.compiler() + .withOptions( + String.format( + "-Adagger.hilt.disableCrossCompilationRootValidation=%s", + disableCrossCompilationRootValidation)); + } + @Test public void testRootTest() { JavaFileObject testRoot = @@ -40,6 +64,7 @@ public void testRootTest() { "@HiltAndroidTest", "public class TestRoot {}"); + // This test case should succeed independent of disableCrossCompilationRootValidation. Compilation compilation = compiler().compile(testRoot); assertThat(compilation).succeeded(); } @@ -58,14 +83,18 @@ public void appRootTest() { "public class AppRoot extends Hilt_AppRoot {}"); Compilation compilation = compiler().compile(appRoot); - assertThat(compilation).failed(); - assertThat(compilation).hadErrorCount(1); - assertThat(compilation) - .hadErrorContaining( - "Cannot process app roots in this compilation unit since there are app roots in a " - + "previous compilation unit:" - + "\n \tApp roots in previous compilation unit: [" - + "dagger.hilt.processor.internal.root.MyAppPreviousCompilation.MyApp]" - + "\n \tApp roots in this compilation unit: [test.AppRoot]"); + if (disableCrossCompilationRootValidation) { + assertThat(compilation).succeeded(); + } else { + assertThat(compilation).failed(); + assertThat(compilation).hadErrorCount(1); + assertThat(compilation) + .hadErrorContaining( + "Cannot process app roots in this compilation unit since there are app roots in a " + + "previous compilation unit:" + + "\n \tApp roots in previous compilation unit: [" + + "dagger.hilt.processor.internal.root.MyAppPreviousCompilation.MyApp]" + + "\n \tApp roots in this compilation unit: [test.AppRoot]"); + } } } diff --git a/javatests/dagger/hilt/processor/internal/root/MyTestPreviousCompilationTest.java b/javatests/dagger/hilt/processor/internal/root/MyTestPreviousCompilationTest.java index e1415d6bf23..9e9fae57ef6 100644 --- a/javatests/dagger/hilt/processor/internal/root/MyTestPreviousCompilationTest.java +++ b/javatests/dagger/hilt/processor/internal/root/MyTestPreviousCompilationTest.java @@ -17,17 +17,41 @@ package dagger.hilt.processor.internal.root; import static com.google.testing.compile.CompilationSubject.assertThat; -import static dagger.hilt.android.processor.AndroidCompilers.compiler; +import com.google.common.collect.ImmutableCollection; +import com.google.common.collect.ImmutableList; import com.google.testing.compile.Compilation; +import com.google.testing.compile.Compiler; import com.google.testing.compile.JavaFileObjects; +import dagger.hilt.android.processor.AndroidCompilers; import javax.tools.JavaFileObject; import org.junit.Test; import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; -@RunWith(JUnit4.class) +@RunWith(Parameterized.class) public final class MyTestPreviousCompilationTest { + + @Parameters(name = "{0}") + public static ImmutableCollection parameters() { + return ImmutableList.copyOf(new Object[][] {{true}, {false}}); + } + + private final boolean disableCrossCompilationRootValidation; + + public MyTestPreviousCompilationTest(boolean disableCrossCompilationRootValidation) { + this.disableCrossCompilationRootValidation = disableCrossCompilationRootValidation; + } + + private Compiler compiler() { + return AndroidCompilers.compiler() + .withOptions( + String.format( + "-Adagger.hilt.disableCrossCompilationRootValidation=%s", + disableCrossCompilationRootValidation)); + } + @Test public void testRootTest() { JavaFileObject testRoot = @@ -41,13 +65,18 @@ public void testRootTest() { "public class TestRoot {}"); Compilation compilation = compiler().compile(testRoot); - assertThat(compilation).failed(); - assertThat(compilation) - .hadErrorContaining( - "Cannot process new roots when there are test roots from a previous compilation unit:" - + "\n \tTest roots from previous compilation unit: " - + "[dagger.hilt.processor.internal.root.MyTestPreviousCompilation.MyTest]" - + "\n \tAll roots from this compilation unit: [test.TestRoot]"); + if (disableCrossCompilationRootValidation) { + assertThat(compilation).succeeded(); + } else { + assertThat(compilation).failed(); + assertThat(compilation).hadErrorCount(1); + assertThat(compilation) + .hadErrorContaining( + "Cannot process new roots when there are test roots from a previous compilation unit:" + + "\n \tTest roots from previous compilation unit: " + + "[dagger.hilt.processor.internal.root.MyTestPreviousCompilation.MyTest]" + + "\n \tAll roots from this compilation unit: [test.TestRoot]"); + } } @Test @@ -64,13 +93,17 @@ public void appRootTest() { "public class AppRoot extends Hilt_AppRoot {}"); Compilation compilation = compiler().compile(appRoot); - assertThat(compilation).failed(); - assertThat(compilation).hadErrorCount(1); - assertThat(compilation) - .hadErrorContaining( - "Cannot process new roots when there are test roots from a previous compilation unit:" - + "\n \tTest roots from previous compilation unit: " - + "[dagger.hilt.processor.internal.root.MyTestPreviousCompilation.MyTest]" - + "\n \tAll roots from this compilation unit: [test.AppRoot]"); + if (disableCrossCompilationRootValidation) { + assertThat(compilation).succeeded(); + } else { + assertThat(compilation).failed(); + assertThat(compilation).hadErrorCount(1); + assertThat(compilation) + .hadErrorContaining( + "Cannot process new roots when there are test roots from a previous compilation unit:" + + "\n \tTest roots from previous compilation unit: " + + "[dagger.hilt.processor.internal.root.MyTestPreviousCompilation.MyTest]" + + "\n \tAll roots from this compilation unit: [test.AppRoot]"); + } } } diff --git a/javatests/dagger/hilt/processor/internal/root/RootProcessorErrorsTest.java b/javatests/dagger/hilt/processor/internal/root/RootProcessorErrorsTest.java index 01c8fc09f6a..e9ed8c418b3 100644 --- a/javatests/dagger/hilt/processor/internal/root/RootProcessorErrorsTest.java +++ b/javatests/dagger/hilt/processor/internal/root/RootProcessorErrorsTest.java @@ -17,17 +17,41 @@ package dagger.hilt.processor.internal.root; import static com.google.testing.compile.CompilationSubject.assertThat; -import static dagger.hilt.android.processor.AndroidCompilers.compiler; +import com.google.common.collect.ImmutableCollection; +import com.google.common.collect.ImmutableList; import com.google.testing.compile.Compilation; +import com.google.testing.compile.Compiler; import com.google.testing.compile.JavaFileObjects; +import dagger.hilt.android.processor.AndroidCompilers; import javax.tools.JavaFileObject; import org.junit.Test; import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; -@RunWith(JUnit4.class) +@RunWith(Parameterized.class) public final class RootProcessorErrorsTest { + + @Parameters(name = "{0}") + public static ImmutableCollection parameters() { + return ImmutableList.copyOf(new Object[][] {{true}, {false}}); + } + + private final boolean disableCrossCompilationRootValidation; + + public RootProcessorErrorsTest(boolean disableCrossCompilationRootValidation) { + this.disableCrossCompilationRootValidation = disableCrossCompilationRootValidation; + } + + private Compiler compiler() { + return AndroidCompilers.compiler() + .withOptions( + String.format( + "-Adagger.hilt.disableCrossCompilationRootValidation=%s", + disableCrossCompilationRootValidation)); + } + @Test public void multipleAppRootsTest() { JavaFileObject appRoot1 = @@ -52,6 +76,7 @@ public void multipleAppRootsTest() { "@HiltAndroidApp(Application.class)", "public class AppRoot2 extends Hilt_AppRoot2 {}"); + // This test case should fail independent of disableCrossCompilationRootValidation. Compilation compilation = compiler().compile(appRoot1, appRoot2); assertThat(compilation).failed(); assertThat(compilation).hadErrorCount(1); @@ -84,6 +109,7 @@ public void appRootWithTestRootTest() { "@HiltAndroidTest", "public class TestRoot {}"); + // This test case should fail independent of disableCrossCompilationRootValidation. Compilation compilation = compiler().compile(appRoot, testRoot); assertThat(compilation).failed(); assertThat(compilation).hadErrorCount(1);