@Before
  public void setup() {
    Messager messager = new TestMessager();
    elements = rule.getElements();
    processingEnvironment = new TestProcessingEnvironment(messager, elements, rule.getTypes());

    parcelable =
        JavaFileObjects.forSourceString(
            "android.os.Parcelable",
            ""
                + "package android.os;\n"
                + "public interface Parcelable {\n"
                + "public interface Creator<T> {\n"
                + "  public T createFromParcel(Parcel source);\n"
                + "  public T[] newArray(int size);\n"
                + "}"
                + "int describeContents();\n"
                + "void writeToParcel(Parcel in, int flags);\n"
                + "}\n");
    parcel =
        JavaFileObjects.forSourceString(
            "android.os.Parcel",
            ""
                + "package android.os;\n"
                + "public interface Parcel {\n"
                + "Object readValue(ClassLoader cl);\n"
                + "void writeValue(Object o);\n"
                + "}");
  }
 @Test
 public void factoryMethod_nonModuleParameter() {
   JavaFileObject componentFile =
       JavaFileObjects.forSourceLines(
           "test.TestComponent",
           "package test;",
           "",
           "import dagger.Component;",
           "",
           "@Component",
           "interface TestComponent {",
           "  ChildComponent newChildComponent(String someRandomString);",
           "}");
   JavaFileObject childComponentFile =
       JavaFileObjects.forSourceLines(
           "test.ChildComponent",
           "package test;",
           "",
           "import dagger.Subcomponent;",
           "",
           "@Subcomponent",
           "interface ChildComponent {}");
   assertAbout(javaSources())
       .that(ImmutableList.of(componentFile, childComponentFile))
       .processedWith(new ComponentProcessor())
       .failsToCompile()
       .withErrorContaining(
           "Subcomponent factory methods may only accept modules, but java.lang.String is not.")
       .in(componentFile)
       .onLine(7)
       .atColumn(43);
 }
