• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015 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.subcomponent;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 
21 import com.google.common.collect.ImmutableMap;
22 import com.google.common.collect.ImmutableSet;
23 import dagger.functional.subcomponent.MultibindingSubcomponents.BoundInChild;
24 import dagger.functional.subcomponent.MultibindingSubcomponents.BoundInParent;
25 import dagger.functional.subcomponent.MultibindingSubcomponents.BoundInParentAndChild;
26 import dagger.functional.subcomponent.MultibindingSubcomponents.ParentWithProvisionHasChildWithProvision;
27 import dagger.functional.subcomponent.MultibindingSubcomponents.ParentWithProvisionHasChildWithoutProvision;
28 import dagger.functional.subcomponent.MultibindingSubcomponents.ParentWithoutProvisionHasChildWithProvision;
29 import dagger.functional.subcomponent.MultibindingSubcomponents.ParentWithoutProvisionHasChildWithoutProvision;
30 import dagger.functional.subcomponent.MultibindingSubcomponents.RequiresMultibindings;
31 import org.junit.Before;
32 import org.junit.Test;
33 import org.junit.runner.RunWith;
34 import org.junit.runners.JUnit4;
35 
36 @RunWith(JUnit4.class)
37 public class SubcomponentMultibindingsTest {
38 
39   private static final RequiresMultibindings<BoundInParent> BOUND_IN_PARENT =
40       new RequiresMultibindings<>(
41           ImmutableSet.of(BoundInParent.INSTANCE),
42           ImmutableMap.of("parent key", BoundInParent.INSTANCE));
43 
44   private static final RequiresMultibindings<BoundInChild> BOUND_IN_CHILD =
45       new RequiresMultibindings<>(
46           ImmutableSet.of(BoundInChild.INSTANCE),
47           ImmutableMap.of("child key", BoundInChild.INSTANCE));
48 
49   private static final RequiresMultibindings<BoundInParentAndChild> BOUND_IN_PARENT_AND_CHILD =
50       new RequiresMultibindings<>(
51           ImmutableSet.of(BoundInParentAndChild.IN_PARENT, BoundInParentAndChild.IN_CHILD),
52           ImmutableMap.of(
53               "parent key", BoundInParentAndChild.IN_PARENT,
54               "child key", BoundInParentAndChild.IN_CHILD));
55 
56   private static final RequiresMultibindings<BoundInParentAndChild>
57       BOUND_IN_PARENT_AND_CHILD_PROVIDED_BY_PARENT =
58           new RequiresMultibindings<>(
59               ImmutableSet.of(BoundInParentAndChild.IN_PARENT),
60               ImmutableMap.of("parent key", BoundInParentAndChild.IN_PARENT));
61 
62   private ParentWithoutProvisionHasChildWithoutProvision
63       parentWithoutProvisionHasChildWithoutProvision;
64   private ParentWithoutProvisionHasChildWithProvision parentWithoutProvisionHasChildWithProvision;
65   private ParentWithProvisionHasChildWithoutProvision parentWithProvisionHasChildWithoutProvision;
66   private ParentWithProvisionHasChildWithProvision parentWithProvisionHasChildWithProvision;
67 
68   @Before
setUp()69   public void setUp() {
70     parentWithoutProvisionHasChildWithoutProvision =
71         DaggerMultibindingSubcomponents_ParentWithoutProvisionHasChildWithoutProvision.create();
72     parentWithoutProvisionHasChildWithProvision =
73         DaggerMultibindingSubcomponents_ParentWithoutProvisionHasChildWithProvision.create();
74     parentWithProvisionHasChildWithoutProvision =
75         DaggerMultibindingSubcomponents_ParentWithProvisionHasChildWithoutProvision.create();
76     parentWithProvisionHasChildWithProvision =
77         DaggerMultibindingSubcomponents_ParentWithProvisionHasChildWithProvision.create();
78   }
79 
80   @Test
testParentWithoutProvisionHasChildWithoutProvision()81   public void testParentWithoutProvisionHasChildWithoutProvision() {
82     // Child
83     assertThat(
84             parentWithoutProvisionHasChildWithoutProvision
85                 .childWithoutProvision()
86                 .grandchild()
87                 .requiresMultibindingsBoundInParent())
88         .isEqualTo(BOUND_IN_PARENT);
89 
90     // Grandchild
91     assertThat(
92             parentWithoutProvisionHasChildWithoutProvision
93                 .childWithoutProvision()
94                 .grandchild()
95                 .requiresMultibindingsBoundInParentAndChild())
96         .isEqualTo(BOUND_IN_PARENT_AND_CHILD);
97     assertThat(
98             parentWithoutProvisionHasChildWithoutProvision
99                 .childWithoutProvision()
100                 .grandchild()
101                 .requiresMultibindingsBoundInChild())
102         .isEqualTo(BOUND_IN_CHILD);
103 
104     /*
105      * Even though the multibinding for Set<RequiresMultiboundObjects> does not itself have a
106      * contribution from the child, it must be pushed down to (not duplicated in) the child because
107      * its contribution depends on multibindings that have one contribution from the parent and one
108      * from the child.
109      *
110      */
111     assertThat(
112             parentWithoutProvisionHasChildWithoutProvision
113                 .childWithoutProvision()
114                 .grandchild()
115                 .setOfRequiresMultibindingsInParentAndChild())
116         .containsExactly(BOUND_IN_PARENT_AND_CHILD);
117   }
118 
119   @Test
testParentWithoutProvisionHasChildWithProvision()120   public void testParentWithoutProvisionHasChildWithProvision() {
121     // Child
122     assertThat(
123             parentWithoutProvisionHasChildWithProvision
124                 .childWithProvision()
125                 .grandchild()
126                 .requiresMultibindingsBoundInParent())
127         .isEqualTo(BOUND_IN_PARENT);
128 
129     // Grandchild
130     assertThat(
131             parentWithoutProvisionHasChildWithProvision
132                 .childWithProvision()
133                 .grandchild()
134                 .requiresMultibindingsBoundInParentAndChild())
135         .isEqualTo(BOUND_IN_PARENT_AND_CHILD);
136     assertThat(
137             parentWithoutProvisionHasChildWithProvision
138                 .childWithProvision()
139                 .grandchild()
140                 .requiresMultibindingsBoundInChild())
141         .isEqualTo(BOUND_IN_CHILD);
142 
143     /*
144      * Even though the multibinding for Set<RequiresMultiboundObjects> does not itself have a
145      * contribution from the child, it must be pushed down to (not duplicated in) the child because
146      * its contribution depends on multibindings that have one contribution from the parent and one
147      * from the child.
148      *
149      */
150     assertThat(
151             parentWithoutProvisionHasChildWithProvision
152                 .childWithProvision()
153                 .grandchild()
154                 .setOfRequiresMultibindingsInParentAndChild())
155         .containsExactly(BOUND_IN_PARENT_AND_CHILD);
156   }
157 
158   @Test
testParentWithProvisionHasChildWithoutProvision()159   public void testParentWithProvisionHasChildWithoutProvision() {
160     // Parent
161     assertThat(parentWithProvisionHasChildWithoutProvision.requiresMultibindingsBoundInParent())
162         .isEqualTo(BOUND_IN_PARENT);
163 
164     assertThat(
165             parentWithProvisionHasChildWithoutProvision
166                 .requiresMultibindingsBoundInParentAndChild())
167         .isEqualTo(BOUND_IN_PARENT_AND_CHILD_PROVIDED_BY_PARENT);
168 
169     // Grandchild
170     assertThat(
171             parentWithProvisionHasChildWithoutProvision
172                 .childWithoutProvision()
173                 .grandchild()
174                 .requiresMultibindingsBoundInParent())
175         .isEqualTo(BOUND_IN_PARENT);
176     assertThat(
177             parentWithProvisionHasChildWithoutProvision
178                 .childWithoutProvision()
179                 .grandchild()
180                 .requiresMultibindingsBoundInChild())
181         .isEqualTo(BOUND_IN_CHILD);
182 
183     assertThat(
184             parentWithProvisionHasChildWithoutProvision
185                 .childWithoutProvision()
186                 .grandchild()
187                 .requiresMultibindingsBoundInParentAndChild())
188         .isEqualTo(BOUND_IN_PARENT_AND_CHILD);
189 
190     /*
191      * Even though the multibinding for Set<RequiresMultiboundObjects> does not itself have a
192      * contribution from the child, it must be pushed down to (not duplicated in) the child because
193      * its contribution depends on multibindings that have one contribution from the parent and one
194      * from the child.
195      *
196      */
197     assertThat(
198             parentWithProvisionHasChildWithoutProvision
199                 .childWithoutProvision()
200                 .grandchild()
201                 .setOfRequiresMultibindingsInParentAndChild())
202         .containsExactly(BOUND_IN_PARENT_AND_CHILD);
203   }
204 
205   @Test
testParentWithProvisionHasChildWithProvision()206   public void testParentWithProvisionHasChildWithProvision() {
207     // Parent
208     assertThat(parentWithProvisionHasChildWithProvision.requiresMultibindingsBoundInParent())
209         .isEqualTo(BOUND_IN_PARENT);
210 
211     // Child
212     assertThat(
213             parentWithProvisionHasChildWithProvision
214                 .childWithProvision()
215                 .requiresMultibindingsBoundInParent())
216         .isEqualTo(BOUND_IN_PARENT);
217     assertThat(
218             parentWithProvisionHasChildWithProvision
219                 .childWithProvision()
220                 .requiresMultibindingsBoundInChild())
221         .isEqualTo(BOUND_IN_CHILD);
222     assertThat(
223             parentWithProvisionHasChildWithProvision
224                 .childWithProvision()
225                 .requiresMultibindingsBoundInParentAndChild())
226         .isEqualTo(BOUND_IN_PARENT_AND_CHILD);
227 
228     // https://github.com/google/dagger/issues/401
229     assertThat(
230         DaggerMultibindingSubcomponents_ParentWithProvisionHasChildWithBinds.create()
231             .childWithBinds()
232             .requiresMultibindingsBoundInParentAndChild())
233         .isEqualTo(BOUND_IN_PARENT_AND_CHILD);
234 
235     /*
236      * Even though the multibinding for Set<RequiresMultiboundObjects> does not itself have a
237      * contribution from the child, it must be pushed down to (not duplicated in) the child because
238      * its contribution depends on multibindings that have one contribution from the parent and one
239      * from the child.
240      *
241      */
242     assertThat(
243             parentWithProvisionHasChildWithProvision
244                 .childWithProvision()
245                 .setOfRequiresMultibindingsInParentAndChild())
246         .containsExactly(BOUND_IN_PARENT_AND_CHILD);
247 
248     // Grandchild
249     assertThat(
250             parentWithProvisionHasChildWithProvision
251                 .childWithProvision()
252                 .grandchild()
253                 .requiresMultibindingsBoundInParent())
254         .isEqualTo(BOUND_IN_PARENT);
255     assertThat(
256             parentWithProvisionHasChildWithProvision
257                 .childWithProvision()
258                 .grandchild()
259                 .requiresMultibindingsBoundInChild())
260         .isEqualTo(BOUND_IN_CHILD);
261     assertThat(
262             parentWithProvisionHasChildWithProvision
263                 .childWithProvision()
264                 .grandchild()
265                 .requiresMultibindingsBoundInParentAndChild())
266         .isEqualTo(BOUND_IN_PARENT_AND_CHILD);
267 
268     /*
269      * Even though the multibinding for Set<RequiresMultiboundObjects> does not itself have a
270      * contribution from the child, it must be pushed down to (not duplicated in) the child because
271      * its contribution depends on multibindings that have one contribution from the parent and one
272      * from the child.
273      *
274      */
275     assertThat(
276             parentWithProvisionHasChildWithProvision
277                 .childWithProvision()
278                 .grandchild()
279                 .setOfRequiresMultibindingsInParentAndChild())
280         .containsExactly(BOUND_IN_PARENT_AND_CHILD);
281   }
282 }
283