/core/test/com/google/inject/ProvisionListenerTest.java
Java | 796 lines | 673 code | 79 blank | 44 comment | 8 complexity | ab80c13d5a88bd93394caed7d2a97d26 MD5 | raw file
- /**
- * Copyright (C) 2011 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.common.collect.ImmutableList.of;
- import static com.google.inject.Asserts.assertContains;
- import static com.google.inject.name.Names.named;
- import com.google.common.collect.ImmutableList;
- import com.google.common.collect.ImmutableSet;
- import com.google.common.collect.Lists;
- import com.google.inject.matcher.AbstractMatcher;
- import com.google.inject.matcher.Matcher;
- import com.google.inject.matcher.Matchers;
- import com.google.inject.name.Named;
- import com.google.inject.spi.DependencyAndSource;
- import com.google.inject.spi.InstanceBinding;
- import com.google.inject.spi.ProvisionListener;
- import com.google.inject.util.Providers;
- import junit.framework.TestCase;
- import java.util.List;
- import java.util.Set;
- import java.util.concurrent.atomic.AtomicBoolean;
- import java.util.concurrent.atomic.AtomicInteger;
- import java.util.concurrent.atomic.AtomicReference;
- /**
- * Tests for {@link Binder#bindListener(Matcher, ProvisionListener...)}
- *
- * @author sameb@google.com (Sam Berlin)
- */
- // TODO(sameb): Add some tests for private modules & child injectors.
- public class ProvisionListenerTest extends TestCase {
- public void testExceptionInListenerBeforeProvisioning() {
- Injector injector = Guice.createInjector(new AbstractModule() {
- @Override
- protected void configure() {
- bindListener(Matchers.any(), new FailBeforeProvision());
- }
- });
- try {
- injector.getInstance(Foo.class);
- fail();
- } catch(ProvisionException pe) {
- assertEquals(1, pe.getErrorMessages().size());
- assertContains(pe.getMessage(),
- "1) Error notifying ProvisionListener " + FailBeforeProvision.class.getName()
- + " of " + Foo.class.getName(),
- "Reason: java.lang.RuntimeException: boo",
- "while locating " + Foo.class.getName());
- assertEquals("boo", pe.getCause().getMessage());
- }
- }
-
- public void testExceptionInListenerAfterProvisioning() {
- Injector injector = Guice.createInjector(new AbstractModule() {
- @Override
- protected void configure() {
- bindListener(Matchers.any(), new FailAfterProvision());
- }
- });
- try {
- injector.getInstance(Foo.class);
- fail();
- } catch(ProvisionException pe) {
- assertEquals(1, pe.getErrorMessages().size());
- assertContains(pe.getMessage(),
- "1) Error notifying ProvisionListener " + FailAfterProvision.class.getName()
- + " of " + Foo.class.getName(),
- "Reason: java.lang.RuntimeException: boo",
- "while locating " + Foo.class.getName());
- assertEquals("boo", pe.getCause().getMessage());
- }
- }
-
- public void testExceptionInProvisionExplicitlyCalled() {
- Injector injector = Guice.createInjector(new AbstractModule() {
- @Override
- protected void configure() {
- bindListener(Matchers.any(), new JustProvision());
- }
- });
- try {
- injector.getInstance(FooBomb.class);
- fail();
- } catch(ProvisionException pe) {
- assertEquals(1, pe.getErrorMessages().size());
- assertContains(pe.getMessage(),
- "1) Error injecting constructor, java.lang.RuntimeException: Retry, Abort, Fail",
- " at " + FooBomb.class.getName(),
- " while locating " + FooBomb.class.getName());
- assertEquals("Retry, Abort, Fail", pe.getCause().getMessage());
- }
- }
-
- public void testExceptionInProvisionAutomaticallyCalled() {
- Injector injector = Guice.createInjector(new AbstractModule() {
- @Override
- protected void configure() {
- bindListener(Matchers.any(), new NoProvision());
- }
- });
- try {
- injector.getInstance(FooBomb.class);
- fail();
- } catch(ProvisionException pe) {
- assertEquals(1, pe.getErrorMessages().size());
- assertContains(pe.getMessage(),
- "1) Error injecting constructor, java.lang.RuntimeException: Retry, Abort, Fail",
- " at " + FooBomb.class.getName(),
- " while locating " + FooBomb.class.getName());
- assertEquals("Retry, Abort, Fail", pe.getCause().getMessage());
- }
- }
-
- public void testExceptionInFieldProvision() throws Exception {
- final CountAndCaptureExceptionListener listener = new CountAndCaptureExceptionListener();
- Injector injector = Guice.createInjector(new AbstractModule() {
- @Override protected void configure() {
- bindListener(new AbstractMatcher<Binding<?>>() {
- @Override public boolean matches(Binding<?> binding) {
- return binding.getKey().getRawType().equals(DependsOnFooBombInField.class);
- }
- }, listener);
- }
- });
- assertEquals(0, listener.beforeProvision);
- String expectedMsg = null;
- try {
- injector.getInstance(DependsOnFooBombInField.class);
- fail();
- } catch (ProvisionException expected) {
- assertEquals(1, expected.getErrorMessages().size());
- expectedMsg = expected.getMessage();
- assertContains(listener.capture.get().getMessage(),
- "1) Error injecting constructor, java.lang.RuntimeException: Retry, Abort, Fail",
- " at " + FooBomb.class.getName(),
- " while locating " + FooBomb.class.getName(),
- " while locating " + DependsOnFooBombInField.class.getName());
- }
- assertEquals(1, listener.beforeProvision);
- assertEquals(expectedMsg, listener.capture.get().getMessage());
- assertEquals(0, listener.afterProvision);
- }
-
- public void testExceptionInCxtorProvision() throws Exception {
- final CountAndCaptureExceptionListener listener = new CountAndCaptureExceptionListener();
- Injector injector = Guice.createInjector(new AbstractModule() {
- @Override protected void configure() {
- bindListener(new AbstractMatcher<Binding<?>>() {
- @Override public boolean matches(Binding<?> binding) {
- return binding.getKey().getRawType().equals(DependsOnFooBombInCxtor.class);
- }
- }, listener);
- }
- });
- assertEquals(0, listener.beforeProvision);
- String expectedMsg = null;
- try {
- injector.getInstance(DependsOnFooBombInCxtor.class);
- fail();
- } catch (ProvisionException expected) {
- assertEquals(1, expected.getErrorMessages().size());
- expectedMsg = expected.getMessage();
- assertContains(listener.capture.get().getMessage(),
- "1) Error injecting constructor, java.lang.RuntimeException: Retry, Abort, Fail",
- " at " + FooBomb.class.getName(),
- " while locating " + FooBomb.class.getName(),
- " while locating " + DependsOnFooBombInCxtor.class.getName());
- }
- assertEquals(1, listener.beforeProvision);
- assertEquals(expectedMsg, listener.capture.get().getMessage());
- assertEquals(0, listener.afterProvision);
- }
- public void testListenerCallsProvisionTwice() {
- Injector injector = Guice.createInjector(new AbstractModule() {
- @Override
- protected void configure() {
- bindListener(Matchers.any(), new ProvisionTwice());
- }
- });
- try {
- injector.getInstance(Foo.class);
- fail();
- } catch(ProvisionException pe) {
- assertEquals(1, pe.getErrorMessages().size());
- assertContains(pe.getMessage(),
- "1) Error notifying ProvisionListener " + ProvisionTwice.class.getName()
- + " of " + Foo.class.getName(),
- "Reason: java.lang.IllegalStateException: Already provisioned in this listener.",
- "while locating " + Foo.class.getName());
- assertEquals("Already provisioned in this listener.", pe.getCause().getMessage());
- }
- }
-
- public void testCachedInScopePreventsProvisionNotify() {
- final Counter count1 = new Counter();
- Injector injector = Guice.createInjector(new AbstractModule() {
- @Override
- protected void configure() {
- bindListener(Matchers.any(), count1);
- bind(Foo.class).in(Scopes.SINGLETON);
- }
- });
- Foo foo = injector.getInstance(Foo.class);
- assertNotNull(foo);
- assertEquals(1, count1.count);
-
- // not notified the second time because nothing is provisioned
- // (it's cached in the scope)
- count1.count = 0;
- assertSame(foo, injector.getInstance(Foo.class));
- assertEquals(0, count1.count);
- }
-
- public void testCombineAllBindListenerCalls() {
- final Counter count1 = new Counter();
- final Counter count2 = new Counter();
- Injector injector = Guice.createInjector(new AbstractModule() {
- @Override
- protected void configure() {
- bindListener(Matchers.any(), count1);
- bindListener(Matchers.any(), count2);
- }
- });
- assertNotNull(injector.getInstance(Foo.class));
- assertEquals(1, count1.count);
- assertEquals(1, count2.count);
- }
-
- public void testNotifyEarlyListenersIfFailBeforeProvision() {
- final Counter count1 = new Counter();
- final Counter count2 = new Counter();
- Injector injector = Guice.createInjector(new AbstractModule() {
- @Override
- protected void configure() {
- bindListener(Matchers.any(), count1, new FailBeforeProvision(), count2);
- }
- });
- try {
- injector.getInstance(Foo.class);
- fail();
- } catch(ProvisionException pe) {
- assertEquals(1, pe.getErrorMessages().size());
- assertContains(pe.getMessage(),
- "1) Error notifying ProvisionListener " + FailBeforeProvision.class.getName()
- + " of " + Foo.class.getName(),
- "Reason: java.lang.RuntimeException: boo",
- "while locating " + Foo.class.getName());
- assertEquals("boo", pe.getCause().getMessage());
-
- assertEquals(1, count1.count);
- assertEquals(0, count2.count);
- }
- }
-
- public void testNotifyLaterListenersIfFailAfterProvision() {
- final Counter count1 = new Counter();
- final Counter count2 = new Counter();
- Injector injector = Guice.createInjector(new AbstractModule() {
- @Override
- protected void configure() {
- bindListener(Matchers.any(), count1, new FailAfterProvision(), count2);
- }
- });
- try {
- injector.getInstance(Foo.class);
- fail();
- } catch(ProvisionException pe) {
- assertEquals(1, pe.getErrorMessages().size());
- assertContains(pe.getMessage(),
- "1) Error notifying ProvisionListener " + FailAfterProvision.class.getName()
- + " of " + Foo.class.getName(),
- "Reason: java.lang.RuntimeException: boo",
- "while locating " + Foo.class.getName());
- assertEquals("boo", pe.getCause().getMessage());
-
- assertEquals(1, count1.count);
- assertEquals(1, count2.count);
- }
- }
-
- public void testNotifiedKeysOfAllBindTypes() {
- final Capturer capturer = new Capturer();
- Injector injector = Guice.createInjector(new AbstractModule() {
- @Override
- protected void configure() {
- bindListener(Matchers.any(), capturer);
- bind(Foo.class).annotatedWith(named("pk")).toProvider(FooP.class);
- try {
- bind(Foo.class).annotatedWith(named("cxtr")).toConstructor(Foo.class.getDeclaredConstructor());
- } catch (Exception ex) {
- throw new RuntimeException(ex);
- }
- bind(LinkedFoo.class).to(Foo.class);
- bind(Interface.class).toInstance(new Implementation());
- bindConstant().annotatedWith(named("constant")).to("MyConstant");
- }
-
- @Provides @Named("pi") Foo provideFooBar() {
- return new Foo();
- }
- });
-
- // toInstance & constant bindings are notified in random order, at the very beginning.
- assertEquals(
- ImmutableSet.of(Key.get(Interface.class), Key.get(String.class, named("constant"))),
- capturer.getAsSetAndClear());
-
- // simple binding
- assertNotNull(injector.getInstance(Foo.class));
- assertEquals(of(Key.get(Foo.class)), capturer.getAndClear());
-
- // provider key binding -- notifies about provider & the object, always
- assertNotNull(injector.getInstance(Key.get(Foo.class, named("pk"))));
- assertEquals(of(Key.get(FooP.class), Key.get(Foo.class, named("pk"))), capturer.getAndClear());
- assertNotNull(injector.getInstance(Key.get(Foo.class, named("pk"))));
- assertEquals(of(Key.get(FooP.class), Key.get(Foo.class, named("pk"))), capturer.getAndClear());
-
- // JIT provider key binding -- notifies about provider & the object, always
- assertNotNull(injector.getInstance(JitFoo2.class));
- assertEquals(of(Key.get(JitFoo2P.class), Key.get(JitFoo2.class)), capturer.getAndClear());
- assertNotNull(injector.getInstance(JitFoo2.class));
- assertEquals(of(Key.get(JitFoo2P.class), Key.get(JitFoo2.class)), capturer.getAndClear());
-
- // provider instance binding -- just the object (not the provider)
- assertNotNull(injector.getInstance(Key.get(Foo.class, named("pi"))));
- assertEquals(of(Key.get(Foo.class, named("pi"))), capturer.getAndClear());
-
- // toConstructor binding
- assertNotNull(injector.getInstance(Key.get(Foo.class, named("cxtr"))));
- assertEquals(of(Key.get(Foo.class, named("cxtr"))), capturer.getAndClear());
-
- // linked binding -- notifies about the target (that's what's provisioned), not the link
- assertNotNull(injector.getInstance(LinkedFoo.class));
- assertEquals(of(Key.get(Foo.class)), capturer.getAndClear());
- // JIT linked binding -- notifies about the target (that's what's provisioned), not the link
- assertNotNull(injector.getInstance(JitFoo.class));
- assertEquals(of(Key.get(Foo.class)), capturer.getAndClear());
- }
-
- public void testSingletonMatcher() {
- final Counter counter = new Counter();
- Injector injector = Guice.createInjector(new AbstractModule() {
- @Override
- protected void configure() {
- bindListener(new AbstractMatcher<Binding<?>>() {
- @Override
- public boolean matches(Binding<?> t) {
- return Scopes.isSingleton(t);
- }
- }, counter);
- }
- });
- assertEquals(0, counter.count);
- // no increment for getting Many.
- injector.getInstance(Many.class);
- assertEquals(0, counter.count);
- // but an increment for getting Sole, since it's a singleton.
- injector.getInstance(Sole.class);
- assertEquals(1, counter.count);
- }
-
- public void testCallingBindingDotGetProviderDotGet() {
- Injector injector = Guice.createInjector(new AbstractModule() {
- @Override
- protected void configure() {
- bindListener(Matchers.any(), new ProvisionListener() {
- @Override
- public <T> void onProvision(ProvisionInvocation<T> provision) {
- provision.getBinding().getProvider().get(); // AGH!
- }
- });
- }
- });
-
- try {
- injector.getInstance(Sole.class);
- fail();
- } catch(ProvisionException expected) {
- // We don't really care what kind of error you get, we only care you get an error.
- }
-
- try {
- injector.getInstance(Many.class);
- fail();
- } catch(ProvisionException expected) {
- // We don't really care what kind of error you get, we only care you get an error.
- }
- }
-
- interface Interface {}
- class Implementation implements Interface {}
-
- @Singleton static class Sole {}
- static class Many {}
-
- @ImplementedBy(Foo.class) static interface JitFoo {}
- @ProvidedBy(JitFoo2P.class) static class JitFoo2 {}
- static interface LinkedFoo {}
- static class Foo implements JitFoo, LinkedFoo {}
- static class FooP implements Provider<Foo> {
- public Foo get() {
- return new Foo();
- }
- }
- static class JitFoo2P implements Provider<JitFoo2> {
- public JitFoo2 get() {
- return new JitFoo2();
- }
- }
-
- static class FooBomb {
- FooBomb() {
- throw new RuntimeException("Retry, Abort, Fail");
- }
- }
-
- static class DependsOnFooBombInField {
- @Inject FooBomb fooBomb;
- }
-
- static class DependsOnFooBombInCxtor {
- @Inject DependsOnFooBombInCxtor(FooBomb fooBomb) {}
- }
-
- private static class Counter implements ProvisionListener {
- int count = 0;
- public <T> void onProvision(ProvisionInvocation<T> provision) {
- count++;
- }
- }
-
- private static class CountAndCaptureExceptionListener implements ProvisionListener {
- int beforeProvision = 0;
- int afterProvision = 0;
- AtomicReference<RuntimeException> capture = new AtomicReference<RuntimeException>();
- public <T> void onProvision(ProvisionInvocation<T> provision) {
- beforeProvision++;
- try {
- provision.provision();
- } catch (RuntimeException re) {
- capture.set(re);
- throw re;
- }
- afterProvision++;
- }
- }
-
- private static class Capturer implements ProvisionListener {
- List<Key> keys = Lists.newArrayList();
- public <T> void onProvision(ProvisionInvocation<T> provision) {
- keys.add(provision.getBinding().getKey());
- T provisioned = provision.provision();
- // InstanceBindings are the only kind of binding where the key can
- // be an instanceof the provisioned, because it isn't linked to any
- // direct implementation. I guess maybe it'd also be possible
- // with a toConstructor binding... but we don't use that in our tests.
- if (provision.getBinding() instanceof InstanceBinding) {
- Class<? super T> expected = provision.getBinding().getKey().getRawType();
- assertTrue("expected instanceof: " + expected + ", but was: " + provisioned,
- expected.isInstance(provisioned));
- } else {
- assertEquals(provision.getBinding().getKey().getRawType(), provisioned.getClass());
- }
- }
-
- Set<Key> getAsSetAndClear() {
- Set<Key> copy = ImmutableSet.copyOf(keys);
- keys.clear();
- return copy;
- }
-
- List<Key> getAndClear() {
- List<Key> copy = ImmutableList.copyOf(keys);
- keys.clear();
- return copy;
- }
- }
- private static class FailBeforeProvision implements ProvisionListener {
- public <T> void onProvision(ProvisionInvocation<T> provision) {
- throw new RuntimeException("boo");
- }
- }
- private static class FailAfterProvision implements ProvisionListener {
- public <T> void onProvision(ProvisionInvocation<T> provision) {
- provision.provision();
- throw new RuntimeException("boo");
- }
- }
- private static class JustProvision implements ProvisionListener {
- public <T> void onProvision(ProvisionInvocation<T> provision) {
- provision.provision();
- }
- }
- private static class NoProvision implements ProvisionListener {
- public <T> void onProvision(ProvisionInvocation<T> provision) {
- }
- }
- private static class ProvisionTwice implements ProvisionListener {
- public <T> void onProvision(ProvisionInvocation<T> provision) {
- provision.provision();
- provision.provision();
- }
- }
-
- private static class ChainAsserter implements ProvisionListener {
- private final List<Class<?>> provisionList;
- private final List<Class<?>> expected;
-
- public ChainAsserter(List<Class<?>> provisionList, Iterable<Class<?>> expected) {
- this.provisionList = provisionList;
- this.expected = ImmutableList.copyOf(expected);
- }
-
- public <T> void onProvision(ProvisionInvocation<T> provision) {
- List<Class<?>> actual = Lists.newArrayList();
- for (DependencyAndSource dep : provision.getDependencyChain()) {
- actual.add(dep.getDependency().getKey().getRawType());
- }
- assertEquals(expected, actual);
- provisionList.add(provision.getBinding().getKey().getRawType());
- }
- }
-
- private static Matcher<Binding<?>> keyMatcher(final Class<?> clazz) {
- return new AbstractMatcher<Binding<?>>() {
- @Override
- public boolean matches(Binding<?> t) {
- return t.getKey().equals(Key.get(clazz));
- }
- };
- }
-
- @SuppressWarnings("unchecked")
- public void testDependencyChain() {
- final List<Class<?>> pList = Lists.newArrayList();
- final List<Class<?>> totalList = Lists.newArrayList();
- Injector injector = Guice.createInjector(new AbstractModule() {
- @Override
- protected void configure() {
- bind(Instance.class).toInstance(new Instance());
- bind(B.class).to(BImpl.class);
- bind(D.class).toProvider(DP.class);
-
- bindListener(Matchers.any(), new ProvisionListener() {
- public <T> void onProvision(ProvisionInvocation<T> provision) {
- totalList.add(provision.getBinding().getKey().getRawType());
- }
- });
-
- // Build up a list of asserters for our dependency chains.
- ImmutableList.Builder<Class<?>> chain = ImmutableList.builder();
- chain.add(Instance.class);
- bindListener(keyMatcher(Instance.class), new ChainAsserter(pList, chain.build()));
-
- chain.add(A.class);
- bindListener(keyMatcher(A.class), new ChainAsserter(pList, chain.build()));
-
- chain.add(B.class).add(BImpl.class);
- bindListener(keyMatcher(BImpl.class), new ChainAsserter(pList, chain.build()));
-
- chain.add(C.class);
- bindListener(keyMatcher(C.class), new ChainAsserter(pList, chain.build()));
-
- // the chain has D before DP even though DP is provisioned & notified first
- // because we do DP because of D, and need DP to provision D.
- chain.add(D.class).add(DP.class);
- bindListener(keyMatcher(D.class), new ChainAsserter(pList, chain.build()));
- bindListener(keyMatcher(DP.class), new ChainAsserter(pList, chain.build()));
-
- chain.add(E.class);
- bindListener(keyMatcher(E.class), new ChainAsserter(pList, chain.build()));
-
- chain.add(F.class);
- bindListener(keyMatcher(F.class), new ChainAsserter(pList, chain.build()));
- }
- @Provides C c(D d) {
- return new C() {};
- }
- });
- Instance instance = injector.getInstance(Instance.class);
- // make sure we're checking all of the chain asserters..
- assertEquals(
- of(Instance.class, A.class, BImpl.class, C.class, DP.class, D.class, E.class, F.class),
- pList);
- // and make sure that nothing else was notified that we didn't expect.
- assertEquals(totalList, pList);
- }
-
- public void testModuleRequestInjection() {
- final AtomicBoolean notified = new AtomicBoolean();
- Guice.createInjector(new AbstractModule() {
- @Override
- protected void configure() {
- requestInjection(new Object() {
- @Inject Foo foo;
- });
- bindListener(Matchers.any(),
- new SpecialChecker(Foo.class, getClass().getName() + ".configure(", notified));
- }
- });
- assertTrue(notified.get());
- }
-
- public void testToProviderInstance() {
- final AtomicBoolean notified = new AtomicBoolean();
- Guice.createInjector(new AbstractModule() {
- @Override
- protected void configure() {
- bind(Object.class).toProvider(new Provider<Object>() {
- @Inject Foo foo;
- public Object get() {
- return null;
- }
- });
- bindListener(Matchers.any(),
- new SpecialChecker(Foo.class, getClass().getName() + ".configure(", notified));
- }
- });
- assertTrue(notified.get());
- }
-
- public void testInjectorInjectMembers() {
- final Object object = new Object() {
- @Inject Foo foo;
- };
- final AtomicBoolean notified = new AtomicBoolean();
- Guice.createInjector(new AbstractModule() {
- @Override
- protected void configure() {
- bindListener(Matchers.any(),
- new SpecialChecker(Foo.class, object.getClass().getName(), notified));
- }
- }).injectMembers(object);
- assertTrue(notified.get());
- }
-
- private static class SpecialChecker implements ProvisionListener {
- private final Class<?> notifyType;
- private final String firstSource;
- private final AtomicBoolean notified;
-
- public SpecialChecker(Class<?> notifyType, String firstSource, AtomicBoolean notified) {
- this.notifyType = notifyType;
- this.firstSource = firstSource;
- this.notified = notified;
- }
-
- public <T> void onProvision(ProvisionInvocation<T> provision) {
- notified.set(true);
- assertEquals(notifyType, provision.getBinding().getKey().getRawType());
- assertEquals(2, provision.getDependencyChain().size());
-
- assertNull(provision.getDependencyChain().get(0).getDependency());
- assertContains(provision.getDependencyChain().get(0).getBindingSource(), firstSource);
-
- assertEquals(notifyType,
- provision.getDependencyChain().get(1).getDependency().getKey().getRawType());
- assertContains(provision.getDependencyChain().get(1).getBindingSource(),
- notifyType.getName() + ".class(");
- }
- }
-
- private static class Instance {
- @Inject A a;
- }
- private static class A {
- @Inject A(B b) {}
- }
- private interface B {}
- private static class BImpl implements B {
- @Inject void inject(C c) {}
- }
- private interface C {}
- private interface D {}
- private static class DP implements Provider<D> {
- @Inject Provider<E> ep;
- public D get() {
- ep.get();
- return new D() {};
- }
- }
- private static class E {
- @SuppressWarnings("unused")
- @Inject F f;
- }
- private static class F {
- }
- public void testBindToInjectorWithListeningGivesSaneException() {
- try {
- Guice.createInjector(new AbstractModule() {
- @Override
- protected void configure() {
- bindListener(Matchers.any(), new Counter());
- bind(Injector.class).toProvider(Providers.<Injector>of(null));
- }
- });
- fail();
- } catch (CreationException ce) {
- assertContains(
- ce.getMessage(), "Binding to core guice framework type is not allowed: Injector.");
- }
- }
- public void testProvisionIsNotifiedAfterContextsClear() {
- Injector injector = Guice.createInjector(new AbstractModule() {
- @Override
- protected void configure() {
- bindListener(Matchers.any(), new ProvisionListener() {
- @Override
- public <T> void onProvision(ProvisionInvocation<T> provision) {
- Object provisioned = provision.provision();
- if (provisioned instanceof X) {
- ((X)provisioned).init();
- } else if (provisioned instanceof Y) {
- X.createY = false;
- ((Y)provisioned).init();
- }
- }
- });
- }
- });
- X.createY = true;
- X x = injector.getInstance(X.class);
- assertNotSame(x, x.y.x);
- assertFalse("x.ID: " + x.ID + ", x.y.x.iD: " + x.y.x.ID, x.ID == x.y.x.ID);
- }
- private static class X {
- final static AtomicInteger COUNTER = new AtomicInteger();
- static boolean createY;
- final int ID = COUNTER.getAndIncrement();
- final Provider<Y> yProvider;
- Y y;
- @Inject X(Provider<Y> yProvider) {
- this.yProvider = yProvider;
- }
- void init() {
- if (createY) {
- this.y = yProvider.get();
- }
- }
- }
- private static class Y {
- final Provider<X> xProvider;
- X x;
- @Inject Y(Provider<X> xProvider) {
- this.xProvider = xProvider;
- }
- void init() {
- this.x = xProvider.get();
- }
- }
-
- public void testDeDuplicateProvisionListeners() {
- final Counter counter = new Counter();
- Injector injector = Guice.createInjector(new AbstractModule() {
- @Override
- protected void configure() {
- bindListener(Matchers.any(), counter);
- bindListener(Matchers.any(), counter);
- }
- });
- injector.getInstance(Many.class);
- assertEquals("ProvisionListener not de-duplicated", 1, counter.count);
- }
- }