• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 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.factory;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 import static org.junit.Assert.fail;
21 
22 import dagger.Component;
23 import org.junit.Test;
24 import org.junit.runner.RunWith;
25 import org.junit.runners.JUnit4;
26 
27 /**
28  * Tests for factories for components with modules that do not require an instance to be passed to
29  * the factory. Includes both tests where the module does not have a corresponding parameter in the
30  * factory method and where it does have a parameter, for cases where that's allowed.
31  */
32 @RunWith(JUnit4.class)
33 public final class FactoryImplicitModulesTest {
34 
35   @Component(modules = AbstractModule.class)
36   interface AbstractModuleComponent {
string()37     String string();
38 
39     @Component.Factory
40     interface Factory {
create()41       AbstractModuleComponent create();
42     }
43   }
44 
45   @Test
abstractModule()46   public void abstractModule() {
47     AbstractModuleComponent component =
48         DaggerFactoryImplicitModulesTest_AbstractModuleComponent.factory().create();
49     assertThat(component.string()).isEqualTo("foo");
50   }
51 
52   @Component(modules = InstantiableConcreteModule.class)
53   interface InstantiableConcreteModuleComponent {
getInt()54     int getInt();
55 
56     @Component.Factory
57     interface Factory {
create()58       InstantiableConcreteModuleComponent create();
59     }
60   }
61 
62   @Test
instantiableConcreteModule()63   public void instantiableConcreteModule() {
64     InstantiableConcreteModuleComponent component =
65         DaggerFactoryImplicitModulesTest_InstantiableConcreteModuleComponent.factory().create();
66     assertThat(component.getInt()).isEqualTo(42);
67   }
68 
69   @Component(modules = InstantiableConcreteModule.class)
70   interface InstantiableConcreteModuleWithFactoryParameterComponent {
getInt()71     int getInt();
72 
73     @Component.Factory
74     interface Factory {
create( InstantiableConcreteModule module)75       InstantiableConcreteModuleWithFactoryParameterComponent create(
76           InstantiableConcreteModule module);
77     }
78   }
79 
80   @Test
instantiableConcreteModule_withFactoryParameter()81   public void instantiableConcreteModule_withFactoryParameter() {
82     InstantiableConcreteModuleWithFactoryParameterComponent component =
83         DaggerFactoryImplicitModulesTest_InstantiableConcreteModuleWithFactoryParameterComponent
84             .factory()
85             .create(new InstantiableConcreteModule());
86     assertThat(component.getInt()).isEqualTo(42);
87   }
88 
89   @Test
instantiableConcreteModule_withFactoryParameter_failsOnNull()90   public void instantiableConcreteModule_withFactoryParameter_failsOnNull() {
91     try {
92       DaggerFactoryImplicitModulesTest_InstantiableConcreteModuleWithFactoryParameterComponent
93           .factory()
94           .create(null);
95       fail();
96     } catch (NullPointerException expected) {
97     }
98   }
99 
100   @Component(modules = ConcreteModuleThatCouldBeAbstract.class)
101   interface ConcreteModuleThatCouldBeAbstractComponent {
getDouble()102     double getDouble();
103 
104     @Component.Factory
105     interface Factory {
create()106       ConcreteModuleThatCouldBeAbstractComponent create();
107     }
108   }
109 
110   @Test
concreteModuleThatCouldBeAbstract()111   public void concreteModuleThatCouldBeAbstract() {
112     ConcreteModuleThatCouldBeAbstractComponent component =
113         DaggerFactoryImplicitModulesTest_ConcreteModuleThatCouldBeAbstractComponent.factory()
114             .create();
115     assertThat(component.getDouble()).isEqualTo(42.0);
116   }
117 
118   @Component(modules = ConcreteModuleThatCouldBeAbstract.class)
119   interface ConcreteModuleThatCouldBeAbstractWithFactoryParameterComponent {
getDouble()120     double getDouble();
121 
122     @Component.Factory
123     interface Factory {
create( ConcreteModuleThatCouldBeAbstract module)124       ConcreteModuleThatCouldBeAbstractWithFactoryParameterComponent create(
125           ConcreteModuleThatCouldBeAbstract module);
126     }
127   }
128 
129   @Test
concreteModuleThatCouldBeAbstract_withFactoryParameter()130   public void concreteModuleThatCouldBeAbstract_withFactoryParameter() {
131     ConcreteModuleThatCouldBeAbstractWithFactoryParameterComponent component =
132         DaggerFactoryImplicitModulesTest_ConcreteModuleThatCouldBeAbstractWithFactoryParameterComponent
133             .factory()
134             .create(new ConcreteModuleThatCouldBeAbstract());
135     assertThat(component.getDouble()).isEqualTo(42.0);
136   }
137 
138   @Test
concreteModuleThatCouldBeAbstract_withFactoryParameter_failsOnNull()139   public void concreteModuleThatCouldBeAbstract_withFactoryParameter_failsOnNull() {
140     // This matches what builders do when there's a setter for such a module; the setter checks that
141     // the argument is not null but otherwise ignores it.
142     // It's possible that we shouldn't even allow such a parameter for a factory, since unlike a
143     // builder, where the setter can just not be called, a factory doesn't give the option of not
144     // passing *something* for the unused parameter.
145     try {
146       ConcreteModuleThatCouldBeAbstractWithFactoryParameterComponent component =
147           DaggerFactoryImplicitModulesTest_ConcreteModuleThatCouldBeAbstractWithFactoryParameterComponent
148               .factory()
149               .create(null);
150       fail();
151     } catch (NullPointerException expected) {
152     }
153   }
154 }
155