/*
* Copyright 2013 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.client.multibindings;
import static com.google.gwt.inject.client.multibindings.GinMultibinder.newSetBinder;
import com.google.gwt.core.client.GWT;
import com.google.gwt.inject.client.AbstractGinModule;
import com.google.gwt.inject.client.GinModules;
import com.google.gwt.inject.client.Ginjector;
import com.google.gwt.inject.client.multibindings.TestTypes.ProviderForXImpl2;
import com.google.gwt.inject.client.multibindings.TestTypes.X;
import com.google.gwt.inject.client.multibindings.TestTypes.XImpl1;
import com.google.gwt.inject.client.multibindings.TestTypes.XImpl2;
import com.google.gwt.inject.client.multibindings.TestTypes.XWithEquals;
import com.google.gwt.inject.client.multibindings.TestTypes.Y;
import com.google.gwt.inject.client.multibindings.TestTypes.YImpl;
import com.google.gwt.junit.client.GWTTestCase;
import com.google.inject.Singleton;
import com.google.inject.name.Named;
import com.google.inject.name.Names;
import java.util.Iterator;
import java.util.Set;
public class GinMultibinderTest extends GWTTestCase {
public static class GinModuleWithNoBinding extends AbstractGinModule {
@Override
protected void configure() {
newSetBinder(binder(), X.class);
}
}
@GinModules(GinModuleWithNoBinding.class)
public interface NoBindingGinjector extends Ginjector {
Set<X> getSet();
}
public void testInject_empty() throws Exception {
NoBindingGinjector injector = GWT.create(NoBindingGinjector.class);
Set<X> set = injector.getSet();
assertTrue(set.isEmpty());
}
public static class GinModuleWithXY extends AbstractGinModule {
@Override
protected void configure() {
newSetBinder(binder(), X.class).addBinding().to(XImpl1.class);
newSetBinder(binder(), Y.class).addBinding().to(YImpl.class);
}
}
public static class GinModuleWithMoreX extends AbstractGinModule {
@Override
protected void configure() {
GinMultibinder<X> setBinder = newSetBinder(binder(), X.class);
setBinder.addBinding().to(XImpl2.class);
setBinder.addBinding().to(XImpl1.class);
}
}
@GinModules({GinModuleWithXY.class, GinModuleWithMoreX.class})
public interface SetGinjector extends Ginjector {
Set<X> getSetX();
Set<Y> getSetY();
}
public void testInject() throws Exception {
SetGinjector injector = GWT.create(SetGinjector.class);
Set<X> setX = injector.getSetX();
assertEquals(3, setX.size());
Iterator<X> iterator = setX.iterator();
assertTrue(iterator.next() instanceof XImpl1);
assertTrue(iterator.next() instanceof XImpl2);
assertTrue(iterator.next() instanceof XImpl1);
Set<Y> setY = injector.getSetY();
assertEquals(1, setY.size());
assertTrue(setY.iterator().next() instanceof YImpl);
}
public void testInject_sameSetTwice() throws Exception {
SetGinjector injector = GWT.create(SetGinjector.class);
Set<X> set1 = injector.getSetX();
Set<X> set2 = injector.getSetX();
assertEquals(set1.size(), set2.size());
Iterator<X> iterator1 = set1.iterator();
Iterator<X> iterator2 = set2.iterator();
X element = iterator2.next();
assertTrue(element instanceof XImpl1);
assertNotSame(iterator1.next(), element);
element = iterator2.next();
assertTrue(element instanceof XImpl2);
assertNotSame(iterator1.next(), element);
element = iterator2.next();
assertTrue(element instanceof XImpl1);
assertNotSame(iterator1.next(), element);
}
public static class GinModuleWithScopedX extends AbstractGinModule {
@Override
protected void configure() {
newSetBinder(binder(), X.class).addBinding().to(XImpl1.class).in(Singleton.class);
}
}
@GinModules({GinModuleWithXY.class, GinModuleWithScopedX.class})
public interface SetGinjectorWithScope extends Ginjector {
Set<X> getSet();
}
public void testInject_sameSetTwiceWithScope() throws Exception {
SetGinjectorWithScope injector = GWT.create(SetGinjectorWithScope.class);
Set<X> set1 = injector.getSet();
Set<X> set2 = injector.getSet();
assertEquals(set1.size(), set2.size());
Iterator<X> iterator1 = set1.iterator();
Iterator<X> iterator2 = set2.iterator();
assertNotSame(iterator1.next(), iterator2.next());
assertSame(iterator1.next(), iterator2.next());
}
public static class GinModuleWithRegularBind extends AbstractGinModule {
@Override
protected void configure() {
newSetBinder(binder(), X.class).addBinding().to(XImpl1.class);
bind(X.class).to(XImpl2.class);
}
}
@GinModules(GinModuleWithRegularBind.class)
public interface GinjectorWithRegularBind extends Ginjector {
Set<X> getSet();
X getX();
}
public void testInject_sameInterfaceBoundWithBothRegularAndMultiBind() throws Exception {
GinjectorWithRegularBind injector = GWT.create(GinjectorWithRegularBind.class);
assertEquals(1, injector.getSet().size());
assertTrue(injector.getSet().iterator().next() instanceof XImpl1);
assertTrue(injector.getX() instanceof XImpl2);
}
public static class GinModuleWithProvider extends AbstractGinModule {
@Override
protected void configure() {
newSetBinder(binder(), X.class).addBinding().toProvider(ProviderForXImpl2.class);
}
}
@GinModules({GinModuleWithXY.class, GinModuleWithProvider.class})
public interface GinjectorWithProvider extends Ginjector {
Set<X> getSetX();
}
public void testInject_valueBoundWithProvider() throws Exception {
GinjectorWithProvider injector = GWT.create(GinjectorWithProvider.class);
Set<X> setX = injector.getSetX();
assertEquals(2, setX.size());
Iterator<X> iterator = setX.iterator();
assertTrue(iterator.next() instanceof XImpl1);
assertTrue(iterator.next() instanceof XImpl2);
}
public static class GinModuleWithAnnotations extends AbstractGinModule {
@Override
protected void configure() {
GinMultibinder<X> mapBinder = newSetBinder(binder(), X.class);
mapBinder.addBinding().to(XImpl1.class);
mapBinder.addBinding().to(XImpl2.class);
GinMultibinder<X> mapBinderA = newSetBinder(binder(), X.class, Names.named("a"));
mapBinderA.addBinding().to(XImpl1.class);
mapBinderA.addBinding().to(XImpl1.class);
GinMultibinder<X> mapBinderB = newSetBinder(binder(), X.class, Names.named("b"));
mapBinderB.addBinding().to(XImpl2.class);
mapBinderB.addBinding().to(XImpl2.class);
}
}
@GinModules(GinModuleWithAnnotations.class)
public interface GinjectorWithAnnotations extends Ginjector {
Set<X> getSetX();
@Named("a") Set<X> getSetXa();
@Named("b") Set<X> getSetXb();
}
public void testInject_annotated() throws Exception {
GinjectorWithAnnotations injector = GWT.create(GinjectorWithAnnotations.class);
Set<X> setX = injector.getSetX();
assertEquals(2, setX.size());
Iterator<X> iterator = setX.iterator();
assertTrue(iterator.next() instanceof XImpl1);
assertTrue(iterator.next() instanceof XImpl2);
Set<X> setXa = injector.getSetXa();
assertEquals(2, setXa.size());
iterator = setXa.iterator();
assertTrue(iterator.next() instanceof XImpl1);
assertTrue(iterator.next() instanceof XImpl1);
Set<X> setXb = injector.getSetXb();
assertEquals(2, setXb.size());
iterator = setXb.iterator();
assertTrue(iterator.next() instanceof XImpl2);
assertTrue(iterator.next() instanceof XImpl2);
}
public static class GinModuleWithDuplicateBinding extends AbstractGinModule {
@Override
protected void configure() {
newSetBinder(binder(), X.class).addBinding().to(XWithEquals.class);
newSetBinder(binder(), X.class).addBinding().to(XWithEquals.class);
}
}
@GinModules(GinModuleWithDuplicateBinding.class)
public interface DoubleBindingGinjector extends Ginjector {
Set<X> getSetX();
}
public void testInject_dontPermitDuplicates() {
DoubleBindingGinjector injector = GWT.create(DoubleBindingGinjector.class);
try {
injector.getSetX();
fail("should have thrown exception");
} catch (IllegalStateException e) {
assertTrue(e.toString().contains("duplicate"));
}
}
public static class GinModuleForPermittingDuplicate extends AbstractGinModule {
@Override
protected void configure() {
newSetBinder(binder(), X.class).permitDuplicates();
newSetBinder(binder(), X.class).permitDuplicates(); // shows multiple calls is OK
}
}
@GinModules(GinModuleForPermittingDuplicate.class)
public interface GinjectorWithPermitDuplicates extends DoubleBindingGinjector {}
public void testInject_permitDuplicates() {
GinjectorWithPermitDuplicates injector = GWT.create(GinjectorWithPermitDuplicates.class);
assertEquals(1, injector.getSetX().size());
}
@Override
public String getModuleName() {
return "com.google.gwt.inject.InjectTest";
}
}