1 /* 2 * Copyright (C) 2022 The Dagger Authors. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package dagger.internal.codegen; 18 19 import androidx.room.compiler.processing.util.Source; 20 import com.google.common.collect.ImmutableList; 21 import dagger.testing.compile.CompilerTests; 22 import org.junit.Test; 23 import org.junit.runner.RunWith; 24 import org.junit.runners.Parameterized; 25 import org.junit.runners.Parameterized.Parameters; 26 27 // Tests an invalid inject constructor that avoids validation in its own library by using 28 // a dependency on jsr330 rather than Dagger gets validated when used in a component. 29 @RunWith(Parameterized.class) 30 public class InvalidInjectConstructorTest { 31 @Parameters(name = "{0}") parameters()32 public static ImmutableList<Object[]> parameters() { 33 return CompilerMode.TEST_PARAMETERS; 34 } 35 36 private final CompilerMode compilerMode; 37 InvalidInjectConstructorTest(CompilerMode compilerMode)38 public InvalidInjectConstructorTest(CompilerMode compilerMode) { 39 this.compilerMode = compilerMode; 40 } 41 42 @Test usedInvalidConstructorFails()43 public void usedInvalidConstructorFails() { 44 Source component = 45 CompilerTests.javaSource( 46 "test.TestComponent", 47 "package test;", 48 "", 49 "import dagger.Component;", 50 "import dagger.internal.codegen.InvalidInjectConstructor;", 51 "", 52 "@Component", 53 "interface TestComponent {", 54 " InvalidInjectConstructor invalidInjectConstructor();", 55 "}"); 56 CompilerTests.daggerCompiler(component) 57 .withProcessingOptions(compilerMode.processorOptions()) 58 .compile( 59 subject -> { 60 // subject.hasErrorCount(2); 61 subject.hasErrorContaining( 62 "Type dagger.internal.codegen.InvalidInjectConstructor may only contain one " 63 + "injected constructor. Found: [" 64 + "@Inject dagger.internal.codegen.InvalidInjectConstructor(), " 65 + "@Inject dagger.internal.codegen.InvalidInjectConstructor(String)" 66 + "]"); 67 // TODO(b/215620949): Avoid reporting missing bindings on a type that has errors. 68 subject.hasErrorContaining( 69 "InvalidInjectConstructor cannot be provided without an @Inject constructor or " 70 + "an @Provides-annotated method."); 71 }); 72 } 73 74 @Test unusedInvalidConstructorFails()75 public void unusedInvalidConstructorFails() { 76 Source component = 77 CompilerTests.javaSource( 78 "test.TestComponent", 79 "package test;", 80 "", 81 "import dagger.Component;", 82 "import dagger.internal.codegen.InvalidInjectConstructor;", 83 "", 84 "@Component", 85 "interface TestComponent {", 86 // Here we're only using the members injection, but we're testing that we still validate 87 // the constructors 88 " void inject(InvalidInjectConstructor instance);", 89 "}"); 90 CompilerTests.daggerCompiler(component) 91 .withProcessingOptions(compilerMode.processorOptions()) 92 .compile( 93 subject -> { 94 // subject.hasErrorCount(2); 95 subject.hasErrorContaining( 96 "Type dagger.internal.codegen.InvalidInjectConstructor may only contain one " 97 + "injected constructor. Found: [" 98 + "@Inject dagger.internal.codegen.InvalidInjectConstructor(), " 99 + "@Inject dagger.internal.codegen.InvalidInjectConstructor(String)" 100 + "]"); 101 // TODO(b/215620949): Avoid reporting missing bindings on a type that has errors. 102 subject.hasErrorContaining( 103 "InvalidInjectConstructor cannot be provided without an @Inject constructor or " 104 + "an @Provides-annotated method."); 105 }); 106 } 107 } 108