View Javadoc

1   /*
2    * Grapht, an open source dependency injector.
3    * Copyright 2014-2015 various contributors (see CONTRIBUTORS.txt)
4    * Copyright 2010-2014 Regents of the University of Minnesota
5    *
6    * This program is free software; you can redistribute it and/or modify
7    * it under the terms of the GNU Lesser General Public License as
8    * published by the Free Software Foundation; either version 2.1 of the
9    * License, or (at your option) any later version.
10   *
11   * This program is distributed in the hope that it will be useful, but WITHOUT
12   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13   * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14   * details.
15   *
16   * You should have received a copy of the GNU General Public License along with
17   * this program; if not, write to the Free Software Foundation, Inc., 51
18   * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19   */
20  package org.grouplens.grapht.solver;
21  
22  import org.grouplens.grapht.CachePolicy;
23  import org.grouplens.grapht.annotation.AnnotationBuilder;
24  import org.grouplens.grapht.reflect.*;
25  import org.grouplens.grapht.reflect.internal.*;
26  import org.grouplens.grapht.reflect.internal.types.*;
27  import org.junit.Assert;
28  import org.junit.Test;
29  
30  import java.lang.annotation.Annotation;
31  
32  import static org.hamcrest.Matchers.equalTo;
33  import static org.junit.Assert.assertThat;
34  
35  public class BindRuleTest {
36      @Test
37      public void testEquals() {
38          // test various permutations of bind rule configurations
39          TypeA instance = new TypeA();
40  
41          BindRule b1 = BindRuleBuilder.create()
42                                       .setDependencyType(TypeA.class)
43                                       .setImplementation(TypeA.class)
44                                       .setCachePolicy(CachePolicy.NO_PREFERENCE)
45                                       .setQualifierMatcher(Qualifiers.matchAny())
46                                       .setTerminal(false)
47                                       .build();
48          BindRule b2 = BindRuleBuilder.create().setDependencyType(TypeA.class).setSatisfaction(new InstanceSatisfaction(instance)).setCachePolicy(CachePolicy.NO_PREFERENCE).setQualifierMatcher(Qualifiers.matchAny()).setTerminal(false).build();
49          BindRule b3 = BindRuleBuilder.create().setDependencyType(TypeA.class).setImplementation(TypeA.class).setCachePolicy(CachePolicy.NO_PREFERENCE).setQualifierMatcher(Qualifiers.match(RoleA.class)).setTerminal(false).build();
50  
51          Assert.assertEquals(b1, BindRuleBuilder.create().setDependencyType(TypeA.class).setImplementation(TypeA.class).setCachePolicy(CachePolicy.NO_PREFERENCE).setQualifierMatcher(Qualifiers.matchAny()).setTerminal(false).build());
52          Assert.assertFalse(b1.equals(BindRuleBuilder.create().setDependencyType(TypeA.class).setImplementation(TypeB.class).setCachePolicy(CachePolicy.NO_PREFERENCE).setQualifierMatcher(Qualifiers.matchAny()).setTerminal(false).build()));
53          Assert.assertFalse(b1.equals(BindRuleBuilder.create().setDependencyType(TypeA.class).setImplementation(TypeA.class).setCachePolicy(CachePolicy.NO_PREFERENCE).setQualifierMatcher(Qualifiers.matchAny()).setTerminal(true).build()));
54          Assert.assertFalse(b1.equals(BindRuleBuilder.create().setDependencyType(TypeA.class).setImplementation(TypeA.class).setCachePolicy(CachePolicy.NEW_INSTANCE).setQualifierMatcher(Qualifiers.matchAny()).setTerminal(false).build()));
55  
56          Assert.assertEquals(b2, BindRuleBuilder.create().setDependencyType(TypeA.class).setSatisfaction(new InstanceSatisfaction(instance)).setCachePolicy(CachePolicy.NO_PREFERENCE).setQualifierMatcher(Qualifiers.matchAny()).setTerminal(false).build());
57          Assert.assertFalse(b2.equals(BindRuleBuilder.create().setDependencyType(TypeA.class).setSatisfaction(new ProviderClassSatisfaction(ProviderA.class)).setCachePolicy(CachePolicy.NO_PREFERENCE).setQualifierMatcher(Qualifiers.matchAny()).setTerminal(false).build()));
58  
59          Assert.assertEquals(b3, BindRuleBuilder.create().setDependencyType(TypeA.class).setImplementation(TypeA.class).setCachePolicy(CachePolicy.NO_PREFERENCE).setQualifierMatcher(Qualifiers.match(RoleA.class)).setTerminal(false).build());
60          Assert.assertFalse(b3.equals(BindRuleBuilder.create().setDependencyType(TypeA.class).setImplementation(TypeA.class).setCachePolicy(CachePolicy.NO_PREFERENCE).setQualifierMatcher(Qualifiers.match(RoleD.class)).setTerminal(false).build()));
61      }
62  
63      @Test
64      public void testPrimitiveMatch() throws Exception {
65          // test boxing/unboxing of types
66          doMatchTest(Integer.class, null, int.class, null, true);
67          doMatchTest(int.class, null, Integer.class, null, true);
68      }
69      
70      @Test
71      public void testExactClassNoRoleMatch() throws Exception {
72          doMatchTest(TypeA.class, null, TypeA.class, null, true);
73      }
74      
75      @Test
76      public void testExactClassExactRoleMatch() throws Exception {
77          doMatchTest(TypeA.class, RoleA.class, TypeA.class, RoleA.class, true);
78      }
79      
80      @Test
81      public void testSubclassNoMatch() throws Exception {
82          doMatchTest(TypeB.class, null, TypeA.class, null, false);
83      }
84      
85      @Test
86      public void testNoInheritenceNoMatch() throws Exception {
87          doMatchTest(TypeC.class, null, TypeA.class, null, false);
88          doMatchTest(TypeA.class, null, TypeB.class, null, false);
89      }
90      
91      @Test
92      public void testNoRoleInheritenceNoMatch() throws Exception {
93          doMatchTest(TypeA.class, RoleA.class, TypeA.class, RoleD.class, false);
94      }
95      
96      @Test
97      public void testSuperRoleNoMatch() throws Exception {
98          doMatchTest(TypeA.class, RoleA.class, TypeA.class, RoleB.class, false);
99      }
100     
101     @SuppressWarnings({ "rawtypes", "unchecked" })
102     private void doMatchTest(Class desireType, Class<? extends Annotation> desireRole,
103                              Class bindType, Class<? extends Annotation> bindRole,
104                              boolean expected) throws Exception {
105         QualifierMatcher br = (bindRole == null ? Qualifiers.matchAny() : Qualifiers.match(bindRole));
106         Annotation dr = (desireRole == null ? null : new AnnotationBuilder(desireRole).build());
107         BindRule rule = BindRuleBuilder.create().setDependencyType(bindType).setImplementation(bindType).setCachePolicy(CachePolicy.NO_PREFERENCE).setQualifierMatcher(br).setTerminal(false).build();
108             
109         ReflectionDesire desire = new ReflectionDesire(new MockInjectionPoint(desireType, dr, false));
110         
111         Assert.assertEquals(expected, rule.matches(desire));
112     }
113     
114     @Test
115     public void testNullable() throws Exception {
116         doNullableTest(false, false, true);
117         doNullableTest(true, false, true);
118         doNullableTest(false, true, true);
119         doNullableTest(true, true, true);
120     }
121     
122     private void doNullableTest(boolean nullableDesire, boolean nullableSatisfaction, boolean expected) throws Exception {
123         InjectionPoint injectPoint = new MockInjectionPoint(TypeA.class, nullableDesire);
124         Satisfaction satisfaction = (nullableSatisfaction ? new NullSatisfaction(TypeA.class) 
125                                                           : new ClassSatisfaction(TypeA.class));
126 
127         BindRule rule = BindRuleBuilder.create().setDependencyType(TypeA.class).setSatisfaction(satisfaction).setCachePolicy(CachePolicy.NO_PREFERENCE).setQualifierMatcher(Qualifiers.matchAny()).setTerminal(true).build();
128         ReflectionDesire desire = new ReflectionDesire(injectPoint);
129         
130         Assert.assertEquals(expected, rule.matches(desire));
131     }
132     
133     @Test
134     public void testSatisfiableClassBindRuleSuccess() throws Exception {
135         BindRule rule = BindRuleBuilder.create().setDependencyType(TypeA.class).setSatisfaction(Satisfactions.type(TypeB.class)).setCachePolicy(CachePolicy.NO_PREFERENCE).setQualifierMatcher(Qualifiers.matchAny()).setTerminal(false).build();
136         ReflectionDesire desire = new ReflectionDesire(new MockInjectionPoint(TypeA.class, false));
137         
138         Assert.assertTrue(rule.matches(desire));
139         
140         ReflectionDesire applied = (ReflectionDesire) rule.apply(desire);
141         Assert.assertNotNull(applied.getSatisfaction());
142         Assert.assertEquals(ClassSatisfaction.class, applied.getSatisfaction().getClass());
143         Assert.assertEquals(TypeB.class, ((ClassSatisfaction) applied.getSatisfaction()).getErasedType());
144     }
145     
146     @Test
147     public void testUnsatisfiableClassBindRuleSuccess() throws Exception {
148         BindRule rule = BindRuleBuilder.create().setDependencyType(InterfaceA.class).setImplementation(InterfaceA.class).setCachePolicy(CachePolicy.NO_PREFERENCE).setQualifierMatcher(Qualifiers.matchAny()).setTerminal(false).build();
149         ReflectionDesire desire = new ReflectionDesire(new MockInjectionPoint(InterfaceA.class, false));
150         
151         Assert.assertTrue(rule.matches(desire));
152         
153         ReflectionDesire applied = (ReflectionDesire) rule.apply(desire);
154         Assert.assertNull(applied.getSatisfaction());
155         Assert.assertEquals(InterfaceA.class, applied.getDesiredType());
156     }
157     
158     @Test
159     public void testInstanceBindRuleSuccess() throws Exception {
160         TypeA instance = new TypeB();
161         BindRule rule = BindRuleBuilder.create().setDependencyType(TypeA.class).setSatisfaction(Satisfactions.instance(instance)).setCachePolicy(CachePolicy.NO_PREFERENCE).setQualifierMatcher(Qualifiers.matchAny()).setTerminal(false).build();
162         ReflectionDesire desire = new ReflectionDesire(new MockInjectionPoint(TypeA.class, false));
163         
164         Assert.assertTrue(rule.matches(desire));
165         
166         Desire applied = rule.apply(desire);
167         Assert.assertNotNull(applied.getSatisfaction());
168         Assert.assertEquals(InstanceSatisfaction.class, applied.getSatisfaction().getClass());
169         Assert.assertEquals(instance, ((InstanceSatisfaction) applied.getSatisfaction()).getInstance());
170     }
171     
172     @Test
173     public void testNullInstanceBindRuleSuccess() throws Exception {
174         BindRule rule = BindRuleBuilder.create().setDependencyType(TypeA.class).setSatisfaction(Satisfactions.nullOfType(TypeA.class)).setCachePolicy(CachePolicy.NO_PREFERENCE).setQualifierMatcher(Qualifiers.matchAny()).setTerminal(false).build();
175         ReflectionDesire desire = new ReflectionDesire(new MockInjectionPoint(TypeA.class, true));
176         
177         Assert.assertTrue(rule.matches(desire));
178         
179         Desire applied = rule.apply(desire);
180         Assert.assertNotNull(applied.getSatisfaction());
181         Assert.assertEquals(NullSatisfaction.class, applied.getSatisfaction().getClass());
182     }
183     
184     @Test
185     public void testProviderClassBindRuleSuccess() throws Exception {
186         BindRule rule = BindRuleBuilder.create().setDependencyType(TypeA.class).setSatisfaction(Satisfactions.providerType(ProviderA.class)).setCachePolicy(CachePolicy.NO_PREFERENCE).setQualifierMatcher(Qualifiers.matchAny()).setTerminal(false).build();
187         ReflectionDesire desire = new ReflectionDesire(new MockInjectionPoint(TypeA.class, false));
188         
189         Assert.assertTrue(rule.matches(desire));
190 
191         Desire applied = rule.apply(desire);
192         Assert.assertNotNull(applied.getSatisfaction());
193         Assert.assertEquals(ProviderClassSatisfaction.class, applied.getSatisfaction().getClass());
194         Assert.assertEquals(ProviderA.class, ((ProviderClassSatisfaction) applied.getSatisfaction()).getProviderType());
195     }
196     
197     @Test
198     public void testProviderInstanceBindRuleSuccess() throws Exception {
199         ProviderA instance = new ProviderA();
200         BindRule rule = BindRuleBuilder.create().setDependencyType(TypeA.class).setSatisfaction(Satisfactions.providerInstance(instance)).setCachePolicy(CachePolicy.NO_PREFERENCE).setQualifierMatcher(Qualifiers.matchAny()).setTerminal(false).build();
201         ReflectionDesire desire = new ReflectionDesire(new MockInjectionPoint(TypeA.class, false));
202         
203         Desire applied = rule.apply(desire);
204         Assert.assertNotNull(applied.getSatisfaction());
205         Assert.assertEquals(ProviderInstanceSatisfaction.class, applied.getSatisfaction().getClass());
206         Assert.assertEquals(instance, ((ProviderInstanceSatisfaction) applied.getSatisfaction()).getProvider());
207     }
208 
209     @Test
210     public void testCopyBuilder() {
211         BindRule b1 = BindRuleBuilder.create().setDependencyType(TypeA.class).setImplementation(TypeA.class).setCachePolicy(CachePolicy.NO_PREFERENCE).setQualifierMatcher(Qualifiers.matchAny()).setTerminal(false).build();
212         BindRule b2 = BindRuleBuilder.create().setDependencyType(TypeA.class).setImplementation(TypeA.class).setCachePolicy(CachePolicy.MEMOIZE).setQualifierMatcher(Qualifiers.matchAny()).setTerminal(false).build();
213         assertThat(b1.newCopyBuilder()
214                      .build(),
215                    equalTo(b1));
216         assertThat(b1.newCopyBuilder()
217                      .setCachePolicy(CachePolicy.MEMOIZE)
218                      .build(),
219                    equalTo(b2));
220     }
221 }