| /** |
| * Copyright (C) 2010 Google Inc. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.google.inject.name; |
| |
| import static com.google.inject.Asserts.assertContains; |
| |
| import java.io.Serializable; |
| import java.lang.annotation.Annotation; |
| import java.util.Properties; |
| |
| import junit.framework.TestCase; |
| |
| import com.google.inject.AbstractModule; |
| import com.google.inject.ConfigurationException; |
| import com.google.inject.CreationException; |
| import com.google.inject.Guice; |
| import com.google.inject.Inject; |
| import com.google.inject.Injector; |
| import com.google.inject.Key; |
| import com.google.inject.Module; |
| import com.google.inject.Provides; |
| |
| /** |
| * Tests that {@code javax.inject.Named} and {@code com.google.inject.name.Named} are completely |
| * interchangeable: bindings for one can be used to inject the other. |
| * |
| * @author cgdecker@gmail.com (Colin Decker) |
| */ |
| public class NamedEquivalanceTest extends TestCase { |
| |
| private static final Module GUICE_BINDING_MODULE = moduleWithAnnotation(Names.named("foo")); |
| private static final Module JSR330_BINDING_MODULE = moduleWithAnnotation(new JsrNamed("foo")); |
| private static final Module GUICE_PROVIDER_METHOD_MODULE = getGuiceBindingProviderMethodModule(); |
| private static final Module JSR330_PROVIDER_METHOD_MODULE = getJsr330BindingProviderMethodModule(); |
| |
| public void testKeysCreatedWithDifferentTypesAreEqual() { |
| assertEquals(keyForAnnotation(new GuiceNamed("foo")), keyForAnnotation(new JsrNamed("foo"))); |
| assertEquals(keyForAnnotation(Names.named("foo")), keyForAnnotation(new GuiceNamed("foo"))); |
| assertEquals(keyForAnnotation(Names.named("foo")), keyForAnnotation(new JsrNamed("foo"))); |
| |
| assertEquals(keyForAnnotationType(com.google.inject.name.Named.class), |
| keyForAnnotationType(javax.inject.Named.class)); |
| } |
| |
| private static Key<String> keyForAnnotation(Annotation annotation) { |
| return Key.get(String.class, annotation); |
| } |
| |
| private static Key<String> keyForAnnotationType(Class<? extends Annotation> annotationType) { |
| return Key.get(String.class, annotationType); |
| } |
| |
| public void testBindingWithNamesCanInjectBothTypes() { |
| assertInjectionsSucceed(GUICE_BINDING_MODULE); |
| } |
| |
| public void testBindingWithJsr330AnnotationCanInjectBothTypes() { |
| assertInjectionsSucceed(JSR330_BINDING_MODULE); |
| } |
| |
| public void testBindingWithGuiceNamedAnnotatedProviderMethodCanInjectBothTypes() { |
| assertInjectionsSucceed(GUICE_PROVIDER_METHOD_MODULE); |
| } |
| |
| public void testBindingWithJsr330NamedAnnotatedProviderMethodCanInjectBothTypes() { |
| assertInjectionsSucceed(JSR330_PROVIDER_METHOD_MODULE); |
| } |
| |
| public void testBindingDifferentTypesWithSameValueIsAnError() { |
| assertDuplicateBinding(GUICE_BINDING_MODULE, JSR330_BINDING_MODULE); |
| assertDuplicateBinding(JSR330_BINDING_MODULE, GUICE_BINDING_MODULE); |
| } |
| |
| public void testBindingDifferentTypesWithSameValueIsAnErrorWithProviderMethods() { |
| assertDuplicateBinding(GUICE_PROVIDER_METHOD_MODULE, JSR330_PROVIDER_METHOD_MODULE); |
| assertDuplicateBinding(JSR330_PROVIDER_METHOD_MODULE, GUICE_PROVIDER_METHOD_MODULE); |
| } |
| |
| public void testBindingDifferentTypesWithSameValueIsAnErrorMixed() { |
| assertDuplicateBinding(GUICE_BINDING_MODULE, JSR330_PROVIDER_METHOD_MODULE); |
| assertDuplicateBinding(JSR330_BINDING_MODULE, GUICE_PROVIDER_METHOD_MODULE); |
| } |
| |
| public void testMissingBindingForGuiceNamedUsesSameTypeInErrorMessage() { |
| assertMissingBindingErrorMessageUsesType(GuiceNamedClient.class); |
| } |
| |
| public void testMissingBindingForJsr330NamedUsesSameTypeInErrorMessage() { |
| assertMissingBindingErrorMessageUsesType(Jsr330NamedClient.class); |
| } |
| |
| public void testBindPropertiesWorksWithJsr330() { |
| assertInjectionsSucceed(new AbstractModule() { |
| @Override protected void configure() { |
| Properties properties = new Properties(); |
| properties.put("foo", "bar"); |
| Names.bindProperties(binder(), properties); |
| } |
| }); |
| } |
| |
| private static void assertMissingBindingErrorMessageUsesType(Class<?> clientType) { |
| try { |
| Guice.createInjector().getInstance(clientType); |
| fail("should have thrown ConfigurationException"); |
| } catch (ConfigurationException e) { |
| assertContains(e.getMessage(), |
| "No implementation for java.lang.String annotated with @com.google.inject.name.Named(value=foo) was bound."); |
| } |
| } |
| |
| private static void assertDuplicateBinding(Module... modules) { |
| try { |
| Guice.createInjector(modules); |
| fail("should have thrown CreationException"); |
| } catch (CreationException e) { |
| assertContains(e.getMessage(), |
| "A binding to java.lang.String annotated with @com.google.inject.name.Named(value=foo) was already configured"); |
| } |
| } |
| |
| private static Module moduleWithAnnotation(final Annotation annotation) { |
| return new AbstractModule() { |
| @Override protected void configure() { |
| bindConstant().annotatedWith(annotation).to("bar"); |
| } |
| }; |
| } |
| |
| private static void assertInjectionsSucceed(Module module) { |
| Injector injector = Guice.createInjector(module); |
| assertInjected(injector.getInstance(GuiceNamedClient.class), injector |
| .getInstance(Jsr330NamedClient.class)); |
| } |
| |
| private static void assertInjected(GuiceNamedClient guiceClient, Jsr330NamedClient jsr330Client) { |
| assertEquals("bar", guiceClient.foo); |
| assertEquals("bar", jsr330Client.foo); |
| } |
| |
| private static Module getJsr330BindingProviderMethodModule() { |
| return new AbstractModule() { |
| @Override protected void configure() {} |
| @SuppressWarnings("unused") @Provides @javax.inject.Named("foo") String provideFoo() { |
| return "bar"; |
| } |
| }; |
| } |
| |
| private static Module getGuiceBindingProviderMethodModule() { |
| return new AbstractModule() { |
| @Override protected void configure() {} |
| @SuppressWarnings("unused") @Provides @Named("foo") String provideFoo() { |
| return "bar"; |
| } |
| }; |
| } |
| |
| private static class GuiceNamedClient { |
| @Inject @Named("foo") String foo; |
| } |
| |
| private static class Jsr330NamedClient { |
| @Inject @javax.inject.Named("foo") String foo; |
| } |
| |
| private static class JsrNamed implements javax.inject.Named, Serializable { |
| private final String value; |
| |
| public JsrNamed(String value) { |
| this.value = value; |
| } |
| |
| public String value() { |
| return this.value; |
| } |
| |
| public int hashCode() { |
| // This is specified in java.lang.Annotation. |
| return (127 * "value".hashCode()) ^ value.hashCode(); |
| } |
| |
| public boolean equals(Object o) { |
| if (!(o instanceof javax.inject.Named)) { |
| return false; |
| } |
| |
| javax.inject.Named other = (javax.inject.Named) o; |
| return value.equals(other.value()); |
| } |
| |
| public String toString() { |
| return "@" + javax.inject.Named.class.getName() + "(value=" + value + ")"; |
| } |
| |
| public Class<? extends Annotation> annotationType() { |
| return javax.inject.Named.class; |
| } |
| |
| private static final long serialVersionUID = 0; |
| } |
| |
| private static class GuiceNamed implements com.google.inject.name.Named, Serializable { |
| private final String value; |
| |
| public GuiceNamed(String value) { |
| this.value = value; |
| } |
| |
| public String value() { |
| return this.value; |
| } |
| |
| public int hashCode() { |
| // This is specified in java.lang.Annotation. |
| return (127 * "value".hashCode()) ^ value.hashCode(); |
| } |
| |
| public boolean equals(Object o) { |
| if (!(o instanceof com.google.inject.name.Named)) { |
| return false; |
| } |
| |
| com.google.inject.name.Named other = (com.google.inject.name.Named) o; |
| return value.equals(other.value()); |
| } |
| |
| public String toString() { |
| return "@" + com.google.inject.name.Named.class.getName() + "(value=" + value + ")"; |
| } |
| |
| public Class<? extends Annotation> annotationType() { |
| return com.google.inject.name.Named.class; |
| } |
| |
| private static final long serialVersionUID = 0; |
| } |
| } |