/* * 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.assistedinject; import com.google.inject.AbstractModule; import com.google.inject.Asserts; import com.google.inject.CreationException; import com.google.inject.Guice; import com.google.inject.Injector; import junit.framework.TestCase; /** @author sameb@google.com (Sam Berlin) */ public class ManyConstructorsTest extends TestCase { public void testTwoConstructors() { Injector injector = Guice.createInjector( new AbstractModule() { @Override protected void configure() { install(new FactoryModuleBuilder().build(Factory.class)); } }); Factory factory = injector.getInstance(Factory.class); Foo noIndex = factory.create("no index"); assertEquals("no index", noIndex.name); assertNull(noIndex.index); Foo index = factory.create("index", 1); assertEquals("index", index.name); assertEquals(1, index.index.intValue()); } public void testDifferentOrderParameters() { Injector injector = Guice.createInjector( new AbstractModule() { @Override protected void configure() { install(new FactoryModuleBuilder().build(OtherFactory.class)); } }); OtherFactory factory = injector.getInstance(OtherFactory.class); Foo noIndex = factory.create("no index"); assertEquals("no index", noIndex.name); assertNull(noIndex.index); Foo index = factory.create(1, "index"); assertEquals("index", index.name); assertEquals(1, index.index.intValue()); Foo index2 = factory.create("index", 2); assertEquals("index", index2.name); assertEquals(2, index2.index.intValue()); } public void testInterfaceToImpl() { Injector injector = Guice.createInjector( new AbstractModule() { @Override protected void configure() { install( new FactoryModuleBuilder() .implement(Bar.class, Foo.class) .build(BarFactory.class)); } }); BarFactory factory = injector.getInstance(BarFactory.class); Bar noIndex = factory.create("no index"); assertEquals("no index", noIndex.getName()); assertNull(noIndex.getIndex()); Bar index = factory.create("index", 1); assertEquals("index", index.getName()); assertEquals(1, index.getIndex().intValue()); } public void testUsingOneConstructor() { Injector injector = Guice.createInjector( new AbstractModule() { @Override protected void configure() { install(new FactoryModuleBuilder().build(SimpleFactory.class)); } }); SimpleFactory factory = injector.getInstance(SimpleFactory.class); Foo noIndex = factory.create("no index"); assertEquals("no index", noIndex.name); assertNull(noIndex.index); injector = Guice.createInjector( new AbstractModule() { @Override protected void configure() { install(new FactoryModuleBuilder().build(SimpleFactory2.class)); } }); SimpleFactory2 factory2 = injector.getInstance(SimpleFactory2.class); Foo index = factory2.create("index", 1); assertEquals("index", index.name); assertEquals(1, index.index.intValue()); } public void testTooManyMatchingConstructors() { try { Guice.createInjector( new AbstractModule() { @Override protected void configure() { install( new FactoryModuleBuilder() .implement(Foo.class, TooManyMatches.class) .build(SimpleFactory2.class)); } }); fail("should have failed"); } catch (CreationException expected) { Asserts.assertContains( expected.getMessage(), "1) " + TooManyMatches.class.getName() + " has more than one constructor annotated with @AssistedInject that " + "matches the parameters in method " + SimpleFactory2.class.getName()); } } public void testNoMatchingConstructorsBecauseTooManyParams() { try { Guice.createInjector( new AbstractModule() { @Override protected void configure() { install(new FactoryModuleBuilder().build(ComplexFactory.class)); } }); fail("should have failed"); } catch (CreationException expected) { Asserts.assertContains( expected.getMessage(), "1) " + Foo.class.getName() + " has @AssistedInject constructors, but none of them match the parameters in method " + ComplexFactory.class.getName()); } } public void testNoMatchingConstrucotsBecauseTooLittleParams() { try { Guice.createInjector( new AbstractModule() { @Override protected void configure() { install(new FactoryModuleBuilder().build(NullFactory.class)); } }); fail("should have failed"); } catch (CreationException expected) { Asserts.assertContains( expected.getMessage(), "1) " + Foo.class.getName() + " has @AssistedInject constructors, but none of them match the parameters in method " + NullFactory.class.getName()); } } public static interface ComplexFactory { Foo create(String name, int idx, float weight); } public static interface NullFactory { Foo create(); } public static interface OtherFactory { Foo create(String name, int idx); Foo create(int idx, String name); Foo create(String name); } public static interface Factory { Foo create(String name); Foo create(String name, int idx); } public static interface BarFactory { Bar create(String name); Bar create(String name, int idx); } public static interface SimpleFactory { Foo create(String name); } public static interface SimpleFactory2 { Foo create(String name, int idx); } public static class TooManyMatches extends Foo { @AssistedInject TooManyMatches(@Assisted String name, @Assisted int index) {} @AssistedInject TooManyMatches(@Assisted int index, @Assisted String name) {} } public static class Foo implements Bar { private String name; private Integer index; Foo() {} @AssistedInject Foo(@Assisted String name) { this.name = name; this.index = null; } @AssistedInject Foo(@Assisted String name, @Assisted int index) { this.name = name; this.index = index; } Foo(String a, String b, String c) {} @Override public String getName() { return name; } @Override public Integer getIndex() { return index; } } public static interface Bar { String getName(); Integer getIndex(); } public void testDependenciesAndOtherAnnotations() { Injector injector = Guice.createInjector( new AbstractModule() { @Override protected void configure() { install(new FactoryModuleBuilder().build(FamilyFarmFactory.class)); } }); FamilyFarmFactory factory = injector.getInstance(FamilyFarmFactory.class); Farm pops = factory.popsFarm("Pop"); assertEquals("Pop", pops.pop); assertEquals(null, pops.mom); Farm moms = factory.momsFarm("Mom"); assertEquals(null, moms.pop); assertEquals("Mom", moms.mom); Farm momAndPop = factory.momAndPopsFarm("Mom", "Pop"); assertEquals("Pop", momAndPop.pop); assertEquals("Mom", momAndPop.mom); } public static interface FamilyFarmFactory { Farm popsFarm(String pop); Farm momsFarm(@Assisted("mom") String mom); Farm momAndPopsFarm(@Assisted("mom") String mom, @Assisted("pop") String pop); } public static class Farm { String pop; String mom; @AssistedInject Farm(@Assisted String pop, Dog dog) { this.pop = pop; } @AssistedInject Farm(@Assisted("mom") String mom, @Assisted("pop") String pop, Cow cow, Dog dog) { this.pop = pop; this.mom = mom; } @AssistedInject Farm(@Assisted("mom") String mom, Cow cow) { this.mom = mom; } } public static class Cow {} public static class Dog {} }