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