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