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.Module
22 import dagger.Provides
23 import dagger.Subcomponent
24 import dagger.assisted.Assisted
25 import dagger.assisted.AssistedFactory
26 import dagger.assisted.AssistedInject
27 import dagger.multibindings.IntoSet
28 import org.junit.Test
29 import org.junit.runner.RunWith
30 import org.junit.runners.JUnit4
31 
32 @RunWith(JUnit4::class)
33 internal class AssistedFactoryWithMultibindingsTest {
34   @Component(modules = [ParentModule::class])
35   interface ParentComponent {
36     // Factory for assisted injection binding with multi binding contribution.
multibindingFooFactorynull37     fun multibindingFooFactory(): MultibindingFooFactory
38     fun childComponent(): ChildComponent.Builder
39   }
40 
41   class AssistedDep
42 
43   class MultibindingFoo
44   @AssistedInject
45   constructor(@Assisted val assistedDep: AssistedDep, private val stringSet: Set<String>) {
46     fun assistedDep(): AssistedDep = assistedDep
47 
48     fun stringSet(): Set<String> = stringSet
49   }
50 
51   @Subcomponent(modules = [ChildModule::class])
52   interface ChildComponent {
multibindingFooFactorynull53     fun multibindingFooFactory(): MultibindingFooFactory
54 
55     @Subcomponent.Builder
56     interface Builder {
57       fun build(): ChildComponent
58     }
59   }
60 
61   @Module(subcomponents = [ChildComponent::class])
62   class ParentModule {
parentStringnull63     @Provides @IntoSet fun parentString(): String = "parent"
64   }
65 
66   @Module
67   class ChildModule {
68     @Provides @IntoSet fun childString(): String = "child"
69   }
70 
71   @AssistedFactory
72   interface MultibindingFooFactory {
createFoonull73     fun createFoo(factoryAssistedDep1: AssistedDep): MultibindingFoo
74   }
75 
76   @Test
77   fun testAssistedFactoryWithMultibinding() {
78     val assistedDep1 = AssistedDep()
79     val parent = DaggerAssistedFactoryWithMultibindingsTest_ParentComponent.create()
80     val child = parent.childComponent().build()
81     val foo1 = parent.multibindingFooFactory().createFoo(assistedDep1)
82     val foo2 = child.multibindingFooFactory().createFoo(assistedDep1)
83     assertThat(foo1.assistedDep()).isEqualTo(foo2.assistedDep)
84     assertThat(foo1.stringSet()).containsExactly("parent")
85     assertThat(foo2.stringSet()).containsExactly("child", "parent")
86   }
87 }
88