Example #3
0
  @Test
  public void testTable() {
    JavaFileObject source =
        JavaFileObjects.forSourceString(
            "test.Test",
            Joiner.on('\n')
                .join(
                    "package test;",
                    "import Table;",
                    "import Key;",
                    "@Table",
                    "public class Test {",
                    "  @Key long id;",
                    "  String name;",
                    "}"));
    JavaFileObject expectedSource =
        JavaFileObjects.forSourceString(
            "test/Test$$ViewBinder",
            Joiner.on('\n')
                .join(
                    "// Generated code from Cying-ORM. Do not modify!",
                    "package test;",
                    "import android.content.ContentValues;",
                    "import android.database.Cursor;",
                    "import BaseDao;",
                    "public class Test$$Dao extends BaseDao<Test> {",
                    "    private static String SQL=\"CREATE TABLE test (id INTEGER PRIMARY KEY AUTOINCREMENT,name TEXT);\"",
                    "    static {",
                    "       saveSQL(SQL);",
                    "    }",
                    "    @Override protected Test cursorToEntity(Cursor cursor) {",
                    "        Test entity=new Test();",
                    "        entity.id=cursor.getLong(cursor.getColumnIndex(\"id\"));",
                    "        entity.name=cursor.getString(cursor.getColumnIndex(\"name\"));",
                    "        return entity;",
                    "    }",
                    "    @Override protected ContentValues entityToValues(Test entity) {",
                    "        ContentValues values=new ContentValues();",
                    "        values.put(\"name\",entity.name)",
                    "        return values;",
                    "    }",
                    "    @Override public String getTableName() {",
                    "        return \"test\";",
                    "    }",
                    "    @Override public String getTableSQL() { return SQL; }",
                    "    @Override public String getIdentityName() {",
                    "        return \"id\";",
                    "    }",
                    "    @Override public long getIdentity(Test entity) {",
                    "        return entity.id;",
                    "    }",
                    "}"));

    Truth.assertAbout(javaSource())
        .that(source)
        .processedWith(new ORMProcessor())
        .compilesWithoutError()
        .and()
        .generatesSources(expectedSource);
  }
  @Test
  public void methodWithMultipleIds() {
    JavaFileObject source =
        JavaFileObjects.forSourceString(
            "test.Test",
            Joiner.on('\n')
                .join(
                    "package test;",
                    "import android.app.Activity;",
                    "import android.view.View;",
                    "import butterknife.OnClick;",
                    "public class Test extends Activity {",
                    "  @OnClick({1, 2, 3}) void click() {}",
                    "}"));

    JavaFileObject expectedSource =
        JavaFileObjects.forSourceString(
            "test/Test$$ViewInjector",
            Joiner.on('\n')
                .join(
                    "package test;",
                    "import android.view.View;",
                    "import butterknife.ButterKnife.Finder;",
                    "import butterknife.ButterKnife.Injector;",
                    "public class Test$$ViewInjector<T extends test.Test> implements Injector<T> {",
                    "  @Override public void inject(final Finder finder, final T target, Object source) {",
                    "    View view;",
                    "    view = finder.findRequiredView(source, 1, \"method 'click'\");",
                    "    view.setOnClickListener(new butterknife.internal.DebouncingOnClickListener() {",
                    "      @Override public void doClick(android.view.View p0) {",
                    "        target.click();",
                    "      }",
                    "    });",
                    "    view = finder.findRequiredView(source, 2, \"method 'click'\");",
                    "    view.setOnClickListener(new butterknife.internal.DebouncingOnClickListener() {",
                    "      @Override public void doClick(android.view.View p0) {",
                    "        target.click();",
                    "      }",
                    "    });",
                    "    view = finder.findRequiredView(source, 3, \"method 'click'\");",
                    "    view.setOnClickListener(new butterknife.internal.DebouncingOnClickListener() {",
                    "      @Override public void doClick(android.view.View p0) {",
                    "        target.click();",
                    "      }",
                    "    });",
                    "  }",
                    "  @Override public void reset(T target) {",
                    "  }",
                    "}"));

    ASSERT
        .about(javaSource())
        .that(source)
        .processedWith(butterknifeProcessors())
        .compilesWithoutError()
        .and()
        .generatesSources(expectedSource);
  }
 @Test
 public void publicClass() {
   assert_()
       .about(javaSource())
       .that(JavaFileObjects.forResource("good/PublicClass.java"))
       .processedWith(new AutoFactoryProcessor())
       .compilesWithoutError()
       .and()
       .generatesSources(JavaFileObjects.forResource("expected/PublicClassFactory.java"));
 }
 @Test
 public void constructorAnnotated() {
   ASSERT
       .about(javaSource())
       .that(JavaFileObjects.forResource("good/ConstructorAnnotated.java"))
       .processedWith(new AutoFactoryProcessor())
       .compilesWithoutError()
       .and()
       .generatesSources(JavaFileObjects.forResource("expected/ConstructorAnnotatedFactory.java"));
 }
 @Test
 public void simpleClassCustomName() {
   assert_()
       .about(javaSource())
       .that(JavaFileObjects.forResource("good/SimpleClassCustomName.java"))
       .processedWith(new AutoFactoryProcessor())
       .compilesWithoutError()
       .and()
       .generatesSources(JavaFileObjects.forResource("expected/CustomNamedFactory.java"));
 }
 @Test
 public void factoryMethod_missingModulesWithParameters() {
   JavaFileObject componentFile =
       JavaFileObjects.forSourceLines(
           "test.TestComponent",
           "package test;",
           "",
           "import dagger.Component;",
           "",
           "@Component",
           "interface TestComponent {",
           "  ChildComponent newChildComponent();",
           "}");
   JavaFileObject childComponentFile =
       JavaFileObjects.forSourceLines(
           "test.ChildComponent",
           "package test;",
           "",
           "import dagger.Subcomponent;",
           "",
           "@Subcomponent(modules = ModuleWithParameters.class)",
           "interface ChildComponent {",
           "  Object object();",
           "}");
   JavaFileObject moduleFile =
       JavaFileObjects.forSourceLines(
           "test.ModuleWithParameters",
           "package test;",
           "",
           "import dagger.Module;",
           "import dagger.Provides;",
           "",
           "@Module",
           "final class ModuleWithParameters {",
           "  private final Object object;",
           "",
           "  ModuleWithParameters(Object object) {",
           "    this.object = object;",
           "  }",
           "",
           "  @Provides Object object() {",
           "    return object;",
           "  }",
           "}");
   assertAbout(javaSources())
       .that(ImmutableList.of(componentFile, childComponentFile, moduleFile))
       .processedWith(new ComponentProcessor())
       .failsToCompile()
       .withErrorContaining(
           "test.ChildComponent requires modules which have no visible default constructors. "
               + "Add the following modules as parameters to this method: "
               + "test.ModuleWithParameters")
       .in(componentFile)
       .onLine(7);
 }
 @Test
 public void mixedDepsImplementingInterfaces() {
   assert_()
       .about(javaSource())
       .that(JavaFileObjects.forResource("good/MixedDepsImplementingInterfaces.java"))
       .processedWith(new AutoFactoryProcessor())
       .compilesWithoutError()
       .and()
       .generatesSources(
           JavaFileObjects.forResource("expected/MixedDepsImplementingInterfacesFactory.java"));
 }
 @Test
 public void simpleClassPassedDeps() {
   ASSERT
       .about(javaSource())
       .that(JavaFileObjects.forResource("good/SimpleClassPassedDeps.java"))
       .processedWith(new AutoFactoryProcessor())
       .compilesWithoutError()
       .and()
       .generatesSources(
           JavaFileObjects.forResource("expected/SimpleClassPassedDepsFactory.java"));
 }
 @Test
 public void factoryExtendingAbstractClass() {
   ASSERT
       .about(javaSource())
       .that(JavaFileObjects.forResource("good/FactoryExtendingAbstractClass.java"))
       .processedWith(new AutoFactoryProcessor())
       .compilesWithoutError()
       .and()
       .generatesSources(
           JavaFileObjects.forResource("expected/FactoryExtendingAbstractClassFactory.java"));
 }
  @Test
  public void shouldCompileWithoutError() throws Exception {
    JavaFileObject source =
        JavaFileObjects.forSourceString(
            "LocalStorage",
            Joiner.on('\n')
                .join(
                    "package test;",
                    "import de.ad.sharp.api.SharedPreference;",
                    "import java.util.Date;",
                    "@SharedPreference public interface LocalStorage {",
                    "   int getIntPreference();",
                    "   void setIntPreference(int value);",
                    "   long getLongPreference();",
                    "   void setLongPreference(long value);",
                    "   float getFloatPreference();",
                    "   void setFloatPreference(float value);",
                    "   boolean isBooleanPreference();",
                    "   void setBooleanPreference(boolean value);",
                    "   String getStringPreference();",
                    "   void setStringPreference(String value);",
                    "   Date getDatePreference();",
                    "   void setDatePreference(Date value);",
                    "void reset();",
                    "}"));

    JavaFileObject expectedSource =
        JavaFileObjects.forSourceString(
            "LocalStorageImpl",
            Joiner.on('\n')
                .join(
                    "package test;",
                    "import de.ad.sharp.api.SharedPreference;",
                    "@SharedPreference public interface LocalStorage {",
                    "   int getIntPreference();",
                    "   void setIntPreference(int value);",
                    "   long getLongPreference();",
                    "   void setLongPreference(long value);",
                    "   float getFloatPreference();",
                    "   void setFloatPreference(float value);",
                    "   boolean getBooleanPreference();",
                    "   void setBooleanPreference(boolean value);",
                    "   String getStringPreference();",
                    "   void setStringPreference(String value);",
                    "}"));

    assertAbout(javaSource())
        .that(source)
        .processedWith(new SharedPreferenceProcessor())
        .compilesWithoutError();
    // http://stackoverflow.com/questions/32394726/assertionerror-when-unit-testing-an-annotation-processor-with-compile-testing
    // .and().generatesSources(expectedSource);
  }
 @Test
 public void simpleClassMixedDeps() {
   assert_()
       .about(javaSources())
       .that(
           ImmutableSet.of(
               JavaFileObjects.forResource("good/SimpleClassMixedDeps.java"),
               JavaFileObjects.forResource("support/AQualifier.java")))
       .processedWith(new AutoFactoryProcessor())
       .compilesWithoutError()
       .and()
       .generatesSources(JavaFileObjects.forResource("expected/SimpleClassMixedDepsFactory.java"));
 }
 @Test
 public void factoryImplementingGenericInterfaceExtension() {
   JavaFileObject file =
       JavaFileObjects.forResource("good/FactoryImplementingGenericInterfaceExtension.java");
   assert_()
       .about(javaSource())
       .that(file)
       .processedWith(new AutoFactoryProcessor())
       .compilesWithoutError()
       .and()
       .generatesSources(
           JavaFileObjects.forResource(
               "expected/FactoryImplementingGenericInterfaceExtension.java"));
 }
