1 /* 2 * Copyright (C) 2023 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.functional.kotlinsrc.assisted 18 19 import com.google.common.truth.Truth.assertThat 20 import dagger.Component 21 import dagger.assisted.Assisted 22 import dagger.assisted.AssistedFactory 23 import dagger.assisted.AssistedInject 24 import javax.inject.Inject 25 import javax.inject.Provider 26 import org.junit.Test 27 import org.junit.runner.RunWith 28 import org.junit.runners.JUnit4 29 30 @RunWith(JUnit4::class) 31 internal class AssistedFactoryTest { 32 @Component 33 interface ParentComponent { 34 // Simple factory using a nested factory. nestedSimpleFooFactorynull35 fun nestedSimpleFooFactory(): SimpleFoo.Factory 36 fun nestedSimpleFooFactoryProvider(): Provider<SimpleFoo.Factory> 37 38 // Simple factory using a non-nested factory. 39 fun nonNestedSimpleFooFactory(): SimpleFooFactory 40 41 // Simple factory using a factory that extends a supertype. 42 fun extendedSimpleFooFactory(): ExtendedSimpleFooFactory 43 44 // Factory as interface 45 fun fooFactory(): FooFactory 46 47 // Factory as abstract class 48 fun abstractFooFactory(): AbstractFooFactory 49 50 // Factory without any assisted parameters 51 fun noAssistedParametersFooFactory(): NoAssistedParametersFooFactory 52 53 // Test injecting the factories from another class 54 fun someEntryPoint(): SomeEntryPoint 55 } 56 57 // This class tests the request of factories from another binding. 58 class SomeEntryPoint 59 @Inject 60 constructor( 61 val nestedSimpleFooFactory: SimpleFoo.Factory, 62 val nestedSimpleFooFactoryProvider: Provider<SimpleFoo.Factory>, 63 val nonNestedSimpleFooFactory: SimpleFooFactory, 64 val extendedSimpleFooFactory: ExtendedSimpleFooFactory, 65 val fooFactory: FooFactory, 66 val abstractFooFactory: AbstractFooFactory, 67 val noAssistedParametersFooFactory: NoAssistedParametersFooFactory 68 ) 69 70 class Dep1 @Inject constructor( 71 @Suppress("UNUSED_PARAMETER") dep2: Dep2, @Suppress("UNUSED_PARAMETER") dep3: Dep3) 72 class Dep2 @Inject constructor(@Suppress("UNUSED_PARAMETER") dep3: Dep3) 73 class Dep3 @Inject constructor(@Suppress("UNUSED_PARAMETER") dep4: Dep4) 74 class Dep4 @Inject constructor() 75 76 // A base interface to test that factories can reference subclasses of the assisted parameter. 77 interface AssistedDep 78 class AssistedDep1 : AssistedDep 79 class AssistedDep2 : AssistedDep 80 class SimpleFoo @AssistedInject constructor(@Assisted val assistedDep: AssistedDep) { 81 @AssistedFactory 82 interface Factory { 83 // Use different parameter names than Foo to make sure we're not assuming they're the same. 84 fun createSimpleFoo(factoryAssistedDep: AssistedDep): SimpleFoo 85 86 companion object { 87 // A no-op method to test static methods in assisted factories 88 fun staticMethod() {} 89 } 90 } 91 } 92 93 @AssistedFactory 94 interface SimpleFooFactory { 95 // Use different parameter names than Foo to make sure we're not assuming they're the same. createSimpleFoonull96 fun createSimpleFoo(factoryAssistedDep1: AssistedDep): SimpleFoo 97 98 companion object { 99 // A no-op method to test static methods are allowed 100 fun staticMethod() {} 101 102 // A no-op method to test static methods that return assisted type are allowed 103 fun staticSimpleFooMethod(): SimpleFoo? = null 104 } 105 } 106 107 @AssistedFactory interface ExtendedSimpleFooFactory : SimpleFooFactory 108 abstract class BaseFoo { 109 @Inject lateinit var dep4: Dep4 110 } 111 112 class Foo 113 @AssistedInject 114 constructor( 115 val dep1: Dep1, 116 @Assisted val assistedDep1: AssistedDep1, 117 val dep2Provider: Provider<Dep2>, 118 @Assisted val assistedDep2: AssistedDep2, 119 @Assisted val assistedInt: Int, 120 val factory: FooFactory 121 ) : BaseFoo() { 122 @Inject lateinit var dep3: Dep3 123 } 124 125 @AssistedFactory 126 interface FooFactory { 127 // Use different parameter names than Foo to make sure we're not assuming they're the same. createFoonull128 fun createFoo( 129 factoryAssistedDep1: AssistedDep1, 130 factoryAssistedDep2: AssistedDep2, 131 factoryAssistedInt: Int 132 ): Foo 133 } 134 135 @AssistedFactory 136 abstract class AbstractFooFactory { 137 // Use different parameter names than Foo to make sure we're not assuming they're the same. 138 abstract fun createFoo( 139 factoryAssistedDep1: AssistedDep1, 140 factoryAssistedDep2: AssistedDep2, 141 factoryAssistedInt: Int 142 ): Foo 143 144 // A no-op method to test concrete methods are allowed 145 fun concreteMethod() {} 146 147 // A no-op method to test concrete methods that return assisted type are allowed 148 fun concreteFooMethod(): Foo? = null 149 150 companion object { 151 // A no-op method to test static methods are allowed 152 fun staticMethod() {} 153 154 // A no-op method to test static methods that return assisted type are allowed 155 fun staticFooMethod(): Foo? = null 156 } 157 } 158 159 class NoAssistedParametersFoo 160 @AssistedInject 161 constructor( 162 val dep1: Dep1, 163 val dep2Provider: Provider<Dep2>, 164 val factory: NoAssistedParametersFooFactory 165 ) : BaseFoo() { 166 @Inject lateinit var dep3: Dep3 167 } 168 169 @AssistedFactory 170 interface NoAssistedParametersFooFactory { createNoAssistedParametersFoonull171 fun createNoAssistedParametersFoo(): NoAssistedParametersFoo 172 } 173 174 @Test 175 fun testNestedSimpleFooFactory() { 176 val assistedDep1 = AssistedDep1() 177 val simpleFoo1 = 178 DaggerAssistedFactoryTest_ParentComponent.create() 179 .nestedSimpleFooFactory() 180 .createSimpleFoo(assistedDep1) 181 assertThat(simpleFoo1.assistedDep).isEqualTo(assistedDep1) 182 val assistedDep2 = AssistedDep2() 183 val simpleFoo2 = 184 DaggerAssistedFactoryTest_ParentComponent.create() 185 .nestedSimpleFooFactory() 186 .createSimpleFoo(assistedDep2) 187 assertThat(simpleFoo2.assistedDep).isEqualTo(assistedDep2) 188 } 189 190 @Test testNestedSimpleFooFactoryProvidernull191 fun testNestedSimpleFooFactoryProvider() { 192 val assistedDep1 = AssistedDep1() 193 val simpleFoo1 = 194 DaggerAssistedFactoryTest_ParentComponent.create() 195 .nestedSimpleFooFactoryProvider() 196 .get() 197 .createSimpleFoo(assistedDep1) 198 assertThat(simpleFoo1.assistedDep).isEqualTo(assistedDep1) 199 val assistedDep2 = AssistedDep2() 200 val simpleFoo2 = 201 DaggerAssistedFactoryTest_ParentComponent.create() 202 .nestedSimpleFooFactoryProvider() 203 .get() 204 .createSimpleFoo(assistedDep2) 205 assertThat(simpleFoo2.assistedDep).isEqualTo(assistedDep2) 206 } 207 208 @Test testNonNestedSimpleFooFactorynull209 fun testNonNestedSimpleFooFactory() { 210 val assistedDep1 = AssistedDep1() 211 val simpleFoo = 212 DaggerAssistedFactoryTest_ParentComponent.create() 213 .nonNestedSimpleFooFactory() 214 .createSimpleFoo(assistedDep1) 215 assertThat(simpleFoo.assistedDep).isEqualTo(assistedDep1) 216 } 217 218 @Test testExtendedSimpleFooFactorynull219 fun testExtendedSimpleFooFactory() { 220 val assistedDep1 = AssistedDep1() 221 val simpleFoo = 222 DaggerAssistedFactoryTest_ParentComponent.create() 223 .extendedSimpleFooFactory() 224 .createSimpleFoo(assistedDep1) 225 assertThat(simpleFoo.assistedDep).isEqualTo(assistedDep1) 226 } 227 228 @Test testFooFactorynull229 fun testFooFactory() { 230 val assistedDep1 = AssistedDep1() 231 val assistedDep2 = AssistedDep2() 232 val assistedInt = 7 233 val foo = 234 DaggerAssistedFactoryTest_ParentComponent.create() 235 .fooFactory() 236 .createFoo(assistedDep1, assistedDep2, assistedInt) 237 assertThat(foo.dep1).isNotNull() 238 assertThat(foo.dep2Provider).isNotNull() 239 assertThat(foo.dep2Provider.get()).isNotNull() 240 assertThat(foo.dep3).isNotNull() 241 assertThat(foo.dep4).isNotNull() 242 assertThat(foo.assistedDep1).isEqualTo(assistedDep1) 243 assertThat(foo.assistedDep2).isEqualTo(assistedDep2) 244 assertThat(foo.assistedInt).isEqualTo(assistedInt) 245 assertThat(foo.factory).isNotNull() 246 } 247 248 @Test testNoAssistedParametersFooFactorynull249 fun testNoAssistedParametersFooFactory() { 250 val foo: NoAssistedParametersFoo = 251 DaggerAssistedFactoryTest_ParentComponent.create() 252 .noAssistedParametersFooFactory() 253 .createNoAssistedParametersFoo() 254 assertThat(foo.dep1).isNotNull() 255 assertThat(foo.dep2Provider).isNotNull() 256 assertThat(foo.dep2Provider.get()).isNotNull() 257 assertThat(foo.dep3).isNotNull() 258 assertThat(foo.dep4).isNotNull() 259 assertThat(foo.factory).isNotNull() 260 } 261 262 @Test testAssistedFactoryFromSomeEntryPointnull263 fun testAssistedFactoryFromSomeEntryPoint() { 264 val someEntryPoint: SomeEntryPoint = 265 DaggerAssistedFactoryTest_ParentComponent.create().someEntryPoint() 266 assertThat(someEntryPoint.nestedSimpleFooFactory).isNotNull() 267 assertThat(someEntryPoint.nestedSimpleFooFactoryProvider).isNotNull() 268 assertThat(someEntryPoint.nonNestedSimpleFooFactory).isNotNull() 269 assertThat(someEntryPoint.extendedSimpleFooFactory).isNotNull() 270 assertThat(someEntryPoint.fooFactory).isNotNull() 271 assertThat(someEntryPoint.abstractFooFactory).isNotNull() 272 assertThat(someEntryPoint.noAssistedParametersFooFactory).isNotNull() 273 } 274 } 275