PageRenderTime 45ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/core/test/com/google/inject/name/NamedEquivalanceTest.java

https://gitlab.com/metamorphiccode/guice
Java | 258 lines | 187 code | 48 blank | 23 comment | 5 complexity | a3afb3ae890c162989e3a574c11ec668 MD5 | raw file
  1. /**
  2. * Copyright (C) 2010 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. package com.google.inject.name;
  17. import static com.google.inject.Asserts.assertContains;
  18. import com.google.inject.AbstractModule;
  19. import com.google.inject.ConfigurationException;
  20. import com.google.inject.CreationException;
  21. import com.google.inject.Guice;
  22. import com.google.inject.Inject;
  23. import com.google.inject.Injector;
  24. import com.google.inject.Key;
  25. import com.google.inject.Module;
  26. import com.google.inject.Provides;
  27. import junit.framework.TestCase;
  28. import java.io.Serializable;
  29. import java.lang.annotation.Annotation;
  30. import java.util.Properties;
  31. /**
  32. * Tests that {@code javax.inject.Named} and {@code com.google.inject.name.Named} are completely
  33. * interchangeable: bindings for one can be used to inject the other.
  34. *
  35. * @author cgdecker@gmail.com (Colin Decker)
  36. */
  37. public class NamedEquivalanceTest extends TestCase {
  38. private static final Module GUICE_BINDING_MODULE = moduleWithAnnotation(Names.named("foo"));
  39. private static final Module JSR330_BINDING_MODULE = moduleWithAnnotation(new JsrNamed("foo"));
  40. private static final Module GUICE_PROVIDER_METHOD_MODULE = getGuiceBindingProviderMethodModule();
  41. private static final Module JSR330_PROVIDER_METHOD_MODULE = getJsr330BindingProviderMethodModule();
  42. public void testKeysCreatedWithDifferentTypesAreEqual() {
  43. assertEquals(keyForAnnotation(new GuiceNamed("foo")), keyForAnnotation(new JsrNamed("foo")));
  44. assertEquals(keyForAnnotation(Names.named("foo")), keyForAnnotation(new GuiceNamed("foo")));
  45. assertEquals(keyForAnnotation(Names.named("foo")), keyForAnnotation(new JsrNamed("foo")));
  46. assertEquals(keyForAnnotationType(com.google.inject.name.Named.class),
  47. keyForAnnotationType(javax.inject.Named.class));
  48. }
  49. private static Key<String> keyForAnnotation(Annotation annotation) {
  50. return Key.get(String.class, annotation);
  51. }
  52. private static Key<String> keyForAnnotationType(Class<? extends Annotation> annotationType) {
  53. return Key.get(String.class, annotationType);
  54. }
  55. public void testBindingWithNamesCanInjectBothTypes() {
  56. assertInjectionsSucceed(GUICE_BINDING_MODULE);
  57. }
  58. public void testBindingWithJsr330AnnotationCanInjectBothTypes() {
  59. assertInjectionsSucceed(JSR330_BINDING_MODULE);
  60. }
  61. public void testBindingWithGuiceNamedAnnotatedProviderMethodCanInjectBothTypes() {
  62. assertInjectionsSucceed(GUICE_PROVIDER_METHOD_MODULE);
  63. }
  64. public void testBindingWithJsr330NamedAnnotatedProviderMethodCanInjectBothTypes() {
  65. assertInjectionsSucceed(JSR330_PROVIDER_METHOD_MODULE);
  66. }
  67. public void testBindingDifferentTypesWithSameValueIsIgnored() {
  68. assertDuplicateBinding(GUICE_BINDING_MODULE, JSR330_BINDING_MODULE, false);
  69. assertDuplicateBinding(JSR330_BINDING_MODULE, GUICE_BINDING_MODULE, false);
  70. }
  71. public void testBindingDifferentTypesWithSameValueIsAnErrorWithProviderMethods() {
  72. assertDuplicateBinding(GUICE_PROVIDER_METHOD_MODULE, JSR330_PROVIDER_METHOD_MODULE, true);
  73. assertDuplicateBinding(JSR330_PROVIDER_METHOD_MODULE, GUICE_PROVIDER_METHOD_MODULE, true);
  74. }
  75. public void testBindingDifferentTypesWithSameValueIsAnErrorMixed() {
  76. assertDuplicateBinding(GUICE_BINDING_MODULE, JSR330_PROVIDER_METHOD_MODULE, true);
  77. assertDuplicateBinding(JSR330_BINDING_MODULE, GUICE_PROVIDER_METHOD_MODULE, true);
  78. }
  79. public void testMissingBindingForGuiceNamedUsesSameTypeInErrorMessage() {
  80. assertMissingBindingErrorMessageUsesType(GuiceNamedClient.class);
  81. }
  82. public void testMissingBindingForJsr330NamedUsesSameTypeInErrorMessage() {
  83. assertMissingBindingErrorMessageUsesType(Jsr330NamedClient.class);
  84. }
  85. public void testBindPropertiesWorksWithJsr330() {
  86. assertInjectionsSucceed(new AbstractModule() {
  87. @Override protected void configure() {
  88. Properties properties = new Properties();
  89. properties.put("foo", "bar");
  90. Names.bindProperties(binder(), properties);
  91. }
  92. });
  93. }
  94. private static void assertMissingBindingErrorMessageUsesType(Class<?> clientType) {
  95. try {
  96. Guice.createInjector().getInstance(clientType);
  97. fail("should have thrown ConfigurationException");
  98. } catch (ConfigurationException e) {
  99. assertContains(e.getMessage(),
  100. "No implementation for java.lang.String annotated with @com.google.inject.name.Named(value=foo) was bound.");
  101. }
  102. }
  103. private static void assertDuplicateBinding(Module a, Module b, boolean fails) {
  104. try {
  105. Guice.createInjector(a, b);
  106. if(fails) {
  107. fail("should have thrown CreationException");
  108. }
  109. } catch (CreationException e) {
  110. if(fails) {
  111. assertContains(e.getMessage(),
  112. "A binding to java.lang.String annotated with @com.google.inject.name.Named(value=foo) was already configured");
  113. } else {
  114. throw e;
  115. }
  116. }
  117. }
  118. private static Module moduleWithAnnotation(final Annotation annotation) {
  119. return new AbstractModule() {
  120. @Override protected void configure() {
  121. bindConstant().annotatedWith(annotation).to("bar");
  122. }
  123. };
  124. }
  125. private static void assertInjectionsSucceed(Module module) {
  126. Injector injector = Guice.createInjector(module);
  127. assertInjected(injector.getInstance(GuiceNamedClient.class), injector
  128. .getInstance(Jsr330NamedClient.class));
  129. }
  130. private static void assertInjected(GuiceNamedClient guiceClient, Jsr330NamedClient jsr330Client) {
  131. assertEquals("bar", guiceClient.foo);
  132. assertEquals("bar", jsr330Client.foo);
  133. }
  134. private static Module getJsr330BindingProviderMethodModule() {
  135. return new AbstractModule() {
  136. @Override protected void configure() {}
  137. @SuppressWarnings("unused") @Provides @javax.inject.Named("foo") String provideFoo() {
  138. return "bar";
  139. }
  140. };
  141. }
  142. private static Module getGuiceBindingProviderMethodModule() {
  143. return new AbstractModule() {
  144. @Override protected void configure() {}
  145. @SuppressWarnings("unused") @Provides @Named("foo") String provideFoo() {
  146. return "bar";
  147. }
  148. };
  149. }
  150. private static class GuiceNamedClient {
  151. @Inject @Named("foo") String foo;
  152. }
  153. private static class Jsr330NamedClient {
  154. @Inject @javax.inject.Named("foo") String foo;
  155. }
  156. private static class JsrNamed implements javax.inject.Named, Serializable {
  157. private final String value;
  158. public JsrNamed(String value) {
  159. this.value = value;
  160. }
  161. public String value() {
  162. return this.value;
  163. }
  164. public int hashCode() {
  165. // This is specified in java.lang.Annotation.
  166. return (127 * "value".hashCode()) ^ value.hashCode();
  167. }
  168. public boolean equals(Object o) {
  169. if (!(o instanceof javax.inject.Named)) {
  170. return false;
  171. }
  172. javax.inject.Named other = (javax.inject.Named) o;
  173. return value.equals(other.value());
  174. }
  175. public String toString() {
  176. return "@" + javax.inject.Named.class.getName() + "(value=" + value + ")";
  177. }
  178. public Class<? extends Annotation> annotationType() {
  179. return javax.inject.Named.class;
  180. }
  181. private static final long serialVersionUID = 0;
  182. }
  183. private static class GuiceNamed implements com.google.inject.name.Named, Serializable {
  184. private final String value;
  185. public GuiceNamed(String value) {
  186. this.value = value;
  187. }
  188. public String value() {
  189. return this.value;
  190. }
  191. public int hashCode() {
  192. // This is specified in java.lang.Annotation.
  193. return (127 * "value".hashCode()) ^ value.hashCode();
  194. }
  195. public boolean equals(Object o) {
  196. if (!(o instanceof com.google.inject.name.Named)) {
  197. return false;
  198. }
  199. com.google.inject.name.Named other = (com.google.inject.name.Named) o;
  200. return value.equals(other.value());
  201. }
  202. public String toString() {
  203. return "@" + com.google.inject.name.Named.class.getName() + "(value=" + value + ")";
  204. }
  205. public Class<? extends Annotation> annotationType() {
  206. return com.google.inject.name.Named.class;
  207. }
  208. private static final long serialVersionUID = 0;
  209. }
  210. }