/spice-inject/guice-patches/vanilla.test/com/google/inject/DuplicateBindingsTest.java
Java | 422 lines | 314 code | 63 blank | 45 comment | 7 complexity | 546013187b2894750784adc79339c513 MD5 | raw file
- /**
- * 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;
- import static com.google.inject.Asserts.assertContains;
- import static com.google.inject.name.Names.named;
- import com.google.inject.internal.util.Lists;
- import java.lang.annotation.Annotation;
- import java.lang.reflect.Constructor;
- import java.util.Arrays;
- import java.util.Collection;
- import java.util.LinkedHashSet;
- import java.util.List;
- import java.util.logging.Logger;
- import junit.framework.TestCase;
- import com.google.inject.spi.Element;
- import com.google.inject.spi.Elements;
- import com.google.inject.util.Providers;
- /**
- * A suite of tests for duplicate bindings.
- *
- * @author sameb@google.com (Sam Berlin)
- */
- public class DuplicateBindingsTest extends TestCase {
-
- private FooImpl foo = new FooImpl();
- private Provider<Foo> pFoo = Providers.<Foo>of(new FooImpl());
- private Class<? extends Provider<? extends Foo>> pclFoo = FooProvider.class;
- private Class<? extends Foo> clFoo = FooImpl.class;
- private Constructor<FooImpl> cFoo = FooImpl.cxtor();
- public void testDuplicateBindingsAreIgnored() {
- Injector injector = Guice.createInjector(
- new SimpleModule(foo, pFoo, pclFoo, clFoo, cFoo),
- new SimpleModule(foo, pFoo, pclFoo, clFoo, cFoo)
- );
- List<Key<?>> bindings = Lists.newArrayList(injector.getAllBindings().keySet());
- removeBasicBindings(bindings);
-
- // Ensure only one binding existed for each type.
- assertTrue(bindings.remove(Key.get(Foo.class, named("instance"))));
- assertTrue(bindings.remove(Key.get(Foo.class, named("pInstance"))));
- assertTrue(bindings.remove(Key.get(Foo.class, named("pKey"))));
- assertTrue(bindings.remove(Key.get(Foo.class, named("linkedKey"))));
- assertTrue(bindings.remove(Key.get(FooImpl.class)));
- assertTrue(bindings.remove(Key.get(Foo.class, named("constructor"))));
- assertTrue(bindings.remove(Key.get(FooProvider.class))); // JIT binding
-
- assertEquals(bindings.toString(), 0, bindings.size());
- }
-
- public void testElementsDeduplicate() {
- List<Element> elements = Elements.getElements(
- new SimpleModule(foo, pFoo, pclFoo, clFoo, cFoo),
- new SimpleModule(foo, pFoo, pclFoo, clFoo, cFoo)
- );
- assertEquals(12, elements.size());
- assertEquals(6, new LinkedHashSet<Element>(elements).size());
- }
-
- public void testSameScopeInstanceIgnored() {
- Guice.createInjector(
- new ScopedModule(Scopes.SINGLETON, foo, pFoo, pclFoo, clFoo, cFoo),
- new ScopedModule(Scopes.SINGLETON, foo, pFoo, pclFoo, clFoo, cFoo)
- );
-
- Guice.createInjector(
- new ScopedModule(Scopes.NO_SCOPE, foo, pFoo, pclFoo, clFoo, cFoo),
- new ScopedModule(Scopes.NO_SCOPE, foo, pFoo, pclFoo, clFoo, cFoo)
- );
- }
-
- public void testSameScopeAnnotationIgnored() {
- Guice.createInjector(
- new AnnotatedScopeModule(Singleton.class, foo, pFoo, pclFoo, clFoo, cFoo),
- new AnnotatedScopeModule(Singleton.class, foo, pFoo, pclFoo, clFoo, cFoo)
- );
- }
-
- public void testMixedAnnotationAndScopeForSingletonIgnored() {
- Guice.createInjector(
- new ScopedModule(Scopes.SINGLETON, foo, pFoo, pclFoo, clFoo, cFoo),
- new AnnotatedScopeModule(Singleton.class, foo, pFoo, pclFoo, clFoo, cFoo)
- );
- }
-
- public void testMixedScopeAndUnscopedIgnored() {
- Guice.createInjector(
- new SimpleModule(foo, pFoo, pclFoo, clFoo, cFoo),
- new ScopedModule(Scopes.NO_SCOPE, foo, pFoo, pclFoo, clFoo, cFoo)
- );
- }
-
- public void testMixedScopeFails() {
- try {
- Guice.createInjector(
- new SimpleModule(foo, pFoo, pclFoo, clFoo, cFoo),
- new ScopedModule(Scopes.SINGLETON, foo, pFoo, pclFoo, clFoo, cFoo)
- );
- fail("expected exception");
- } catch(CreationException ce) {
- assertContains(ce.getMessage(),
- "A binding to " + Foo.class.getName() + " annotated with " + named("pInstance") + " was already configured at " + SimpleModule.class.getName(),
- "at " + ScopedModule.class.getName(),
- "A binding to " + Foo.class.getName() + " annotated with " + named("pKey") + " was already configured at " + SimpleModule.class.getName(),
- "at " + ScopedModule.class.getName(),
- "A binding to " + Foo.class.getName() + " annotated with " + named("linkedKey") + " was already configured at " + SimpleModule.class.getName(),
- "at " + ScopedModule.class.getName(),
- "A binding to " + FooImpl.class.getName() + " was already configured at " + SimpleModule.class.getName(),
- "at " + ScopedModule.class.getName(),
- "A binding to " + Foo.class.getName() + " annotated with " + named("constructor") + " was already configured at " + SimpleModule.class.getName(),
- "at " + ScopedModule.class.getName());
- }
- }
-
- @SuppressWarnings("unchecked")
- public void testMixedTargetsFails() {
- try {
- Guice.createInjector(
- new SimpleModule(foo, pFoo, pclFoo, clFoo, cFoo),
- new SimpleModule(new FooImpl(), Providers.<Foo>of(new FooImpl()),
- (Class)BarProvider.class, (Class)Bar.class, (Constructor)Bar.cxtor())
- );
- fail("expected exception");
- } catch(CreationException ce) {
- assertContains(ce.getMessage(),
- "A binding to " + Foo.class.getName() + " annotated with " + named("pInstance") + " was already configured at " + SimpleModule.class.getName(),
- "at " + SimpleModule.class.getName(),
- "A binding to " + Foo.class.getName() + " annotated with " + named("pKey") + " was already configured at " + SimpleModule.class.getName(),
- "at " + SimpleModule.class.getName(),
- "A binding to " + Foo.class.getName() + " annotated with " + named("linkedKey") + " was already configured at " + SimpleModule.class.getName(),
- "at " + SimpleModule.class.getName(),
- "A binding to " + Foo.class.getName() + " annotated with " + named("constructor") + " was already configured at " + SimpleModule.class.getName(),
- "at " + SimpleModule.class.getName());
- }
- }
-
- public void testExceptionInEqualsThrowsCreationException() {
- try {
- Guice.createInjector(new ThrowingModule(), new ThrowingModule());
- fail("expected exception");
- } catch(CreationException ce) {
- assertContains(ce.getMessage(),
- "A binding to " + Foo.class.getName() + " was already configured at " + ThrowingModule.class.getName(),
- "and an error was thrown while checking duplicate bindings. Error: java.lang.RuntimeException: Boo!",
- "at " + ThrowingModule.class.getName());
- }
- }
-
- public void testChildInjectorDuplicateParentFail() {
- Injector injector = Guice.createInjector(
- new SimpleModule(foo, pFoo, pclFoo, clFoo, cFoo)
- );
-
- try {
- injector.createChildInjector(
- new SimpleModule(foo, pFoo, pclFoo, clFoo, cFoo)
- );
- fail("expected exception");
- } catch(CreationException ce) {
- assertContains(ce.getMessage(),
- "A binding to " + Foo.class.getName() + " annotated with " + named("pInstance") + " was already configured at " + SimpleModule.class.getName(),
- "at " + SimpleModule.class.getName(),
- "A binding to " + Foo.class.getName() + " annotated with " + named("pKey") + " was already configured at " + SimpleModule.class.getName(),
- "at " + SimpleModule.class.getName(),
- "A binding to " + Foo.class.getName() + " annotated with " + named("linkedKey") + " was already configured at " + SimpleModule.class.getName(),
- "at " + SimpleModule.class.getName(),
- "A binding to " + Foo.class.getName() + " annotated with " + named("constructor") + " was already configured at " + SimpleModule.class.getName(),
- "at " + SimpleModule.class.getName());
- }
- }
-
- public void testDuplicatesSolelyInChildIgnored() {
- Injector injector = Guice.createInjector();
- injector.createChildInjector(
- new SimpleModule(foo, pFoo, pclFoo, clFoo, cFoo),
- new SimpleModule(foo, pFoo, pclFoo, clFoo, cFoo)
- );
- }
-
- public void testDifferentBindingTypesFail() {
- List<Element> elements = Elements.getElements(
- new FailedModule(foo, pFoo, pclFoo, clFoo, cFoo)
- );
-
- // Make sure every combination of the elements with another element fails.
- // This ensures that duplication checks the kind of binding also.
- for(Element e1 : elements) {
- for(Element e2: elements) {
- // if they're the same, this shouldn't fail.
- try {
- Guice.createInjector(Elements.getModule(Arrays.asList(e1, e2)));
- if(e1 != e2) {
- fail("must fail!");
- }
- } catch(CreationException expected) {
- if(e1 != e2) {
- assertContains(expected.getMessage(),
- "A binding to " + Foo.class.getName() + " was already configured at " + FailedModule.class.getName(),
- "at " + FailedModule.class.getName());
- } else {
- throw expected;
- }
- }
- }
- }
- }
-
- public void testJitBindingsAreCheckedAfterConversions() {
- Guice.createInjector(new AbstractModule() {
- @Override
- protected void configure() {
- bind(A.class);
- bind(A.class).to(RealA.class);
- }
- });
- }
-
- private static class RealA extends A {}
- @ImplementedBy(RealA.class) private static class A {}
-
- private void removeBasicBindings(Collection<Key<?>> bindings) {
- bindings.remove(Key.get(Injector.class));
- bindings.remove(Key.get(Logger.class));
- bindings.remove(Key.get(Stage.class));
- }
-
- private static class ThrowingModule extends AbstractModule {
- @Override
- protected void configure() {
- bind(Foo.class).toInstance(new Foo() {
- @Override
- public boolean equals(Object obj) {
- throw new RuntimeException("Boo!");
- }
- });
- }
- }
-
- private static abstract class FooModule extends AbstractModule {
- protected final FooImpl foo;
- protected final Provider<Foo> pFoo;
- protected final Class<? extends Provider<? extends Foo>> pclFoo;
- protected final Class<? extends Foo> clFoo;
- protected final Constructor<FooImpl> cFoo;
-
- FooModule(FooImpl foo, Provider<Foo> pFoo, Class<? extends Provider<? extends Foo>> pclFoo,
- Class<? extends Foo> clFoo, Constructor<FooImpl> cFoo) {
- this.foo = foo;
- this.pFoo = pFoo;
- this.pclFoo = pclFoo;
- this.clFoo = clFoo;
- this.cFoo = cFoo;
- }
- }
-
- private static class FailedModule extends FooModule {
- FailedModule(FooImpl foo, Provider<Foo> pFoo, Class<? extends Provider<? extends Foo>> pclFoo,
- Class<? extends Foo> clFoo, Constructor<FooImpl> cFoo) {
- super(foo, pFoo, pclFoo, clFoo, cFoo);
- }
-
- protected void configure() {
- // InstanceBinding
- bind(Foo.class).toInstance(foo);
-
- // ProviderInstanceBinding
- bind(Foo.class).toProvider(pFoo);
-
- // ProviderKeyBinding
- bind(Foo.class).toProvider(pclFoo);
-
- // LinkedKeyBinding
- bind(Foo.class).to(clFoo);
-
- // ConstructorBinding
- bind(Foo.class).toConstructor(cFoo);
- }
- }
-
- private static class SimpleModule extends FooModule {
- SimpleModule(FooImpl foo, Provider<Foo> pFoo, Class<? extends Provider<? extends Foo>> pclFoo,
- Class<? extends Foo> clFoo, Constructor<FooImpl> cFoo) {
- super(foo, pFoo, pclFoo, clFoo, cFoo);
- }
-
- protected void configure() {
- // InstanceBinding
- bind(Foo.class).annotatedWith(named("instance")).toInstance(foo);
-
- // ProviderInstanceBinding
- bind(Foo.class).annotatedWith(named("pInstance")).toProvider(pFoo);
-
- // ProviderKeyBinding
- bind(Foo.class).annotatedWith(named("pKey")).toProvider(pclFoo);
-
- // LinkedKeyBinding
- bind(Foo.class).annotatedWith(named("linkedKey")).to(clFoo);
-
- // UntargettedBinding / ConstructorBinding
- bind(FooImpl.class);
-
- // ConstructorBinding
- bind(Foo.class).annotatedWith(named("constructor")).toConstructor(cFoo);
- }
- }
-
- private static class ScopedModule extends FooModule {
- private final Scope scope;
- ScopedModule(Scope scope, FooImpl foo, Provider<Foo> pFoo,
- Class<? extends Provider<? extends Foo>> pclFoo, Class<? extends Foo> clFoo,
- Constructor<FooImpl> cFoo) {
- super(foo, pFoo, pclFoo, clFoo, cFoo);
- this.scope = scope;
- }
-
- protected void configure() {
- // ProviderInstanceBinding
- bind(Foo.class).annotatedWith(named("pInstance")).toProvider(pFoo).in(scope);
-
- // ProviderKeyBinding
- bind(Foo.class).annotatedWith(named("pKey")).toProvider(pclFoo).in(scope);
-
- // LinkedKeyBinding
- bind(Foo.class).annotatedWith(named("linkedKey")).to(clFoo).in(scope);
-
- // UntargettedBinding / ConstructorBinding
- bind(FooImpl.class).in(scope);
-
- // ConstructorBinding
- bind(Foo.class).annotatedWith(named("constructor")).toConstructor(cFoo).in(scope);
- }
- }
-
- private static class AnnotatedScopeModule extends FooModule {
- private final Class<? extends Annotation> scope;
- AnnotatedScopeModule(Class<? extends Annotation> scope, FooImpl foo, Provider<Foo> pFoo,
- Class<? extends Provider<? extends Foo>> pclFoo, Class<? extends Foo> clFoo,
- Constructor<FooImpl> cFoo) {
- super(foo, pFoo, pclFoo, clFoo, cFoo);
- this.scope = scope;
- }
-
-
- protected void configure() {
- // ProviderInstanceBinding
- bind(Foo.class).annotatedWith(named("pInstance")).toProvider(pFoo).in(scope);
-
- // ProviderKeyBinding
- bind(Foo.class).annotatedWith(named("pKey")).toProvider(pclFoo).in(scope);
-
- // LinkedKeyBinding
- bind(Foo.class).annotatedWith(named("linkedKey")).to(clFoo).in(scope);
-
- // UntargettedBinding / ConstructorBinding
- bind(FooImpl.class).in(scope);
-
- // ConstructorBinding
- bind(Foo.class).annotatedWith(named("constructor")).toConstructor(cFoo).in(scope);
- }
- }
-
- private static interface Foo {}
- private static class FooImpl implements Foo {
- @Inject public FooImpl() {}
-
- private static Constructor<FooImpl> cxtor() {
- try {
- return FooImpl.class.getConstructor();
- } catch (SecurityException e) {
- throw new RuntimeException(e);
- } catch (NoSuchMethodException e) {
- throw new RuntimeException(e);
- }
- }
- }
- private static class FooProvider implements Provider<Foo> {
- public Foo get() {
- return new FooImpl();
- }
- }
-
- private static class Bar implements Foo {
- @Inject public Bar() {}
-
- private static Constructor<Bar> cxtor() {
- try {
- return Bar.class.getConstructor();
- } catch (SecurityException e) {
- throw new RuntimeException(e);
- } catch (NoSuchMethodException e) {
- throw new RuntimeException(e);
- }
- }
- }
- private static class BarProvider implements Provider<Foo> {
- public Foo get() {
- return new Bar();
- }
- }
-
- }