Example #15
0
  @Test
  public void testPrivateModelValues() {
    final String content =
        ""
            + "package com.yella;\n"
            + "import com.ngandroid.lib.annotations.NgModel;\n"
            + "import com.ngandroid.lib.annotations.NgScope;\n\n"
            + "@NgScope    \n"
            + "class PrivateScope {\n"
            + "   @NgModel\n"
            + "   Model model;"
            + "}\n"
            + "class Model {\n"
            + "   private void setX(int x){\n"
            + "   }\n"
            + "   private int getX(){\n"
            + "       return 0;\n"
            + "   }\n"
            + "}";

    JavaFileObject fileObject = JavaFileObjects.forSourceString("com.yella.PrivateScope", content);

    ASSERT
        .about(javaSource())
        .that(fileObject)
        .processedWith(
            Collections.singletonList(
                new NgProcessor("ng-processor/src/test/resources/emptylayout")))
        .failsToCompile()
        .withErrorContaining("Unable to access field")
        .in(fileObject)
        .onLine(10);
  }
 @Test
 public void rawComparableTypeMixedTypes() {
   JavaFileObject file =
       JavaFileObjects.forSourceLines(
           "test.MyTest",
           "package test;",
           "import static com.google.common.truth.Truth.assertThat;",
           "class MyTest {",
           "  public void testFoo() {",
           "    assertThat(new RawComparableType(3)).isLessThan(\"kak\");",
           "  }",
           "  private static final class RawComparableType implements Comparable {",
           "    private final int wrapped;",
           "    private RawComparableType(int toWrap) {",
           "      this.wrapped = toWrap;",
           "    }",
           "    @Override public int compareTo(Object other) {",
           "      return wrapped - ((RawComparableType) other).wrapped;",
           "    }",
           "  }",
           "}");
   assert_()
       .about(javaSource())
       .that(file)
       .failsToCompile()
       .withErrorContaining(
           "reason: actual argument java.lang.String cannot be converted to "
               + "test.MyTest.RawComparableType by method invocation conversion")
       .in(file)
       .onLine(5);
 }
