/spice-inject/guice-patches/vanilla.test/com/google/inject/OverrideModuleTest.java
Java | 512 lines | 411 code | 80 blank | 21 comment | 0 complexity | cb42a5872fc3269e98cab7ebf4c39bcd MD5 | raw file
- /**
- * Copyright (C) 2008 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.Guice.createInjector;
- import static com.google.inject.name.Names.named;
- import com.google.inject.name.Named;
- import com.google.inject.util.Modules;
- import static java.lang.annotation.ElementType.TYPE;
- import java.lang.annotation.Retention;
- import static java.lang.annotation.RetentionPolicy.RUNTIME;
- import java.lang.annotation.Target;
- import java.util.Date;
- import java.util.concurrent.atomic.AtomicReference;
- import junit.framework.TestCase;
- /**
- * @author sberlin@gmail.com (Sam Berlin)
- */
- public class OverrideModuleTest extends TestCase {
- private static final Key<String> key2 = Key.get(String.class, named("2"));
- private static final Key<String> key3 = Key.get(String.class, named("3"));
- private static final Module EMPTY_MODULE = new Module() {
- public void configure(Binder binder) {}
- };
- public void testOverride() {
- Injector injector = createInjector(Modules.override(newModule("A")).with(newModule("B")));
- assertEquals("B", injector.getInstance(String.class));
- }
- public void testOverrideMultiple() {
- Module module = Modules.override(newModule("A"), newModule(1), newModule(0.5f))
- .with(newModule("B"), newModule(2), newModule(1.5d));
- Injector injector = createInjector(module);
- assertEquals("B", injector.getInstance(String.class));
- assertEquals(2, injector.getInstance(Integer.class).intValue());
- assertEquals(0.5f, injector.getInstance(Float.class));
- assertEquals(1.5d, injector.getInstance(Double.class));
- }
- public void testOverrideUnmatchedTolerated() {
- Injector injector = createInjector(Modules.override(EMPTY_MODULE).with(newModule("B")));
- assertEquals("B", injector.getInstance(String.class));
- }
- public void testOverrideConstant() {
- Module original = new AbstractModule() {
- @Override protected void configure() {
- bindConstant().annotatedWith(named("Test")).to("A");
- }
- };
- Module replacements = new AbstractModule() {
- @Override protected void configure() {
- bindConstant().annotatedWith(named("Test")).to("B");
- }
- };
- Injector injector = createInjector(Modules.override(original).with(replacements));
- assertEquals("B", injector.getInstance(Key.get(String.class, named("Test"))));
- }
- public void testGetProviderInModule() {
- Module original = new AbstractModule() {
- @Override protected void configure() {
- bind(String.class).toInstance("A");
- bind(key2).toProvider(getProvider(String.class));
- }
- };
- Injector injector = createInjector(Modules.override(original).with(EMPTY_MODULE));
- assertEquals("A", injector.getInstance(String.class));
- assertEquals("A", injector.getInstance(key2));
- }
- public void testOverrideWhatGetProviderProvided() {
- Module original = new AbstractModule() {
- @Override protected void configure() {
- bind(String.class).toInstance("A");
- bind(key2).toProvider(getProvider(String.class));
- }
- };
- Module replacements = newModule("B");
- Injector injector = createInjector(Modules.override(original).with(replacements));
- assertEquals("B", injector.getInstance(String.class));
- assertEquals("B", injector.getInstance(key2));
- }
- public void testOverrideUsingOriginalsGetProvider() {
- Module original = new AbstractModule() {
- @Override protected void configure() {
- bind(String.class).toInstance("A");
- bind(key2).toInstance("B");
- }
- };
- Module replacements = new AbstractModule() {
- @Override protected void configure() {
- bind(String.class).toProvider(getProvider(key2));
- }
- };
- Injector injector = createInjector(Modules.override(original).with(replacements));
- assertEquals("B", injector.getInstance(String.class));
- assertEquals("B", injector.getInstance(key2));
- }
- public void testOverrideOfOverride() {
- Module original = new AbstractModule() {
- @Override protected void configure() {
- bind(String.class).toInstance("A1");
- bind(key2).toInstance("A2");
- bind(key3).toInstance("A3");
- }
- };
- Module replacements1 = new AbstractModule() {
- @Override protected void configure() {
- bind(String.class).toInstance("B1");
- bind(key2).toInstance("B2");
- }
- };
- Module overrides = Modules.override(original).with(replacements1);
- Module replacements2 = new AbstractModule() {
- @Override protected void configure() {
- bind(String.class).toInstance("C1");
- bind(key3).toInstance("C3");
- }
- };
- Injector injector = createInjector(Modules.override(overrides).with(replacements2));
- assertEquals("C1", injector.getInstance(String.class));
- assertEquals("B2", injector.getInstance(key2));
- assertEquals("C3", injector.getInstance(key3));
- }
- public void testOverridesTwiceFails() {
- Module original = newModule("A");
- Module replacements = new AbstractModule() {
- @Override protected void configure() {
- bind(String.class).toInstance("B");
- bind(String.class).toInstance("C");
- }
- };
- Module module = Modules.override(original).with(replacements);
- try {
- createInjector(module);
- fail();
- } catch (CreationException expected) {
- assertContains(expected.getMessage(), "A binding to java.lang.String "
- + "was already configured at " + replacements.getClass().getName(),
- "at " + replacements.getClass().getName());
- }
- }
- public void testOverridesDoesntFixTwiceBoundInOriginal() {
- Module original = new AbstractModule() {
- @Override protected void configure() {
- bind(String.class).toInstance("A");
- bind(String.class).toInstance("B");
- }
- };
- Module replacements = new AbstractModule() {
- @Override protected void configure() {
- bind(String.class).toInstance("C");
- }
- };
- Module module = Modules.override(original).with(replacements);
- try {
- createInjector(module);
- fail();
- } catch (CreationException expected) {
- assertContains(expected.getMessage(), "1) A binding to java.lang.String "
- + "was already configured at " + replacements.getClass().getName(),
- "at " + original.getClass().getName());
- }
- }
- public void testStandardScopeAnnotation() {
- final SingleUseScope scope = new SingleUseScope();
- Module module = new AbstractModule() {
- protected void configure() {
- bindScope(TestScopeAnnotation.class, scope);
- bind(String.class).in(TestScopeAnnotation.class);
- }
- };
- assertFalse(scope.used);
- Guice.createInjector(module);
- assertTrue(scope.used);
- }
- public void testOverrideUntargettedBinding() {
- Module original = new AbstractModule() {
- @Override protected void configure() {
- bind(Date.class);
- }
- };
- Module replacements = new AbstractModule() {
- @Override protected void configure() {
- bind(Date.class).toInstance(new Date(0));
- }
- };
- Injector injector = createInjector(Modules.override(original).with(replacements));
- assertEquals(0, injector.getInstance(Date.class).getTime());
- }
- public void testOverrideScopeAnnotation() {
- final Scope scope = new Scope() {
- public <T> Provider<T> scope(Key<T> key, Provider<T> unscoped) {
- throw new AssertionError("Should not be called");
- }
- };
- final SingleUseScope replacementScope = new SingleUseScope();
- Module original = new AbstractModule() {
- @Override protected void configure() {
- bindScope(TestScopeAnnotation.class, scope);
- bind(Date.class).in(TestScopeAnnotation.class);
- }
- };
- Module replacements = new AbstractModule() {
- @Override protected void configure() {
- bindScope(TestScopeAnnotation.class, replacementScope);
- }
- };
- Injector injector = createInjector(Modules.override(original).with(replacements));
- injector.getInstance(Date.class);
- assertTrue(replacementScope.used);
- }
- public void testFailsIfOverridenScopeInstanceHasBeenUsed() {
- final Scope scope = new Scope() {
- public <T> Provider<T> scope(Key<T> key, Provider<T> unscoped) {
- return unscoped;
- }
- @Override public String toString() {
- return "ORIGINAL SCOPE";
- }
- };
- Module original = new AbstractModule() {
- @Override protected void configure() {
- bindScope(TestScopeAnnotation.class, scope);
- bind(Date.class).in(scope);
- }
- };
- Module replacements = new AbstractModule() {
- @Override protected void configure() {
- bindScope(TestScopeAnnotation.class, new SingleUseScope());
- }
- };
- try {
- createInjector(Modules.override(original).with(replacements));
- fail("Exception expected");
- } catch (CreationException e) {
- assertContains(e.getMessage(),
- "1) The scope for @TestScopeAnnotation is bound directly and cannot be overridden.",
- "at ", getClass().getName(), ".configure(");
- }
- }
- public void testOverrideIsLazy() {
- final AtomicReference<String> value = new AtomicReference<String>("A");
- Module overridden = Modules.override(new AbstractModule() {
- protected void configure() {
- bind(String.class).annotatedWith(named("original")).toInstance(value.get());
- }
- }).with(new AbstractModule() {
- protected void configure() {
- bind(String.class).annotatedWith(named("override")).toInstance(value.get());
- }
- });
- // the value.get() call should be deferred until Guice.createInjector
- value.set("B");
- Injector injector = Guice.createInjector(overridden);
- assertEquals("B", injector.getInstance(Key.get(String.class, named("original"))));
- assertEquals("B", injector.getInstance(Key.get(String.class, named("override"))));
- }
- public void testOverridePrivateModuleOverPrivateModule() {
- Module exposes5and6 = new AbstractModule() {
- protected void configure() {
- install(new PrivateModule() {
- protected void configure() {
- bind(Integer.class).toInstance(5);
- expose(Integer.class);
- bind(Character.class).toInstance('E');
- }
- });
- install(new PrivateModule() {
- protected void configure() {
- bind(Long.class).toInstance(6L);
- expose(Long.class);
- bind(Character.class).toInstance('F');
- }
- });
- }
- };
- AbstractModule exposes15 = new AbstractModule() {
- protected void configure() {
- install(new PrivateModule() {
- protected void configure() {
- bind(Integer.class).toInstance(15);
- expose(Integer.class);
- bind(Character.class).toInstance('G');
- }
- });
- install(new PrivateModule() {
- protected void configure() {
- bind(Character.class).toInstance('H');
- }
- });
- }
- };
- // override forwards
- Injector injector = Guice.createInjector(Modules.override(exposes5and6).with(exposes15));
- assertEquals(15, injector.getInstance(Integer.class).intValue());
- assertEquals(6L, injector.getInstance(Long.class).longValue());
- // and in reverse order
- Injector reverse = Guice.createInjector(Modules.override(exposes15).with(exposes5and6));
- assertEquals(5, reverse.getInstance(Integer.class).intValue());
- assertEquals(6L, reverse.getInstance(Long.class).longValue());
- }
- public void testOverrideModuleAndPrivateModule() {
- Module exposes5 = new PrivateModule() {
- protected void configure() {
- bind(Integer.class).toInstance(5);
- expose(Integer.class);
- }
- };
- Module binds15 = new AbstractModule() {
- protected void configure() {
- bind(Integer.class).toInstance(15);
- }
- };
- Injector injector = Guice.createInjector(Modules.override(exposes5).with(binds15));
- assertEquals(15, injector.getInstance(Integer.class).intValue());
- Injector reverse = Guice.createInjector(Modules.override(binds15).with(exposes5));
- assertEquals(5, reverse.getInstance(Integer.class).intValue());
- }
- public void testOverrideDeepExpose() {
- final AtomicReference<Provider<Character>> charAProvider
- = new AtomicReference<Provider<Character>>();
- Module exposes5 = new PrivateModule() {
- protected void configure() {
- install(new PrivateModule() {
- protected void configure() {
- bind(Integer.class).toInstance(5);
- expose(Integer.class);
- charAProvider.set(getProvider(Character.class));
- bind(Character.class).toInstance('A');
- }
- });
- expose(Integer.class);
- }
- };
- Injector injector = Guice.createInjector(Modules.override(exposes5).with(EMPTY_MODULE));
- assertEquals(5, injector.getInstance(Integer.class).intValue());
- assertEquals('A', charAProvider.getAndSet(null).get().charValue());
- injector = Guice.createInjector(Modules.override(EMPTY_MODULE).with(exposes5));
- assertEquals(5, injector.getInstance(Integer.class).intValue());
- assertEquals('A', charAProvider.getAndSet(null).get().charValue());
- final AtomicReference<Provider<Character>> charBProvider
- = new AtomicReference<Provider<Character>>();
- Module binds15 = new AbstractModule() {
- protected void configure() {
- bind(Integer.class).toInstance(15);
- install(new PrivateModule() {
- protected void configure() {
- charBProvider.set(getProvider(Character.class));
- bind(Character.class).toInstance('B');
- }
- });
- }
- };
- injector = Guice.createInjector(Modules.override(binds15).with(exposes5));
- assertEquals(5, injector.getInstance(Integer.class).intValue());
- assertEquals('A', charAProvider.getAndSet(null).get().charValue());
- assertEquals('B', charBProvider.getAndSet(null).get().charValue());
- injector = Guice.createInjector(Modules.override(exposes5).with(binds15));
- assertEquals(15, injector.getInstance(Integer.class).intValue());
- assertEquals('A', charAProvider.getAndSet(null).get().charValue());
- assertEquals('B', charBProvider.getAndSet(null).get().charValue());
- }
- @Retention(RUNTIME)
- @Target(TYPE)
- @ScopeAnnotation
- private static @interface TestScopeAnnotation {}
- private static class SingleUseScope implements Scope {
- boolean used = false;
- public <T> Provider<T> scope(Key<T> key, Provider<T> unscoped) {
- assertFalse(used);
- used = true;
- return unscoped;
- }
- }
- private static <T> Module newModule(final T bound) {
- return new AbstractModule() {
- @Override protected void configure() {
- @SuppressWarnings("unchecked")
- Class<T> type = (Class<T>) bound.getClass();
- bind(type).toInstance(bound);
- }
- };
- }
-
- private static final String RESULT = "RESULT";
- private static final String PRIVATE_INPUT = "PRIVATE_INPUT";
- private static final String OVERRIDDEN_INPUT = "FOO";
- private static final String OVERRIDDEN_RESULT = "Size: 3";
- private static final Key<String> RESULT_KEY = Key.get(String.class, named(RESULT));
- private static final Key<String> INPUT_KEY = Key.get(String.class, named(PRIVATE_INPUT));
- public void testExposedBindingOverride() throws Exception {
- Injector inj = Guice.createInjector(
- Modules.override(new ExampleModule()).with(
- new AbstractModule() {
- @Override protected void configure() {
- bind(RESULT_KEY).toInstance(OVERRIDDEN_RESULT);
- }
- }));
- assertEquals(inj.getInstance(RESULT_KEY), OVERRIDDEN_RESULT);
- }
- public void testPrivateBindingOverride() throws Exception {
- Injector inj = Guice.createInjector(
- Modules.override(new ExampleModule()).with(
- new AbstractModule() {
- @Override protected void configure() {
- bind(INPUT_KEY).toInstance(OVERRIDDEN_INPUT);
- }
- }));
- assertEquals(inj.getInstance(RESULT_KEY), OVERRIDDEN_RESULT);
- }
- public static class ExampleModule extends PrivateModule {
- @Provides @Exposed @Named(RESULT)
- public String provideResult(@Named(PRIVATE_INPUT) String input) {
- return "Size: " + input.length();
- }
- @Provides @Named(PRIVATE_INPUT)
- public String provideInput() {
- return "Hello World";
- }
- @Override protected void configure() {
- }
- }
- }