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;
21  
22  import org.grouplens.grapht.annotation.AliasFor;
23  import org.grouplens.grapht.annotation.AnnotationBuilder;
24  import org.grouplens.grapht.annotation.DefaultNull;
25  import org.grouplens.grapht.annotation.DefaultString;
26  import org.grouplens.grapht.solver.MultipleBindingsException;
27  import org.junit.Test;
28  
29  import javax.annotation.Nullable;
30  import javax.inject.Inject;
31  import javax.inject.Qualifier;
32  import java.lang.annotation.*;
33  
34  import static org.hamcrest.Matchers.*;
35  import static org.junit.Assert.assertThat;
36  import static org.junit.Assert.fail;
37  
38  /**
39   * Tests for qualifier aliases.
40   *
41   * @author <a href="http://www.grouplens.org">GroupLens Research</a>
42   */
43  public class QualifierAliasTest {
44  
45      /**
46       * Test that bindings and dependencies on unaliased qualifier work.
47       */
48      @Test
49      public void testRealQualifier() throws InjectionException {
50          InjectorBuilder bld = InjectorBuilder.create();
51          bld.bind(Qual.class, String.class).to("hello");
52          Injector inj = bld.build();
53          RequireQual rq = inj.getInstance(RequireQual.class);
54          assertThat(rq.dependency, equalTo("hello"));
55      }
56  
57      /**
58       * Test that binding to alias w/ dep on unaliased qualifier works.
59       */
60      @Test
61      public void testBindAlias() throws InjectionException {
62          InjectorBuilder bld = InjectorBuilder.create();
63          bld.bind(Alias.class, String.class).to("hello");
64          Injector inj = bld.build();
65          RequireQual rq = inj.getInstance(RequireQual.class);
66          assertThat(rq.dependency, equalTo("hello"));
67      }
68  
69      /**
70       * Test that binding to alias value w/ dep on unaliased qualifier works.
71       */
72      @Test
73      public void testBindAliasValue() throws InjectionException {
74          InjectorBuilder bld = InjectorBuilder.create();
75          Alias qual = AnnotationBuilder.of(Alias.class).build();
76          bld.bind(String.class).withQualifier(qual).to("hello");
77          Injector inj = bld.build();
78          RequireQual rq = inj.getInstance(RequireQual.class);
79          assertThat(rq.dependency, equalTo("hello"));
80      }
81  
82      /**
83       * Test that binding to qualifier w/ dep on alias works.
84       */
85      @Test
86      public void testRequireAlias() throws InjectionException {
87          InjectorBuilder bld = InjectorBuilder.create();
88          bld.bind(Qual.class, String.class).to("hello");
89          Injector inj = bld.build();
90          RequireAlias rq = inj.getInstance(RequireAlias.class);
91          assertThat(rq.dependency, equalTo("hello"));
92      }
93  
94      /**
95       * Test that binding and requiring alias works.
96       */
97      @Test
98      public void testBindAndRequireAlias() throws InjectionException {
99          InjectorBuilder bld = InjectorBuilder.create();
100         bld.bind(Alias.class, String.class).to("hello");
101         Injector inj = bld.build();
102         RequireAlias rq = inj.getInstance(RequireAlias.class);
103         assertThat(rq.dependency, equalTo("hello"));
104     }
105 
106     /**
107      * Test that binding both alias and qualifier fails.  Aliases are treated as equivalent to their qualifiers,
108      * so we have a multiple-binding situation.
109      *
110      * We will also take this opportunity to test the {@link MultipleBindingsException}.
111      */
112     @Test
113     public void testBindQualAndAlias() throws InjectionException {
114         InjectorBuilder bld = InjectorBuilder.create();
115         bld.bind(Alias.class, String.class).to("goodbye");
116         bld.bind(Qual.class, String.class).to("hello");
117         Injector inj = bld.build();
118         try {
119             RequireAlias rq = inj.getInstance(RequireAlias.class);
120             fail("should fail w/ multiple bindings");
121         } catch (MultipleBindingsException ex) {
122             /* expected */
123             assertThat(ex.getBindRules(), hasSize(2));
124             assertThat(ex.getDesire().getDesiredType(),
125                        equalTo((Class) String.class));
126             assertThat(ex.getContext(), hasSize(2));
127         }
128     }
129 
130     /**
131      * Test that the default on the alias works.
132      */
133     @Test
134     public void testAliasDefault() throws InjectionException {
135         InjectorBuilder bld = InjectorBuilder.create();
136         Injector inj = bld.build();
137         RequireQual rq = inj.getInstance(RequireQual.class);
138         assertThat(rq.dependency, equalTo("wombat"));
139         RequireAlias ra = inj.getInstance(RequireAlias.class);
140         assertThat(ra.dependency, equalTo("wombat"));
141     }
142 
143     /**
144      * Basic qualifier
145      */
146     @Qualifier
147     @Retention(RetentionPolicy.RUNTIME)
148     @DefaultString("wombat")
149     @Target(ElementType.PARAMETER)
150     @Documented
151     public static @interface Qual {}
152 
153     /**
154      * Qualifier Alias
155      */
156     @Qualifier
157     @Retention(RetentionPolicy.RUNTIME)
158     @Target(ElementType.PARAMETER)
159     @Documented
160     @AliasFor(Qual.class)
161     public static @interface Alias {}
162 
163     public static class RequireQual {
164         final String dependency;
165 
166         @Inject
167         public RequireQual(@Qual String dep) {
168             dependency = dep;
169         }
170     }
171 
172     public static class RequireAlias {
173         final String dependency;
174 
175         @Inject
176         public RequireAlias(@Alias String dep) {
177             dependency = dep;
178         }
179     }
180 }