Example #17
0
  @Test
  public void testPrivateUsedMethod() {
    final String content =
        ""
            + "package com.yella;\n"
            + "import com.ngandroid.lib.annotations.NgModel;\n"
            + "import com.ngandroid.lib.annotations.NgScope;\n\n"
            + "@NgScope    \n"
            + "class PrivateScope {\n"
            + "   private void method(){\n"
            + "   }\n"
            + "}";

    JavaFileObject fileObject = JavaFileObjects.forSourceString("com.yella.PrivateScope", content);

    ASSERT
        .about(javaSource())
        .that(fileObject)
        .processedWith(
            Collections.singletonList(
                new NgProcessor("ng-processor/src/test/resources/test_private_method")))
        .failsToCompile()
        .withErrorContaining("is not accessible")
        .in(fileObject)
        .onLine(7);
  }
  @Test
  public void failsIfStatic() {
    JavaFileObject source =
        JavaFileObjects.forSourceString(
            "test.Test",
            Joiner.on('\n')
                .join(
                    "package test;",
                    "import android.app.Activity;",
                    "import butterknife.OnClick;",
                    "public class Test extends Activity {",
                    "  @OnClick(1)",
                    "  public static void doStuff() {",
                    "  }",
                    "}"));

    ASSERT
        .about(javaSource())
        .that(source)
        .processedWith(butterknifeProcessors())
        .failsToCompile()
        .withErrorContaining("@OnClick methods must not be private or static. (test.Test.doStuff)")
        .in(source)
        .onLine(6);
  }
  @Test
  public void failsIfMoreThanOneParameter() {
    JavaFileObject source =
        JavaFileObjects.forSourceString(
            "test.Test",
            Joiner.on('\n')
                .join(
                    "package test;",
                    "import android.app.Activity;",
                    "import android.view.View;",
                    "import butterknife.OnClick;",
                    "public class Test extends Activity {",
                    "  @OnClick(1)",
                    "  public void doStuff(View thing, View otherThing) {",
                    "  }",
                    "}"));

    ASSERT
        .about(javaSource())
        .that(source)
        .processedWith(butterknifeProcessors())
        .failsToCompile()
        .withErrorContaining(
            "@OnClick methods can have at most 1 parameter(s). (test.Test.doStuff)")
        .in(source)
        .onLine(7);
  }
  @Test
  public void failsIfHasDuplicateIds() {
    JavaFileObject source =
        JavaFileObjects.forSourceString(
            "test.Test",
            Joiner.on('\n')
                .join(
                    "package test;",
                    "import android.app.Activity;",
                    "import butterknife.OnClick;",
                    "public class Test extends Activity {",
                    "  @OnClick({1, 2, 3, 1})",
                    "  void doStuff() {",
                    "  }",
                    "}"));

    ASSERT
        .about(javaSource())
        .that(source)
        .processedWith(butterknifeProcessors())
        .failsToCompile()
        .withErrorContaining(
            "@OnClick annotation for method contains duplicate ID 1. (test.Test.doStuff)")
        .in(source)
        .onLine(6);
  }
  @Test
  public void missingEmptyConstructor() {
    JavaFileObject helperClass =
        JavaFileObjects.forSourceString(
            "com.example.MyDatabaseHelper",
            Joiner.on('\n')
                .join(
                    "package com.example;",
                    "",
                    "import eu.f3rog.ormlite.helper.Helper;",
                    "import eu.f3rog.ormlite.helper.OnUpgrade;",
                    "",
                    "@Helper(",
                    "   name = \"my_database.db\",",
                    "   tables = {}",
                    ")",
                    "public class MyDatabaseHelper {",
                    "",
                    "   public MyDatabaseHelper(int i) { }",
                    "",
                    "}"));

    Truth.assert_()
        .about(JavaSourcesSubjectFactory.javaSources())
        .that(files(helperClass))
        .processedWith(new eu.f3rog.ormlite.helper.compiler.HelperProcessor())
        .failsToCompile()
        .withErrorContaining("must have empty constructor");
  }
  @Test
  public void wrong2ndOnUpgradeParam() {
    JavaFileObject helperClass =
        JavaFileObjects.forSourceString(
            "com.example.MyDatabaseHelper",
            Joiner.on('\n')
                .join(
                    "package com.example;",
                    "",
                    "import android.database.sqlite.SQLiteDatabase;",
                    "import com.j256.ormlite.support.ConnectionSource;",
                    "import eu.f3rog.ormlite.helper.Helper;",
                    "import eu.f3rog.ormlite.helper.OnUpgrade;",
                    "",
                    "@Helper(",
                    "   name = \"my_database.db\",",
                    "   tables = {}",
                    ")",
                    "public class MyDatabaseHelper {",
                    "",
                    "   @OnUpgrade(to = 1)",
                    "   public void up(SQLiteDatabase database, Object o) {}",
                    "",
                    "}"));

    Truth.assert_()
        .about(JavaSourcesSubjectFactory.javaSources())
        .that(files(helperClass))
        .processedWith(new eu.f3rog.ormlite.helper.compiler.HelperProcessor())
        .failsToCompile()
        .withErrorContaining("must have 2nd parameter of type");
  }
 @Test
 public void multipleProducesMethodsWithSameName() {
   JavaFileObject moduleFile =
       JavaFileObjects.forSourceLines(
           "test.TestModule",
           "package test;",
           "",
           "import dagger.producers.ProducerModule;",
           "import dagger.producers.Produces;",
           "",
           "@ProducerModule",
           "final class TestModule {",
           "  @Produces Object produce(int i) {",
           "    return i;",
           "  }",
           "",
           "  @Produces String produce() {",
           "    return \"\";",
           "  }",
           "}");
   String errorMessage = String.format(BINDING_METHOD_WITH_SAME_NAME, "Produces");
   assertAbout(javaSource())
       .that(moduleFile)
       .processedWith(new ComponentProcessor())
       .failsToCompile()
       .withErrorContaining(errorMessage)
       .in(moduleFile)
       .onLine(8)
       .and()
       .withErrorContaining(errorMessage)
       .in(moduleFile)
       .onLine(12);
 }
  @Test
  public void shouldCompileDefaultSharedPreferenceWithoutError() throws Exception {
    JavaFileObject source =
        JavaFileObjects.forSourceString(
            "LocalStorage",
            Joiner.on('\n')
                .join(
                    "package test;",
                    "import de.ad.sharp.api.DefaultSharedPreference;",
                    "@DefaultSharedPreference public interface LocalStorage {",
                    "   int getIntPreference();",
                    "   void setIntPreference(int value);",
                    "   long getLongPreference();",
                    "   void setLongPreference(long value);",
                    "   float getFloatPreference();",
                    "   void setFloatPreference(float value);",
                    "   boolean isBooleanPreference();",
                    "   void setBooleanPreference(boolean value);",
                    "   String getStringPreference();",
                    "   void setStringPreference(String value);",
                    "void reset();",
                    "}"));

    assertAbout(javaSource())
        .that(source)
        .processedWith(new SharedPreferenceProcessor())
        .compilesWithoutError();
  }
 private JavaFileObject classFile(String packageName, String className) {
   return JavaFileObjects.forSourceString(
       String.format("%s.%s", packageName, className),
       Joiner.on('\n')
           .join(
               String.format("package %s;", packageName),
               String.format("public class %s {}", className)));
 }
 @Test
 public void missingBinding() {
   JavaFileObject moduleFile =
       JavaFileObjects.forSourceLines(
           "test.TestModule",
           "package test;",
           "",
           "import dagger.Module;",
           "import dagger.Provides;",
           "",
           "@Module",
           "final class TestModule {",
           "  @Provides String provideString(int i) {",
           "    return Integer.toString(i);",
           "  }",
           "}");
   JavaFileObject componentFile =
       JavaFileObjects.forSourceLines(
           "test.TestComponent",
           "package test;",
           "",
           "import dagger.Component;",
           "",
           "@Component",
           "interface TestComponent {",
           "  ChildComponent newChildComponent();",
           "}");
   JavaFileObject childComponentFile =
       JavaFileObjects.forSourceLines(
           "test.ChildComponent",
           "package test;",
           "",
           "import dagger.Subcomponent;",
           "",
           "@Subcomponent(modules = TestModule.class)",
           "interface ChildComponent {",
           "  String getString();",
           "}");
   assertAbout(javaSources())
       .that(ImmutableList.of(moduleFile, componentFile, childComponentFile))
       .processedWith(new ComponentProcessor())
       .failsToCompile()
       .withErrorContaining(
           "java.lang.Integer cannot be provided without an @Inject constructor or from an "
               + "@Provides-annotated method");
 }
 @Test
 public void scopeMismatch() {
   JavaFileObject componentFile =
       JavaFileObjects.forSourceLines(
           "test.ParentComponent",
           "package test;",
           "",
           "import dagger.Component;",
           "import javax.inject.Singleton;",
           "",
           "@Component",
           "@Singleton",
           "interface ParentComponent {",
           "  ChildComponent childComponent();",
           "}");
   JavaFileObject subcomponentFile =
       JavaFileObjects.forSourceLines(
           "test.ChildComponent",
           "package test;",
           "",
           "import dagger.Subcomponent;",
           "",
           "@Subcomponent(modules = ChildModule.class)",
           "interface ChildComponent {",
           "  Object getObject();",
           "}");
   JavaFileObject moduleFile =
       JavaFileObjects.forSourceLines(
           "test.ChildModule",
           "package test;",
           "",
           "import dagger.Module;",
           "import dagger.Provides;",
           "import javax.inject.Singleton;",
           "",
           "@Module",
           "final class ChildModule {",
           "  @Provides @Singleton Object provideObject() { return null; }",
           "}");
   assertAbout(javaSources())
       .that(ImmutableList.of(componentFile, subcomponentFile, moduleFile))
       .processedWith(new ComponentProcessor())
       .failsToCompile()
       .withErrorContaining("@Singleton");
 }
 public SingleClassSubject(FailureStrategy failureStrategy, String subject) {
   super(failureStrategy, subject);
   source = JavaFileObjects.forResource(Utils.toResourcePath(subject));
   tester =
       ASSERT
           .about(javaSources())
           .that(ImmutableList.of(source, Utils.ROBO_SOURCE, Utils.SHADOW_EXTRACTOR_SOURCE))
           .processedWith(new RobolectricProcessor());
 }
 @Test
 public void factoryMethod_duplicateParameter() {
   JavaFileObject moduleFile =
       JavaFileObjects.forSourceLines(
           "test.TestModule",
           "package test;",
           "",
           "import dagger.Module;",
           "",
           "@Module",
           "final class TestModule {}");
   JavaFileObject componentFile =
       JavaFileObjects.forSourceLines(
           "test.TestComponent",
           "package test;",
           "",
           "import dagger.Component;",
           "",
           "@Component",
           "interface TestComponent {",
           "  ChildComponent newChildComponent(TestModule testModule1, TestModule testModule2);",
           "}");
   JavaFileObject childComponentFile =
       JavaFileObjects.forSourceLines(
           "test.ChildComponent",
           "package test;",
           "",
           "import dagger.Subcomponent;",
           "",
           "@Subcomponent(modules = TestModule.class)",
           "interface ChildComponent {}");
   assertAbout(javaSources())
       .that(ImmutableList.of(moduleFile, componentFile, childComponentFile))
       .processedWith(new ComponentProcessor())
       .failsToCompile()
       .withErrorContaining(
           "A module may only occur once an an argument in a Subcomponent factory method, "
               + "but test.TestModule was already passed.")
       .in(componentFile)
       .onLine(7)
       .atColumn(71);
 }
 @Test
 public void factoryExtendingAbstractClass_multipleConstructors() {
   JavaFileObject file =
       JavaFileObjects.forResource(
           "good/FactoryExtendingAbstractClassWithMultipleConstructors.java");
   assert_()
       .about(javaSource())
       .that(file)
       .processedWith(new AutoFactoryProcessor())
       .compilesWithoutError();
 }