• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2006 Google Inc.
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 com.google.inject;
18 
19 import static com.google.inject.Asserts.assertContains;
20 import static com.google.inject.Asserts.getDeclaringSourcePart;
21 import static java.lang.annotation.RetentionPolicy.RUNTIME;
22 
23 import java.lang.annotation.Annotation;
24 import java.lang.annotation.Retention;
25 import junit.framework.TestCase;
26 
27 /** @author crazybob@google.com (Bob Lee) */
28 public class BindingAnnotationTest extends TestCase {
29 
testAnnotationWithValueMatchesKeyWithTypeOnly()30   public void testAnnotationWithValueMatchesKeyWithTypeOnly() throws CreationException {
31     Injector c =
32         Guice.createInjector(
33             new AbstractModule() {
34               @Override
35               protected void configure() {
36                 bindConstant().annotatedWith(Blue.class).to("foo");
37                 bind(BlueFoo.class);
38               }
39             });
40 
41     BlueFoo foo = c.getInstance(BlueFoo.class);
42 
43     assertEquals("foo", foo.s);
44   }
45 
testRequireExactAnnotationsDisablesFallback()46   public void testRequireExactAnnotationsDisablesFallback() {
47     try {
48       Guice.createInjector(
49           new AbstractModule() {
50             @Override
51             protected void configure() {
52               binder().requireExactBindingAnnotations();
53               bindConstant().annotatedWith(Blue.class).to("foo");
54               bind(BlueFoo.class);
55             }
56           });
57       fail();
58     } catch (CreationException expected) {
59       assertContains(
60           expected.getMessage(),
61           true,
62           "No implementation for java.lang.String annotated with",
63           "BindingAnnotationTest$Blue(value=5) was bound",
64           "at " + BindingAnnotationTest.class.getName(),
65           getDeclaringSourcePart(getClass()));
66     }
67   }
68 
testRequireExactAnnotationsDoesntBreakIfDefaultsExist()69   public void testRequireExactAnnotationsDoesntBreakIfDefaultsExist() {
70     Guice.createInjector(
71             new AbstractModule() {
72               @Override
73               protected void configure() {
74                 binder().requireExactBindingAnnotations();
75                 bindConstant().annotatedWith(Red.class).to("foo");
76                 bind(RedFoo.class);
77               }
78             })
79         .getInstance(RedFoo.class);
80   }
81 
testRequireExactAnnotationsRequireAllOptionals()82   public void testRequireExactAnnotationsRequireAllOptionals() {
83     try {
84       Guice.createInjector(
85           new AbstractModule() {
86             @Override
87             protected void configure() {
88               binder().requireExactBindingAnnotations();
89               bindConstant().annotatedWith(Color.class).to("foo");
90               bind(ColorFoo.class);
91             }
92           });
93       fail();
94     } catch (CreationException expected) {
95       assertContains(
96           expected.getMessage(),
97           true,
98           "No implementation for java.lang.String annotated with",
99           "BindingAnnotationTest$Color",
100           "at " + BindingAnnotationTest.class.getName(),
101           getDeclaringSourcePart(getClass()));
102     }
103   }
104 
testAnnotationWithValueThatDoesntMatch()105   public void testAnnotationWithValueThatDoesntMatch() {
106     try {
107       Guice.createInjector(
108           new AbstractModule() {
109             @Override
110             protected void configure() {
111               bindConstant().annotatedWith(createBlue(6)).to("six");
112               bind(String.class).toInstance("bar");
113               bind(BlueFoo.class);
114             }
115           });
116       fail();
117     } catch (CreationException expected) {
118       assertContains(
119           expected.getMessage(),
120           true,
121           "No implementation for java.lang.String annotated with",
122           "BindingAnnotationTest$Blue(value=5) was bound",
123           "at " + BindingAnnotationTest.class.getName(),
124           getDeclaringSourcePart(getClass()));
125     }
126   }
127 
128   static class BlueFoo {
129     @Inject
130     @Blue(5)
131     String s;
132   }
133 
134   static class RedFoo {
135     @Inject @Red String s;
136   }
137 
138   static class ColorFoo {
139     @Inject
140     @Color(b = 2)
141     String s;
142   }
143 
144   @Retention(RUNTIME)
145   @BindingAnnotation
146   @interface Blue {
value()147     int value();
148   }
149 
150   @Retention(RUNTIME)
151   @BindingAnnotation
152   @interface Red {
r()153     int r() default 42;
154 
g()155     int g() default 42;
156 
b()157     int b() default 42;
158   }
159 
160   @Retention(RUNTIME)
161   @BindingAnnotation
162   @interface Color {
r()163     int r() default 0;
164 
g()165     int g() default 0;
166 
b()167     int b();
168   }
169 
createBlue(final int value)170   public Blue createBlue(final int value) {
171     return new Blue() {
172       @Override
173       public int value() {
174         return value;
175       }
176 
177       @Override
178       public Class<? extends Annotation> annotationType() {
179         return Blue.class;
180       }
181 
182       @Override
183       public boolean equals(Object o) {
184         return o instanceof Blue && ((Blue) o).value() == value;
185       }
186 
187       @Override
188       public int hashCode() {
189         return 127 * "value".hashCode() ^ value;
190       }
191     };
192   }
193 }
194