/* * Copyright 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.gwt.inject.rebind; import static org.easymock.EasyMock.createControl; import static org.easymock.EasyMock.createNiceControl; import static org.easymock.EasyMock.expect; import static org.easymock.EasyMock.replay; import static org.easymock.EasyMock.verify; import com.google.gwt.core.ext.TreeLogger; import com.google.gwt.inject.client.Ginjector; import com.google.gwt.inject.rebind.binding.BindingFactory; import com.google.gwt.inject.rebind.binding.BindingFactoryImpl; import com.google.gwt.inject.rebind.binding.Context; import com.google.gwt.inject.rebind.resolution.BindingResolver; import com.google.gwt.inject.rebind.util.GuiceUtil; import com.google.gwt.inject.rebind.util.MemberCollector; import com.google.gwt.inject.rebind.util.MethodCallUtil; import com.google.gwt.inject.rebind.util.NameGenerator; import com.google.inject.Key; import com.google.inject.Provider; import junit.framework.TestCase; import org.easymock.EasyMock; import org.easymock.IMocksControl; public class GinjectorBindingsTest extends TestCase { private IMocksControl control; private IMocksControl niceControl; private BindingFactory bindingFactory; // Mocks: private NameGenerator nameGenerator; private TreeLogger logger; private GuiceUtil guiceUtil; private Provider<GinjectorBindings> ginjectorBindingsProvider; private MemberCollector collector; private ErrorManager errorManager; private BindingResolver bindingResolver; private MethodCallUtil methodCallUtil; private final Context context = Context.forText(""); @Override public void setUp() { control = createControl(); niceControl = createNiceControl(); nameGenerator = control.createMock("nameGenerator", NameGenerator.class); logger = niceControl.createMock("logger", TreeLogger.class); guiceUtil = control.createMock("guiceUtil", GuiceUtil.class); { @SuppressWarnings("unchecked") Provider<GinjectorBindings> tmpProvider = control.createMock("ginjectorBindingsProvider", Provider.class); ginjectorBindingsProvider = tmpProvider; } collector = control.createMock("collector", MemberCollector.class); errorManager = control.createMock("errorManager", ErrorManager.class); bindingResolver = control.createMock("bindingResolver", BindingResolver.class); methodCallUtil = control.createMock("methodCallUtil", MethodCallUtil.class); bindingFactory = new BindingFactoryImpl( errorManager, guiceUtil, DummyInjectorInterface.class, methodCallUtil); } /** Replay all mocks. */ private void replay() { control.replay(); niceControl.replay(); } /** Verify all mocks and reset them. */ private void verifyAndReset() { control.verify(); niceControl.verify(); control.reset(); niceControl.reset(); } public void testGetChildWhichBindsLocally() { GinjectorBindings topBindings = createBindings(); GinjectorBindings childBindings = createBindings(); expect(ginjectorBindingsProvider.get()).andReturn(childBindings); replay(); topBindings.createChildGinjectorBindings(GinjectorBindingsTest.class); Key<?> fromKey = Key.get(GinjectorBindingsTest.class); Key<?> toKey = Key.get(Long.class); childBindings.addBinding(fromKey, bindingFactory.getBindClassBinding(fromKey, toKey, context)); verifyAndReset(); assertEquals(childBindings, topBindings.getChildWhichBindsLocally(fromKey)); } public void testIsBoundLocallyInChild() { GinjectorBindings topBindings = createBindings(); GinjectorBindings childBindings = createBindings(); expect(ginjectorBindingsProvider.get()).andReturn(childBindings); replay(); topBindings.createChildGinjectorBindings(GinjectorBindingsTest.class); Key<?> fromKey = Key.get(GinjectorBindingsTest.class); Key<?> toKey = Key.get(Long.class); childBindings.addBinding(fromKey, bindingFactory.getBindClassBinding(fromKey, toKey, context)); verifyAndReset(); assertTrue(topBindings.isBoundLocallyInChild(fromKey)); } public void testIsBoundLocallyInChild_ignoresParentBindings() { GinjectorBindings topBindings = createBindings(); GinjectorBindings childBindings = createBindings(); expect(ginjectorBindingsProvider.get()).andReturn(childBindings); replay(); topBindings.createChildGinjectorBindings(GinjectorBindingsTest.class); Key<?> key = Key.get(GinjectorBindingsTest.class); childBindings.addBinding(key, bindingFactory.getParentBinding(key, topBindings, context)); verifyAndReset(); assertFalse(topBindings.isBoundLocallyInChild(key)); } public void testisBoundLocallyInChild_ignoresParentBindingsButKeepsOthers() { GinjectorBindings topBindings = createBindings(); GinjectorBindings childBindings1 = createBindings(); GinjectorBindings childBindings2 = createBindings(); GinjectorBindings childBindings3 = createBindings(); expect(ginjectorBindingsProvider.get()).andReturn(childBindings1); expect(ginjectorBindingsProvider.get()).andReturn(childBindings2); expect(ginjectorBindingsProvider.get()).andReturn(childBindings3); replay(); topBindings.createChildGinjectorBindings(GinjectorBindingsTest.class); topBindings.createChildGinjectorBindings(GinjectorBindingsTest.class); topBindings.createChildGinjectorBindings(GinjectorBindingsTest.class); Key<?> key = Key.get(GinjectorBindingsTest.class); Key<?> toKey = Key.get(Long.class); childBindings1.addBinding(key, bindingFactory.getParentBinding(key, topBindings, context)); childBindings2.addBinding(key, bindingFactory.getBindClassBinding(key, toKey, context)); childBindings3.addBinding(key, bindingFactory.getParentBinding(key, topBindings, context)); verifyAndReset(); assertTrue(topBindings.isBoundLocallyInChild(key)); } public void testHasEagerSingletonBindingInSubtree_selfHasNoEagerSingletonBinding() throws Exception { GinjectorBindings bindings = createBindings(); expectFinalize(bindings); replay(); Key<?> key = Key.get(GinjectorBindingsTest.class); Key<?> toKey = Key.get(Long.class); bindings.addBinding(key, bindingFactory.getBindClassBinding(key, toKey, context)); bindings.putScope(key, GinScope.SINGLETON); finalize(bindings); assertFalse(bindings.hasEagerSingletonBindingInSubtree()); } public void testHasEagerSingletonBindingInSubtree_selfHasEagerSingleton() throws Exception { GinjectorBindings bindings = createBindings(); expectFinalize(bindings); replay(); Key<?> key = Key.get(GinjectorBindingsTest.class); Key<?> toKey = Key.get(Long.class); bindings.addBinding(key, bindingFactory.getBindClassBinding(key, toKey, context)); bindings.putScope(key, GinScope.EAGER_SINGLETON); finalize(bindings); assertTrue(bindings.hasEagerSingletonBindingInSubtree()); } public void testHasEagerSingletonBindingInSubtree_childHasEagerSingleton() throws Exception { GinjectorBindings toplevelBindings = createBindings(); GinjectorBindings childBindings = createBindings(); expect(ginjectorBindingsProvider.get()).andReturn(childBindings); expectFinalize(toplevelBindings); expectFinalize(childBindings); replay(); toplevelBindings.createChildGinjectorBindings(GinjectorBindingsTest.class); Key<?> key = Key.get(GinjectorBindingsTest.class); Key<?> toKey = Key.get(Long.class); childBindings.addBinding(key, bindingFactory.getBindClassBinding(key, toKey, context)); childBindings.putScope(key, GinScope.EAGER_SINGLETON); finalize(toplevelBindings); finalize(childBindings); assertTrue(toplevelBindings.hasEagerSingletonBindingInSubtree()); } public void testHasEagerSingletonBindingInSubtree_grandchildHasEagerSingleton() throws Exception { GinjectorBindings toplevelBindings = createBindings(); GinjectorBindings childBindings = createBindings(); GinjectorBindings grandchildBindings = createBindings(); expect(ginjectorBindingsProvider.get()).andReturn(childBindings); expect(ginjectorBindingsProvider.get()).andReturn(grandchildBindings); expectFinalize(toplevelBindings); expectFinalize(childBindings); expectFinalize(grandchildBindings); replay(); toplevelBindings.createChildGinjectorBindings(GinjectorBindingsTest.class); childBindings.createChildGinjectorBindings(GinjectorBindingsTest.class); Key<?> key = Key.get(GinjectorBindingsTest.class); Key<?> toKey = Key.get(Long.class); grandchildBindings.addBinding(key, bindingFactory.getBindClassBinding(key, toKey, context)); grandchildBindings.putScope(key, GinScope.EAGER_SINGLETON); finalize(toplevelBindings); finalize(childBindings); finalize(grandchildBindings); assertTrue(toplevelBindings.hasEagerSingletonBindingInSubtree()); } public void testHasStaticInjectionRequestInSubtree_selfHasNoStaticInjectionRequest() { GinjectorBindings bindings = createBindings(); replay(); assertFalse(bindings.hasStaticInjectionRequestInSubtree()); } public void testHasStaticInjectionRequestInSubtree_selfHasStaticInjectionRequest() { GinjectorBindings bindings = createBindings(); replay(); bindings.addStaticInjectionRequest(GinjectorBindingsTest.class, ""); assertTrue(bindings.hasStaticInjectionRequestInSubtree()); } public void testHasStaticInjectionRequestInSubtree_childHasStaticInjectionRequest() { GinjectorBindings toplevelBindings = createBindings(); GinjectorBindings childBindings = createBindings(); expect(ginjectorBindingsProvider.get()).andReturn(childBindings); replay(); toplevelBindings.createChildGinjectorBindings(GinjectorBindingsTest.class); childBindings.addStaticInjectionRequest(GinjectorBindingsTest.class, ""); assertTrue(toplevelBindings.hasStaticInjectionRequestInSubtree()); } public void testHasStaticInjectionRequestInSubtree_grandchildHasStaticInjectionRequest() { GinjectorBindings toplevelBindings = createBindings(); GinjectorBindings childBindings = createBindings(); GinjectorBindings grandchildBindings = createBindings(); expect(ginjectorBindingsProvider.get()).andReturn(childBindings); expect(ginjectorBindingsProvider.get()).andReturn(grandchildBindings); replay(); toplevelBindings.createChildGinjectorBindings(GinjectorBindingsTest.class); childBindings.createChildGinjectorBindings(GinjectorBindingsTest.class); grandchildBindings.addStaticInjectionRequest(GinjectorBindingsTest.class, ""); assertTrue(toplevelBindings.hasStaticInjectionRequestInSubtree()); } private GinjectorBindings createBindings() { collector.setMethodFilter(EasyMock.<MemberCollector.MethodFilter>anyObject()); replay(); GinjectorBindings result = new GinjectorBindings( nameGenerator, logger, guiceUtil, DummyInjectorInterface.class, ginjectorBindingsProvider, collector, errorManager, bindingResolver); verifyAndReset(); return result; } /** * Set up the expectations necessary to finalize the given * {@link GinjectorBindings}. */ private void expectFinalize(GinjectorBindings bindings) throws Exception { bindingResolver.resolveBindings(bindings); errorManager.checkForError(); } /** * Finalize the given {@link GinjectorBindings}. This must be invoked before * checking whether it contains any eager singletons. */ private void finalize(GinjectorBindings bindings) throws Exception { bindings.resolveBindings(); } private interface DummyInjectorInterface extends Ginjector { } }