Skip to content

Commit

Permalink
Migrate Hilt compiler tests from KSP1 to KSP2.
Browse files Browse the repository at this point in the history
Note: This was previously blocked by b/390685181 (google/ksp#2309), but that's fixed now
RELNOTES=N/A
PiperOrigin-RevId: 733876340
  • Loading branch information
bcorso authored and Dagger Team committed Mar 7, 2025
1 parent 6f64d4b commit 164344a
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 100 deletions.
27 changes: 24 additions & 3 deletions java/dagger/hilt/android/testing/compile/HiltCompilerTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,18 @@ public final class HiltCompilerTests {

private static final ImmutableList<String> DEFAULT_KOTLINC_OPTIONS =
ImmutableList.of(
"-api-version=1.9",
"-language-version=1.9",
"-jvm-target=11",
"-Xjvm-default=all",
"-P",
"plugin:org.jetbrains.kotlin.kapt3:correctErrorTypes=true");

private static final ImmutableList<String> KSP1_DEFAULT_KOTLINC_OPTIONS =
ImmutableList.<String>builder()
.addAll(DEFAULT_KOTLINC_OPTIONS)
.add("-api-version=1.9")
.add("-language-version=1.9")
.build();

/** Returns the {@link XProcessingEnv.Backend} for the given {@link CompilationResultSubject}. */
public static XProcessingEnv.Backend backend(CompilationResultSubject subject) {
return CompilerTests.backend(subject);
Expand Down Expand Up @@ -281,6 +286,22 @@ public HiltCompiler withJavacArguments(ImmutableCollection<String> arguments) {
abstract Builder toBuilder();

public void compile(Consumer<CompilationResultSubject> onCompilationResult) {
compileInternal(onCompilationResult, DEFAULT_KOTLINC_OPTIONS);
}

/**
* Returns a compiler with the KSP1 options.
*
* @deprecated This is only intended to be used for tests that are not yet compatible with KSP2.
*/
@Deprecated // TODO(b/378271452): Remove once we've fixed issues with KSP2
public void legacyCompile(Consumer<CompilationResultSubject> onCompilationResult) {
compileInternal(onCompilationResult, KSP1_DEFAULT_KOTLINC_OPTIONS);
}

private void compileInternal(
Consumer<CompilationResultSubject> onCompilationResult,
ImmutableList<String> kotlincArguments) {
ProcessorTestExtKt.runProcessorTest(
sources().asList(),
/* classpath= */ ImmutableList.of(CompilerTests.compilerDepsJar()),
Expand All @@ -290,7 +311,7 @@ public void compile(Consumer<CompilationResultSubject> onCompilationResult) {
.addAll(DEFAULT_JAVAC_OPTIONS)
.addAll(javacArguments())
.build(),
/* kotlincArguments= */ DEFAULT_KOTLINC_OPTIONS,
/* kotlincArguments= */ kotlincArguments,
/* config= */ HiltProcessingEnvConfigs.CONFIGS,
/* javacProcessors= */ ImmutableList.<Processor>builder()
.addAll(mergeProcessors(defaultProcessors(), additionalJavacProcessors()))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,18 @@

package dagger.hilt.processor.internal.aggregateddeps;

import static com.google.common.truth.Truth.assertThat;

import androidx.room.compiler.processing.util.CompilationResultSubject;
import androidx.room.compiler.processing.util.Source;
import com.google.common.collect.ImmutableList;
import dagger.hilt.android.testing.compile.HiltCompilerTests;
import dagger.hilt.processor.internal.GeneratedImport;
import org.junit.Rule;
import java.util.function.Consumer;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Tests for errors generated by {@link AggregatedDepsProcessor} */
@RunWith(JUnit4.class)
public class AggregatedDepsProcessorErrorsTest {

@Rule public TemporaryFolder tempFolderRule = new TemporaryFolder();

@Test
public void reportMultipleAnnotationTypeKindErrors() {
Source source =
Expand Down Expand Up @@ -68,33 +62,33 @@ public void reportMultipleAnnotationTypeKindErrors() {
"interface DontMix{}",
"");

HiltCompilerTests.hiltCompiler(source)
.compile(
subject -> {
subject.compilationDidFail();
subject
.hasErrorContaining("Only classes and interfaces can be annotated with @Module")
.onSource(source)
.onLine(12);
subject
.hasErrorContaining("Only interfaces can be annotated with @EntryPoint")
.onSource(source)
.onLine(16);
subject
.hasErrorContaining("Only interfaces can be annotated with @ComponentEntryPoint")
.onSource(source)
.onLine(20);
subject
.hasErrorContaining(
"@EntryPoint foo.bar.QuxEntryPoint must also be annotated with @InstallIn")
.onSource(source)
.onLine(23);
subject
.hasErrorContaining(
"@Module and @EntryPoint cannot be used on the same interface")
.onSource(source)
.onLine(27);
});
compile(
source,
subject -> {
subject.compilationDidFail();
subject
.hasErrorContaining("Only classes and interfaces can be annotated with @Module")
.onSource(source)
.onLine(12);
subject
.hasErrorContaining("Only interfaces can be annotated with @EntryPoint")
.onSource(source)
.onLine(16);
subject
.hasErrorContaining("Only interfaces can be annotated with @ComponentEntryPoint")
.onSource(source)
.onLine(20);
subject
.hasErrorContaining(
"@EntryPoint foo.bar.QuxEntryPoint must also be annotated with @InstallIn")
.onSource(source)
.onLine(23);
subject
.hasErrorContaining(
"@Module and @EntryPoint cannot be used on the same interface")
.onSource(source)
.onLine(27);
});
}

@Test
Expand All @@ -112,17 +106,17 @@ public void testInvalidComponentInInstallInAnnotation() {
"@Module",
"final class FooModule {}");

HiltCompilerTests.hiltCompiler(module)
.compile(
subject -> {
subject.compilationDidFail();
subject
.hasErrorContaining(
"@InstallIn, can only be used with @DefineComponent-annotated classes, but"
+ " found: [dagger.hilt.android.qualifiers.ApplicationContext]")
.onSource(module)
.onLine(9);
});
compile(
module,
subject -> {
subject.compilationDidFail();
subject
.hasErrorContaining(
"@InstallIn, can only be used with @DefineComponent-annotated classes, but"
+ " found: [dagger.hilt.android.qualifiers.ApplicationContext]")
.onSource(module)
.onLine(9);
});
}

@Test
Expand All @@ -137,15 +131,15 @@ public void testMissingInstallInAnnotation() {
"@Module", // Error: Doesn't have InstallIn annotation
"final class FooModule {}");

HiltCompilerTests.hiltCompiler(source)
.compile(
subject -> {
subject.compilationDidFail();
subject
.hasErrorContaining("foo.bar.FooModule is missing an @InstallIn annotation")
.onSource(source)
.onLine(6);
});
compile(
source,
subject -> {
subject.compilationDidFail();
subject
.hasErrorContaining("foo.bar.FooModule is missing an @InstallIn annotation")
.onSource(source)
.onLine(6);
});
}

@Test
Expand All @@ -167,16 +161,16 @@ public void testNoErrorOnDaggerGeneratedModules() {
"@Generated(value = \"dagger\")", // No error because the module is dagger generated
"final class BarModule {}");

HiltCompilerTests.hiltCompiler(source)
.compile(
subject -> {
subject.compilationDidFail();
subject.hasErrorCount(1);
subject
.hasErrorContaining("foo.bar.FooModule is missing an @InstallIn annotation")
.onSource(source)
.onLine(8);
});
compile(
source,
subject -> {
subject.compilationDidFail();
subject.hasErrorCount(1);
subject
.hasErrorContaining("foo.bar.FooModule is missing an @InstallIn annotation")
.onSource(source)
.onLine(8);
});
}

@Test
Expand All @@ -202,15 +196,15 @@ public void testModuleWithOnlyParamConstructor_fails() {
" }",
"}");

HiltCompilerTests.hiltCompiler(source)
.compile(
subject -> {
subject.compilationDidFail();
subject.hasErrorCount(1);
subject.hasErrorContaining(
"Modules that need to be instantiated by Hilt must have a visible, empty"
+ " constructor.");
});
compile(
source,
subject -> {
subject.compilationDidFail();
subject.hasErrorCount(1);
subject.hasErrorContaining(
"Modules that need to be instantiated by Hilt must have a visible, empty"
+ " constructor.");
});
}

@Test
Expand All @@ -230,15 +224,15 @@ public void testInnerModule() {
" final class InnerModule {}",
"}");

HiltCompilerTests.hiltCompiler(source)
.compile(
subject -> {
subject.compilationDidFail();
subject.hasErrorCount(1);
subject.hasErrorContaining(
"Nested @InstallIn modules must be static unless they are directly nested within"
+ " a test. Found: foo.bar.Outer.InnerModule");
});
compile(
source,
subject -> {
subject.compilationDidFail();
subject.hasErrorCount(1);
subject.hasErrorContaining(
"Nested @InstallIn modules must be static unless they are directly nested within"
+ " a test. Found: foo.bar.Outer.InnerModule");
});
}

@Test
Expand All @@ -262,15 +256,15 @@ public void testInnerModuleInTest() {
" }",
"}");

HiltCompilerTests.hiltCompiler(source)
.compile(
subject -> {
subject.compilationDidFail();
subject.hasErrorCount(1);
subject.hasErrorContaining(
"Nested @InstallIn modules must be static unless they are directly nested within"
+ " a test. Found: foo.bar.Outer.Nested.InnerModule");
});
compile(
source,
subject -> {
subject.compilationDidFail();
subject.hasErrorCount(1);
subject.hasErrorContaining(
"Nested @InstallIn modules must be static unless they are directly nested within"
+ " a test. Found: foo.bar.Outer.Nested.InnerModule");
});
}

@Test
Expand All @@ -292,10 +286,12 @@ public void testInnerModuleInTest_succeeds() {
" static final class InnerModule {}",
"}");

// TODO(danysantiago): Add KSP test once b/288966076 is resolved.
HiltCompilerTests.compileWithKapt(
ImmutableList.of(source),
tempFolderRule,
result -> assertThat(result.getSuccess()).isTrue());
compile(source, subject -> subject.hasErrorCount(0));
}

private static void compile(
Source source, Consumer<CompilationResultSubject> onCompilationResult) {
HiltCompilerTests.hiltCompiler(source)
.compileLegacy(onCompilationResult);
}
}

0 comments on commit 164344a

Please sign in to comment.