/*
* Copyright (C) 2015 Google, Inc.
*
* 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.internal.codegen;
import com.google.common.collect.ImmutableList;
import com.google.testing.compile.JavaFileObjects;
import javax.tools.JavaFileObject;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import static com.google.common.truth.Truth.assertAbout;
import static com.google.testing.compile.JavaSourceSubjectFactory.javaSource;
import static com.google.testing.compile.JavaSourcesSubjectFactory.javaSources;
/** Tests for {@link dagger.Component.Builder} */
@RunWith(JUnit4.class)
public class ComponentBuilderTest {
private static final ErrorMessages.ComponentBuilderMessages MSGS =
ErrorMessages.ComponentBuilderMessages.INSTANCE;
@Test
public void testEmptyBuilder() {
JavaFileObject injectableTypeFile = JavaFileObjects.forSourceLines("test.SomeInjectableType",
"package test;",
"",
"import javax.inject.Inject;",
"",
"final class SomeInjectableType {",
" @Inject SomeInjectableType() {}",
"}");
JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.SimpleComponent",
"package test;",
"",
"import dagger.Component;",
"",
"import javax.inject.Provider;",
"",
"@Component",
"interface SimpleComponent {",
" SomeInjectableType someInjectableType();",
"",
" @Component.Builder",
" static interface Builder {",
" SimpleComponent build();",
" }",
"}");
JavaFileObject generatedComponent = JavaFileObjects.forSourceLines(
"test.DaggerSimpleComponent",
"package test;",
"",
"import javax.annotation.Generated;",
"import test.SimpleComponent",
"",
"@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
"public final class DaggerSimpleComponent implements SimpleComponent {",
" private DaggerSimpleComponent(Builder builder) {",
" assert builder != null;",
" initialize(builder);",
" }",
"",
" public static SimpleComponent.Builder builder() {",
" return new Builder();",
" }",
"",
" public static SimpleComponent create() {",
" return builder().build();",
" }",
"",
" @SuppressWarnings(\"unchecked\")",
" private void initialize(final Builder builder) {",
" }",
"",
" @Override",
" public SomeInjectableType someInjectableType() {",
" return SomeInjectableType_Factory.create().get();",
" }",
"",
" private static final class Builder implements SimpleComponent.Builder {",
" @Override",
" public SimpleComponent build() {",
" return new DaggerSimpleComponent(this);",
" }",
" }",
"}");
assertAbout(javaSources()).that(ImmutableList.of(injectableTypeFile, componentFile))
.processedWith(new ComponentProcessor())
.compilesWithoutError()
.and().generatesSources(generatedComponent);
}
@Test
public void testUsesBuildAndSetterNames() {
JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule",
"package test;",
"",
"import dagger.Module;",
"import dagger.Provides;",
"",
"@Module",
"final class TestModule {",
" @Provides String string() { return null; }",
"}");
JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.TestComponent",
"package test;",
"",
"import dagger.Component;",
"",
"@Component(modules = TestModule.class)",
"interface TestComponent {",
" String string();",
"",
" @Component.Builder",
" interface Builder {",
" Builder setTestModule(TestModule testModule);",
" TestComponent create();",
" }",
"}");
JavaFileObject generatedComponent = JavaFileObjects.forSourceLines(
"test.DaggerTestComponent",
"package test;",
"",
"import javax.annotation.Generated;",
"import javax.inject.Provider;",
"import test.TestComponent;",
"",
"@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
"public final class DaggerTestComponent implements TestComponent {",
" private Provider<String> stringProvider;",
"",
" private DaggerTestComponent(Builder builder) {",
" assert builder != null;",
" initialize(builder);",
" }",
"",
" public static TestComponent.Builder builder() {",
" return new Builder();",
" }",
"",
" public static TestComponent create() {",
" return builder().create();",
" }",
"",
" @SuppressWarnings(\"unchecked\")",
" private void initialize(final Builder builder) {",
" this.stringProvider = TestModule_StringFactory.create(builder.testModule);",
" }",
"",
" @Override",
" public String string() {",
" return stringProvider.get();",
" }",
"",
" private static final class Builder implements TestComponent.Builder {",
" private TestModule testModule;",
"",
" @Override",
" public TestComponent create() {",
" if (testModule == null) {",
" this.testModule = new TestModule();",
" }",
" return new DaggerTestComponent(this);",
" }",
"",
" @Override",
" public Builder setTestModule(TestModule testModule) {",
" if (testModule == null) {",
" throw new NullPointerException();",
" }",
" this.testModule = testModule;",
" return this;",
" }",
" }",
"}");
assertAbout(javaSources())
.that(ImmutableList.of(moduleFile, componentFile))
.processedWith(new ComponentProcessor())
.compilesWithoutError()
.and().generatesSources(generatedComponent);
}
@Test
public void testIgnoresModulesNotInApi() {
JavaFileObject module1 = JavaFileObjects.forSourceLines("test.TestModule1",
"package test;",
"",
"import dagger.Module;",
"import dagger.Provides;",
"",
"@Module",
"final class TestModule1 {",
" @Provides String string() { return null; }",
"}");
JavaFileObject module2 = JavaFileObjects.forSourceLines("test.TestModule2",
"package test;",
"",
"import dagger.Module;",
"import dagger.Provides;",
"",
"@Module",
"final class TestModule2 {",
" @Provides Integer integer() { return null; }",
"}");
JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.TestComponent",
"package test;",
"",
"import dagger.Component;",
"",
"@Component(modules = {TestModule1.class, TestModule2.class})",
"interface TestComponent {",
" String string();",
" Integer integer();",
"",
" @Component.Builder",
" interface Builder {",
" Builder testModule1(TestModule1 testModule1);",
" TestComponent build();",
" }",
"}");
JavaFileObject generatedComponent = JavaFileObjects.forSourceLines(
"test.DaggerTestComponent",
"package test;",
"",
"import javax.annotation.Generated;",
"import javax.inject.Provider;",
"import test.TestComponent;",
"",
"@Generated(\"dagger.internal.codegen.ComponentProcessor\")",
"public final class DaggerTestComponent implements TestComponent {",
" private Provider<String> stringProvider;",
" private Provider<Integer> integerProvider;",
"",
" private DaggerTestComponent(Builder builder) {",
" assert builder != null;",
" initialize(builder);",
" }",
"",
" public static TestComponent.Builder builder() {",
" return new Builder();",
" }",
"",
" public static TestComponent create() {",
" return builder().build();",
" }",
"",
" @SuppressWarnings(\"unchecked\")",
" private void initialize(final Builder builder) {",
" this.stringProvider = TestModule1_StringFactory.create(builder.testModule1);",
" this.integerProvider = TestModule2_IntegerFactory.create(builder.testModule2);",
" }",
"",
" @Override",
" public String string() {",
" return stringProvider.get();",
" }",
"",
" @Override",
" public Integer integer() {",
" return integerProvider.get();",
" }",
"",
" private static final class Builder implements TestComponent.Builder {",
" private TestModule1 testModule1;",
" private TestModule2 testModule2;",
"",
" @Override",
" public TestComponent build() {",
" if (testModule1 == null) {",
" this.testModule1 = new TestModule1();",
" }",
" if (testModule2 == null) {",
" this.testModule2 = new TestModule2();",
" }",
" return new DaggerTestComponent(this);",
" }",
"",
" @Override",
" public Builder testModule1(TestModule1 testModule1) {",
" if (testModule1 == null) {",
" throw new NullPointerException();",
" }",
" this.testModule1 = testModule1;",
" return this;",
" }",
" }",
"}");
assertAbout(javaSources())
.that(ImmutableList.of(module1, module2, componentFile))
.processedWith(new ComponentProcessor())
.compilesWithoutError()
.and().generatesSources(generatedComponent);
}
@Test
public void testMoreThanOneBuilderFails() {
JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.SimpleComponent",
"package test;",
"",
"import dagger.Component;",
"",
"import javax.inject.Provider;",
"",
"@Component",
"interface SimpleComponent {",
" @Component.Builder",
" static interface Builder {",
" SimpleComponent build();",
" }",
"",
" @Component.Builder",
" interface Builder2 {",
" SimpleComponent build();",
" }",
"}");
assertAbout(javaSource()).that(componentFile)
.processedWith(new ComponentProcessor())
.failsToCompile()
.withErrorContaining(String.format(MSGS.moreThanOne(),
"[test.SimpleComponent.Builder, test.SimpleComponent.Builder2]"))
.in(componentFile);
}
@Test
public void testBuilderGenericsFails() {
JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.SimpleComponent",
"package test;",
"",
"import dagger.Component;",
"",
"import javax.inject.Provider;",
"",
"@Component",
"interface SimpleComponent {",
" @Component.Builder",
" interface Builder<T> {",
" SimpleComponent build();",
" }",
"}");
assertAbout(javaSource()).that(componentFile)
.processedWith(new ComponentProcessor())
.failsToCompile()
.withErrorContaining(MSGS.generics())
.in(componentFile);
}
@Test
public void testBuilderNotInComponentFails() {
JavaFileObject builder = JavaFileObjects.forSourceLines("test.Builder",
"package test;",
"",
"import dagger.Component;",
"",
"@Component.Builder",
"interface Builder {}");
assertAbout(javaSource()).that(builder)
.processedWith(new ComponentProcessor())
.failsToCompile()
.withErrorContaining(MSGS.mustBeInComponent())
.in(builder);
}
@Test
public void testBuilderMissingBuildMethodFails() {
JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.SimpleComponent",
"package test;",
"",
"import dagger.Component;",
"",
"import javax.inject.Provider;",
"",
"@Component",
"interface SimpleComponent {",
" @Component.Builder",
" interface Builder {}",
"}");
assertAbout(javaSource()).that(componentFile)
.processedWith(new ComponentProcessor())
.failsToCompile()
.withErrorContaining(MSGS.missingBuildMethod())
.in(componentFile);
}
@Test
public void testPrivateBuilderFails() {
JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.SimpleComponent",
"package test;",
"",
"import dagger.Component;",
"",
"import javax.inject.Provider;",
"",
"@Component",
"abstract class SimpleComponent {",
" @Component.Builder",
" private interface Builder {}",
"}");
assertAbout(javaSource()).that(componentFile)
.processedWith(new ComponentProcessor())
.failsToCompile()
.withErrorContaining(MSGS.isPrivate())
.in(componentFile);
}
@Test
public void testNonStaticBuilderFails() {
JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.SimpleComponent",
"package test;",
"",
"import dagger.Component;",
"",
"import javax.inject.Provider;",
"",
"@Component",
"abstract class SimpleComponent {",
" @Component.Builder",
" abstract class Builder {}",
"}");
assertAbout(javaSource()).that(componentFile)
.processedWith(new ComponentProcessor())
.failsToCompile()
.withErrorContaining(MSGS.mustBeStatic())
.in(componentFile);
}
@Test
public void testNonAbstractBuilderFails() {
JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.SimpleComponent",
"package test;",
"",
"import dagger.Component;",
"",
"import javax.inject.Provider;",
"",
"@Component",
"abstract class SimpleComponent {",
" @Component.Builder",
" static class Builder {}",
"}");
assertAbout(javaSource()).that(componentFile)
.processedWith(new ComponentProcessor())
.failsToCompile()
.withErrorContaining(MSGS.mustBeAbstract());
}
@Test
public void testBuilderOneCxtorWithArgsFails() {
JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.SimpleComponent",
"package test;",
"",
"import dagger.Component;",
"",
"import javax.inject.Provider;",
"",
"@Component",
"abstract class SimpleComponent {",
" @Component.Builder",
" static abstract class Builder {",
" Builder(String unused) {}",
" }",
"}");
assertAbout(javaSource()).that(componentFile)
.processedWith(new ComponentProcessor())
.failsToCompile()
.withErrorContaining(MSGS.cxtorOnlyOneAndNoArgs())
.in(componentFile);
}
@Test
public void testBuilderMoreThanOneCxtorFails() {
JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.SimpleComponent",
"package test;",
"",
"import dagger.Component;",
"",
"import javax.inject.Provider;",
"",
"@Component",
"abstract class SimpleComponent {",
" @Component.Builder",
" static abstract class Builder {",
" Builder() {}",
" Builder(String unused) {}",
" }",
"}");
assertAbout(javaSource()).that(componentFile)
.processedWith(new ComponentProcessor())
.failsToCompile()
.withErrorContaining(MSGS.cxtorOnlyOneAndNoArgs())
.in(componentFile);
}
@Test
public void testBuilderEnumFails() {
JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.SimpleComponent",
"package test;",
"",
"import dagger.Component;",
"",
"import javax.inject.Provider;",
"",
"@Component",
"abstract class SimpleComponent {",
" @Component.Builder",
" enum Builder {}",
"}");
assertAbout(javaSource()).that(componentFile)
.processedWith(new ComponentProcessor())
.failsToCompile()
.withErrorContaining(MSGS.mustBeClassOrInterface())
.in(componentFile);
}
@Test
public void testBuilderBuildReturnsWrongTypeFails() {
JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.SimpleComponent",
"package test;",
"",
"import dagger.Component;",
"",
"import javax.inject.Provider;",
"",
"@Component",
"abstract class SimpleComponent {",
" @Component.Builder",
" interface Builder {",
" String build();",
" }",
"}");
assertAbout(javaSource()).that(componentFile)
.processedWith(new ComponentProcessor())
.failsToCompile()
.withErrorContaining(MSGS.buildMustReturnComponentType())
.in(componentFile).onLine(11);
}
@Test
public void testInheritedBuilderBuildReturnsWrongTypeFails() {
JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.SimpleComponent",
"package test;",
"",
"import dagger.Component;",
"",
"import javax.inject.Provider;",
"",
"@Component",
"abstract class SimpleComponent {",
" interface Parent {",
" String build();",
" }",
"",
" @Component.Builder",
" interface Builder extends Parent {}",
"}");
assertAbout(javaSource()).that(componentFile)
.processedWith(new ComponentProcessor())
.failsToCompile()
.withErrorContaining(
String.format(MSGS.inheritedBuildMustReturnComponentType(), "build"))
.in(componentFile).onLine(14);
}
@Test
public void testTwoBuildMethodsFails() {
JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.SimpleComponent",
"package test;",
"",
"import dagger.Component;",
"",
"import javax.inject.Provider;",
"",
"@Component",
"abstract class SimpleComponent {",
" @Component.Builder",
" interface Builder {",
" SimpleComponent build();",
" SimpleComponent create();",
" }",
"}");
assertAbout(javaSource()).that(componentFile)
.processedWith(new ComponentProcessor())
.failsToCompile()
.withErrorContaining(String.format(MSGS.twoBuildMethods(), "build()"))
.in(componentFile).onLine(12);
}
@Test
public void testInheritedTwoBuildMethodsFails() {
JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.SimpleComponent",
"package test;",
"",
"import dagger.Component;",
"",
"import javax.inject.Provider;",
"",
"@Component",
"abstract class SimpleComponent {",
" interface Parent {",
" SimpleComponent build();",
" SimpleComponent create();",
" }",
"",
" @Component.Builder",
" interface Builder extends Parent {}",
"}");
assertAbout(javaSource()).that(componentFile)
.processedWith(new ComponentProcessor())
.failsToCompile()
.withErrorContaining(
String.format(MSGS.inheritedTwoBuildMethods(), "create()", "build()"))
.in(componentFile).onLine(15);
}
@Test
public void testMoreThanOneArgFails() {
JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.SimpleComponent",
"package test;",
"",
"import dagger.Component;",
"",
"import javax.inject.Provider;",
"",
"@Component",
"abstract class SimpleComponent {",
" @Component.Builder",
" interface Builder {",
" SimpleComponent build();",
" Builder set(String s, Integer i);",
" Builder set(Number n, Double d);",
" }",
"}");
assertAbout(javaSource()).that(componentFile)
.processedWith(new ComponentProcessor())
.failsToCompile()
.withErrorContaining(MSGS.methodsMustTakeOneArg())
.in(componentFile).onLine(12)
.and().withErrorContaining(MSGS.methodsMustTakeOneArg())
.in(componentFile).onLine(13);
}
@Test
public void testInheritedMoreThanOneArgFails() {
JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.SimpleComponent",
"package test;",
"",
"import dagger.Component;",
"",
"import javax.inject.Provider;",
"",
"@Component",
"abstract class SimpleComponent {",
" interface Parent {",
" SimpleComponent build();",
" Builder set1(String s, Integer i);",
" }",
"",
" @Component.Builder",
" interface Builder extends Parent {}",
"}");
assertAbout(javaSource()).that(componentFile)
.processedWith(new ComponentProcessor())
.failsToCompile()
.withErrorContaining(
String.format(MSGS.inheritedMethodsMustTakeOneArg(),
"set1(java.lang.String,java.lang.Integer)"))
.in(componentFile).onLine(15);
}
@Test
public void testSetterReturningNonVoidOrBuilderFails() {
JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.SimpleComponent",
"package test;",
"",
"import dagger.Component;",
"",
"import javax.inject.Provider;",
"",
"@Component",
"abstract class SimpleComponent {",
" @Component.Builder",
" interface Builder {",
" SimpleComponent build();",
" String set(Integer i);",
" }",
"}");
assertAbout(javaSource()).that(componentFile)
.processedWith(new ComponentProcessor())
.failsToCompile()
.withErrorContaining(MSGS.methodsMustReturnVoidOrBuilder())
.in(componentFile).onLine(12);
}
@Test
public void testInheritedSetterReturningNonVoidOrBuilderFails() {
JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.SimpleComponent",
"package test;",
"",
"import dagger.Component;",
"",
"import javax.inject.Provider;",
"",
"@Component",
"abstract class SimpleComponent {",
" interface Parent {",
" SimpleComponent build();",
" String set(Integer i);",
" }",
"",
" @Component.Builder",
" interface Builder extends Parent {}",
"}");
assertAbout(javaSource()).that(componentFile)
.processedWith(new ComponentProcessor())
.failsToCompile()
.withErrorContaining(
String.format(MSGS.inheritedMethodsMustReturnVoidOrBuilder(),
"set(java.lang.Integer)"))
.in(componentFile).onLine(15);
}
@Test
public void testGenericsOnSetterMethodFails() {
JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.SimpleComponent",
"package test;",
"",
"import dagger.Component;",
"",
"import javax.inject.Provider;",
"",
"@Component",
"abstract class SimpleComponent {",
" @Component.Builder",
" interface Builder {",
" SimpleComponent build();",
" <T> Builder set(T t);",
" }",
"}");
assertAbout(javaSource()).that(componentFile)
.processedWith(new ComponentProcessor())
.failsToCompile()
.withErrorContaining(MSGS.methodsMayNotHaveTypeParameters())
.in(componentFile).onLine(12);
}
@Test
public void testGenericsOnInheritedSetterMethodFails() {
JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.SimpleComponent",
"package test;",
"",
"import dagger.Component;",
"",
"import javax.inject.Provider;",
"",
"@Component",
"abstract class SimpleComponent {",
" interface Parent {",
" SimpleComponent build();",
" <T> Builder set(T t);",
" }",
"",
" @Component.Builder",
" interface Builder extends Parent {}",
"}");
assertAbout(javaSource()).that(componentFile)
.processedWith(new ComponentProcessor())
.failsToCompile()
.withErrorContaining(
String.format(MSGS.inheritedMethodsMayNotHaveTypeParameters(), "<T>set(T)"))
.in(componentFile).onLine(15);
}
@Test
public void testMultipleSettersPerTypeFails() {
JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.SimpleComponent",
"package test;",
"",
"import dagger.Component;",
"",
"import javax.inject.Provider;",
"",
"@Component",
"abstract class SimpleComponent {",
" @Component.Builder",
" interface Builder {",
" SimpleComponent build();",
" void set1(String s);",
" void set2(String s);",
" }",
"}");
assertAbout(javaSource()).that(componentFile)
.processedWith(new ComponentProcessor())
.failsToCompile()
.withErrorContaining(
String.format(MSGS.manyMethodsForType(),
"java.lang.String", "[set1(java.lang.String), set2(java.lang.String)]"))
.in(componentFile).onLine(10);
}
@Test
public void testMultipleSettersPerTypeIncludingResolvedGenericsFails() {
JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.SimpleComponent",
"package test;",
"",
"import dagger.Component;",
"",
"import javax.inject.Provider;",
"",
"@Component",
"abstract class SimpleComponent {",
" interface Parent<T> {",
" void set1(T t);",
" }",
"",
" @Component.Builder",
" interface Builder extends Parent<String> {",
" SimpleComponent build();",
" void set2(String s);",
" }",
"}");
assertAbout(javaSource()).that(componentFile)
.processedWith(new ComponentProcessor())
.failsToCompile()
.withErrorContaining(
String.format(MSGS.manyMethodsForType(),
"java.lang.String", "[set1(T), set2(java.lang.String)]"))
.in(componentFile).onLine(14);
}
@Test
public void testExtraSettersFails() {
JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.SimpleComponent",
"package test;",
"",
"import dagger.Component;",
"",
"import javax.inject.Provider;",
"",
"@Component",
"abstract class SimpleComponent {",
" @Component.Builder",
" interface Builder {",
" SimpleComponent build();",
" void set1(String s);",
" void set2(Integer s);",
" }",
"}");
assertAbout(javaSource()).that(componentFile)
.processedWith(new ComponentProcessor())
.failsToCompile()
.withErrorContaining(
String.format(MSGS.extraSetters(),
"[void test.SimpleComponent.Builder.set1(String),"
+ " void test.SimpleComponent.Builder.set2(Integer)]"))
.in(componentFile).onLine(10);
}
@Test
public void testMissingSettersFail() {
JavaFileObject moduleFile = JavaFileObjects.forSourceLines("test.TestModule",
"package test;",
"",
"import dagger.Module;",
"import dagger.Provides;",
"",
"@Module",
"final class TestModule {",
" TestModule(String unused) {}",
" @Provides String s() { return null; }",
"}");
JavaFileObject module2File = JavaFileObjects.forSourceLines("test.Test2Module",
"package test;",
"",
"import dagger.Module;",
"import dagger.Provides;",
"",
"@Module",
"final class Test2Module {",
" @Provides Integer i() { return null; }",
"}");
JavaFileObject module3File = JavaFileObjects.forSourceLines("test.Test3Module",
"package test;",
"",
"import dagger.Module;",
"import dagger.Provides;",
"",
"@Module",
"final class Test3Module {",
" Test3Module(String unused) {}",
" @Provides Double d() { return null; }",
"}");
JavaFileObject componentFile = JavaFileObjects.forSourceLines("test.TestComponent",
"package test;",
"",
"import dagger.Component;",
"",
"@Component(modules = {TestModule.class, Test2Module.class, Test3Module.class},",
" dependencies = OtherComponent.class)",
"interface TestComponent {",
" String string();",
" Integer integer();",
"",
" @Component.Builder",
" interface Builder {",
" TestComponent create();",
" }",
"}");
JavaFileObject otherComponent = JavaFileObjects.forSourceLines("test.OtherComponent",
"package test;",
"",
"import dagger.Component;",
"",
"@Component",
"interface OtherComponent {}");
assertAbout(javaSources())
.that(ImmutableList.of(moduleFile, module2File, module3File, componentFile, otherComponent))
.processedWith(new ComponentProcessor())
.failsToCompile()
.withErrorContaining(
// Ignores Test2Module because we can construct it ourselves.
// TODO(sameb): Ignore Test3Module because it's not used within transitive dependencies.
String.format(MSGS.missingSetters(),
"[test.TestModule, test.Test3Module, test.OtherComponent]"))
.in(componentFile).onLine(12);
}
}