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.Binds 21 import dagger.BindsInstance 22 import dagger.BindsOptionalOf 23 import dagger.Component 24 import dagger.Module 25 import dagger.Provides 26 import dagger.assisted.AssistedFactory 27 import dagger.assisted.AssistedInject 28 import dagger.multibindings.IntoSet 29 import dagger.multibindings.Multibinds 30 import java.util.Optional 31 import javax.inject.Inject 32 import javax.inject.Qualifier 33 import org.junit.Test 34 import org.junit.runner.RunWith 35 import org.junit.runners.JUnit4 36 37 /** Tests that qualified assisted types can be provided and injected as normal types. */ 38 @RunWith(JUnit4::class) 39 internal class AssistedFactoryAsQualifiedBindingTest { 40 @Qualifier annotation class AsComponentDependency 41 42 @Qualifier annotation class AsProvides 43 44 @Qualifier annotation class AsBinds 45 46 @Qualifier annotation class AsOptional 47 48 @Qualifier annotation class AsMultibinding 49 50 @Component(modules = [BarFactoryModule::class]) 51 interface TestComponent { foonull52 fun foo(): Foo 53 54 @Component.Factory 55 interface Factory { 56 fun create( 57 @BindsInstance @AsComponentDependency bar: Bar, 58 @BindsInstance @AsComponentDependency barFactory: BarFactory, 59 ): TestComponent 60 } 61 } 62 63 @Module 64 interface BarFactoryModule { bindsBarnull65 @Binds @AsBinds fun bindsBar(@AsComponentDependency bar: Bar): Bar 66 67 @Binds @AsBinds fun bindsBarFactory(@AsComponentDependency barFactory: BarFactory): BarFactory 68 69 @BindsOptionalOf @AsOptional fun optionalBar(): Bar 70 71 @BindsOptionalOf @AsOptional fun optionalBarFactory(): BarFactory 72 73 @Multibinds @AsMultibinding fun barSet(): Set<Bar> 74 75 @Multibinds @AsMultibinding fun barFactorySet(): Set<BarFactory> 76 77 @Multibinds fun unqualifiedBarSet(): Set<Bar> 78 79 @Multibinds fun unqualifiedBarFactorySet(): Set<BarFactory> 80 81 companion object { 82 @Provides @AsProvides fun providesBar(@AsComponentDependency bar: Bar): Bar = bar 83 84 @Provides 85 @AsProvides 86 fun providesBarFactory(@AsComponentDependency barFactory: BarFactory): BarFactory = barFactory 87 88 @Provides @AsOptional fun providesOptionalBar(@AsComponentDependency bar: Bar): Bar = bar 89 90 @Provides 91 @AsOptional 92 fun providesOptionalBarFactory(@AsComponentDependency barFactory: BarFactory): BarFactory = 93 barFactory 94 95 @Provides 96 @IntoSet 97 @AsMultibinding 98 fun providesMultibindingBar(@AsComponentDependency bar: Bar): Bar = bar 99 100 @Provides 101 @IntoSet 102 @AsMultibinding 103 fun providesMultibindingBarFactory( 104 @AsComponentDependency barFactory: BarFactory 105 ): BarFactory = barFactory 106 107 @Provides 108 @IntoSet 109 fun providesUnqualifiedMultibindingBar(@AsComponentDependency bar: Bar): Bar = bar 110 111 @Provides 112 @IntoSet 113 fun providesUnqualifiedMultibindingBarFactory( 114 @AsComponentDependency barFactory: BarFactory 115 ): BarFactory = barFactory 116 } 117 } 118 119 class Foo 120 @Inject 121 constructor( 122 val barFactory: BarFactory, 123 @AsComponentDependency val barAsComponentDependency: Bar, 124 @AsComponentDependency val barFactoryAsComponentDependency: BarFactory, 125 @AsProvides val barAsProvides: Bar, 126 @AsProvides val barFactoryAsProvides: BarFactory, 127 @AsBinds val barAsBinds: Bar, 128 @AsBinds val barFactoryAsBinds: BarFactory, 129 @AsOptional val optionalBar: Optional<Bar>, 130 @AsOptional val optionalBarFactory: Optional<BarFactory>, 131 @AsMultibinding val barSet: Set<Bar>, 132 @AsMultibinding val barFactorySet: Set<@JvmSuppressWildcards BarFactory>, 133 val unqualifiedBarSet: Set<Bar>, 134 val unqualifiedBarFactorySet: Set<@JvmSuppressWildcards BarFactory>, 135 ) 136 137 class Bar @AssistedInject constructor() 138 139 @AssistedFactory interfacenull140 fun interface BarFactory { 141 fun create(): Bar 142 } 143 144 @Test testFoonull145 fun testFoo() { 146 val bar = Bar() 147 val barFactory = BarFactory { bar } 148 val foo = 149 DaggerAssistedFactoryAsQualifiedBindingTest_TestComponent.factory() 150 .create(bar, barFactory) 151 .foo() 152 153 // Test we can inject the "real" BarFactory implemented by Dagger 154 assertThat(foo.barFactory).isNotNull() 155 assertThat(foo.barFactory).isNotEqualTo(barFactory) 156 assertThat(foo.barFactory.create()).isNotEqualTo(bar) 157 158 // Test injection of a qualified Bar/BarFactory with custom @BindsInstance implementation 159 assertThat(foo.barAsComponentDependency).isEqualTo(bar) 160 assertThat(foo.barFactoryAsComponentDependency).isEqualTo(barFactory) 161 162 // Test injection of a qualified Bar/BarFactory with custom @Provides implementation 163 assertThat(foo.barAsProvides).isEqualTo(bar) 164 assertThat(foo.barFactoryAsProvides).isEqualTo(barFactory) 165 166 // Test injection of a qualified Bar/BarFactory with custom @Binds implementation 167 assertThat(foo.barAsBinds).isEqualTo(bar) 168 assertThat(foo.barFactoryAsBinds).isEqualTo(barFactory) 169 170 // Test injection of a qualified Bar/BarFactory with custom @BindsOptionalOf implementation 171 assertThat(foo.optionalBar).isPresent() 172 assertThat(foo.optionalBar).hasValue(bar) 173 assertThat(foo.optionalBarFactory).isPresent() 174 assertThat(foo.optionalBarFactory).hasValue(barFactory) 175 176 // Test injection of a qualified Bar/BarFactory as multibinding 177 assertThat(foo.barSet).containsExactly(bar) 178 assertThat(foo.barFactorySet).containsExactly(barFactory) 179 180 // Test injection of a unqualified Bar/BarFactory as multibinding 181 assertThat(foo.unqualifiedBarSet).containsExactly(bar) 182 assertThat(foo.unqualifiedBarFactorySet).containsExactly(barFactory) 183 } 184 } 185