blob: 3af5be6fd0f7eb1acfea27eeeaf5c0d314aee9b0 [file] [log] [blame]
/*
* Copyright (C) 2020 The Dagger Authors.
*
* 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 dagger.hilt.android.processor.internal.aggregateddeps;
import static com.google.testing.compile.CompilationSubject.assertThat;
import static dagger.hilt.android.processor.AndroidCompilers.compiler;
import com.google.testing.compile.Compilation;
import com.google.testing.compile.JavaFileObjects;
import javax.tools.JavaFileObject;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@RunWith(JUnit4.class)
public class TestInstallInTest {
@Test
public void testMissingValues() {
JavaFileObject testInstallInModule =
JavaFileObjects.forSourceLines(
"test.TestInstallInModule",
"package test;",
"",
"import dagger.Module;",
"import dagger.hilt.testing.TestInstallIn;",
"",
"@Module",
"@TestInstallIn",
"interface TestInstallInModule {}");
Compilation compilation = compiler().compile(testInstallInModule);
assertThat(compilation).failed();
assertThat(compilation).hadErrorCount(1);
assertThat(compilation)
.hadErrorContaining(
"@dagger.hilt.testing.TestInstallIn is missing default values for elements "
+ "components,replaces")
.inFile(testInstallInModule)
.onLine(7);
}
@Test
public void testEmptyComponentValues() {
JavaFileObject installInModule =
JavaFileObjects.forSourceLines(
"test.InstallInModule",
"package test;",
"",
"import dagger.Module;",
"import dagger.hilt.InstallIn;",
"import dagger.hilt.components.SingletonComponent;",
"",
"@Module",
"@InstallIn(SingletonComponent.class)",
"interface InstallInModule {}");
JavaFileObject testInstallInModule =
JavaFileObjects.forSourceLines(
"test.TestInstallInModule",
"package test;",
"",
"import dagger.Module;",
"import dagger.hilt.testing.TestInstallIn;",
"",
"@Module",
"@TestInstallIn(components = {}, replaces = InstallInModule.class)",
"interface TestInstallInModule {}");
Compilation compilation = compiler().compile(installInModule, testInstallInModule);
assertThat(compilation).failed();
assertThat(compilation).hadErrorCount(1);
// TODO(bcorso): Add inFile().onLine() whenever we've fixed Processors.getAnnotationClassValues
assertThat(compilation)
.hadErrorContaining(
"@TestInstallIn, 'components' class is invalid or missing: "
+ "@dagger.hilt.testing.TestInstallIn("
+ "components={}, replaces={test.InstallInModule.class})");
}
@Test
public void testEmptyReplacesValues() {
JavaFileObject testInstallInModule =
JavaFileObjects.forSourceLines(
"test.TestInstallInModule",
"package test;",
"",
"import dagger.Module;",
"import dagger.hilt.testing.TestInstallIn;",
"import dagger.hilt.components.SingletonComponent;",
"",
"@Module",
"@TestInstallIn(components = SingletonComponent.class, replaces = {})",
"interface TestInstallInModule {}");
Compilation compilation = compiler().compile(testInstallInModule);
assertThat(compilation).failed();
assertThat(compilation).hadErrorCount(1);
// TODO(bcorso): Add inFile().onLine() whenever we've fixed Processors.getAnnotationClassValues
assertThat(compilation)
.hadErrorContaining(
"@TestInstallIn, 'replaces' class is invalid or missing: "
+ "@dagger.hilt.testing.TestInstallIn("
+ "components={dagger.hilt.components.SingletonComponent.class}, replaces={})");
}
@Test
public void testMissingModuleAnnotation() {
JavaFileObject installInModule =
JavaFileObjects.forSourceLines(
"test.InstallInModule",
"package test;",
"",
"import dagger.Module;",
"import dagger.hilt.InstallIn;",
"import dagger.hilt.components.SingletonComponent;",
"",
"@Module",
"@InstallIn(SingletonComponent.class)",
"interface InstallInModule {}");
JavaFileObject testInstallInModule =
JavaFileObjects.forSourceLines(
"test.TestInstallInModule",
"package test;",
"",
"import dagger.Module;",
"import dagger.hilt.components.SingletonComponent;",
"import dagger.hilt.testing.TestInstallIn;",
"",
"@TestInstallIn(",
" components = SingletonComponent.class,",
" replaces = InstallInModule.class)",
"interface TestInstallInModule {}");
Compilation compilation = compiler().compile(installInModule, testInstallInModule);
assertThat(compilation).failed();
assertThat(compilation).hadErrorCount(1);
assertThat(compilation)
.hadErrorContaining(
"@TestInstallIn-annotated classes must also be annotated with @Module or @EntryPoint: "
+ "test.TestInstallInModule")
.inFile(testInstallInModule)
.onLine(10);
}
@Test
public void testInvalidUsageOnEntryPoint() {
JavaFileObject installInModule =
JavaFileObjects.forSourceLines(
"test.InstallInModule",
"package test;",
"",
"import dagger.Module;",
"import dagger.hilt.InstallIn;",
"import dagger.hilt.components.SingletonComponent;",
"",
"@Module",
"@InstallIn(SingletonComponent.class)",
"interface InstallInModule {}");
JavaFileObject testInstallInEntryPoint =
JavaFileObjects.forSourceLines(
"test.TestInstallInEntryPoint",
"package test;",
"",
"import dagger.hilt.EntryPoint;",
"import dagger.hilt.components.SingletonComponent;",
"import dagger.hilt.testing.TestInstallIn;",
"",
"@EntryPoint",
"@TestInstallIn(",
" components = SingletonComponent.class,",
" replaces = InstallInModule.class)",
"interface TestInstallInEntryPoint {}");
Compilation compilation = compiler().compile(installInModule, testInstallInEntryPoint);
assertThat(compilation).failed();
assertThat(compilation).hadErrorCount(1);
assertThat(compilation)
.hadErrorContaining("@TestInstallIn can only be used with modules")
.inFile(testInstallInEntryPoint)
.onLine(11);
}
@Test
public void testInvalidReplaceModules() {
JavaFileObject foo =
JavaFileObjects.forSourceLines("test.Foo", "package test;", "", "class Foo {}");
JavaFileObject testInstallInModule =
JavaFileObjects.forSourceLines(
"test.TestInstallInModule",
"package test;",
"",
"import dagger.Module;",
"import dagger.hilt.components.SingletonComponent;",
"import dagger.hilt.testing.TestInstallIn;",
"",
"@Module",
"@TestInstallIn(",
" components = SingletonComponent.class,",
" replaces = Foo.class)",
"interface TestInstallInModule {}");
Compilation compilation = compiler().compile(foo, testInstallInModule);
assertThat(compilation).failed();
assertThat(compilation).hadErrorCount(1);
assertThat(compilation)
.hadErrorContaining(
"@TestInstallIn#replaces() can only contain @InstallIn modules, but found: [test.Foo]")
.inFile(testInstallInModule)
.onLine(11);
}
@Test
public void testInternalDaggerReplaceModules() {
JavaFileObject testInstallInModule =
JavaFileObjects.forSourceLines(
"test.TestInstallInModule",
"package test;",
"",
"import dagger.Module;",
"import dagger.hilt.components.SingletonComponent;",
"import dagger.hilt.testing.TestInstallIn;",
"",
"@Module",
"@TestInstallIn(",
" components = SingletonComponent.class,",
" replaces = dagger.hilt.android.internal.modules.ApplicationContextModule.class)",
"interface TestInstallInModule {}");
Compilation compilation = compiler().compile(testInstallInModule);
assertThat(compilation).failed();
assertThat(compilation).hadErrorCount(1);
assertThat(compilation)
.hadErrorContaining(
"@TestInstallIn#replaces() cannot contain internal Hilt modules, but found: "
+ "[dagger.hilt.android.internal.modules.ApplicationContextModule]")
.inFile(testInstallInModule)
.onLine(11);
}
@Test
public void testHiltWrapperDaggerReplaceModules() {
JavaFileObject testInstallInModule =
JavaFileObjects.forSourceLines(
"test.TestInstallInModule",
"package test;",
"",
"import dagger.Module;",
"import dagger.hilt.components.SingletonComponent;",
"import dagger.hilt.testing.TestInstallIn;",
"import"
+ " dagger.hilt.android.processor.internal.aggregateddeps.HiltWrapper_InstallInModule;",
"",
"@Module",
"@TestInstallIn(",
" components = SingletonComponent.class,",
// Note: this module is built in a separate library since AggregatedDepsProcessor can't
// handle modules generated in the same round.
" replaces = HiltWrapper_InstallInModule.class)",
"interface TestInstallInModule {}");
Compilation compilation = compiler().compile(testInstallInModule);
assertThat(compilation).failed();
assertThat(compilation).hadErrorCount(1);
assertThat(compilation)
.hadErrorContaining(
"@TestInstallIn#replaces() cannot contain Hilt generated public wrapper modules, "
+ "but found: [dagger.hilt.android.processor.internal.aggregateddeps."
+ "HiltWrapper_InstallInModule]")
.inFile(testInstallInModule)
.onLine(12);
}
@Test
public void testCannotReplaceLocalInstallInModule() {
JavaFileObject test =
JavaFileObjects.forSourceLines(
"test.MyTest",
"package test;",
"",
"import dagger.Module;",
"import dagger.hilt.InstallIn;",
"import dagger.hilt.components.SingletonComponent;",
"import dagger.hilt.testing.TestInstallIn;",
"import dagger.hilt.android.testing.HiltAndroidTest;",
"",
"@HiltAndroidTest",
"public class MyTest {",
" @Module",
" @InstallIn(SingletonComponent.class)",
" interface LocalInstallInModule {}",
"}");
JavaFileObject testInstallIn =
JavaFileObjects.forSourceLines(
"test.TestInstallInModule",
"package test;",
"",
"import dagger.Module;",
"import dagger.hilt.components.SingletonComponent;",
"import dagger.hilt.testing.TestInstallIn;",
"",
"@Module",
"@TestInstallIn(",
" components = SingletonComponent.class,",
" replaces = MyTest.LocalInstallInModule.class)",
"interface TestInstallInModule {}");
Compilation compilation = compiler().compile(test, testInstallIn);
assertThat(compilation).failed();
assertThat(compilation).hadErrorCount(1);
assertThat(compilation)
.hadErrorContaining(
"TestInstallIn#replaces() cannot replace test specific @InstallIn modules, but found: "
+ "[test.MyTest.LocalInstallInModule].")
.inFile(testInstallIn)
.onLine(11);
}
@Test
public void testThatTestInstallInCannotOriginateFromTest() {
JavaFileObject installInModule =
JavaFileObjects.forSourceLines(
"test.InstallInModule",
"package test;",
"",
"import dagger.Module;",
"import dagger.hilt.InstallIn;",
"import dagger.hilt.components.SingletonComponent;",
"",
"@Module",
"@InstallIn(SingletonComponent.class)",
"interface InstallInModule {}");
JavaFileObject test =
JavaFileObjects.forSourceLines(
"test.MyTest",
"package test;",
"",
"import dagger.Module;",
"import dagger.hilt.components.SingletonComponent;",
"import dagger.hilt.testing.TestInstallIn;",
"import dagger.hilt.android.testing.HiltAndroidTest;",
"",
"@HiltAndroidTest",
"public class MyTest {",
" @Module",
" @TestInstallIn(",
" components = SingletonComponent.class,",
" replaces = InstallInModule.class)",
" interface TestInstallInModule {}",
"}");
Compilation compilation = compiler().compile(test, installInModule);
assertThat(compilation).failed();
assertThat(compilation).hadErrorCount(1);
assertThat(compilation)
.hadErrorContaining(
"@TestInstallIn modules cannot be nested in (or originate from) a "
+ "@HiltAndroidTest-annotated class: test.MyTest")
.inFile(test)
.onLine(14);
}
}