| /* |
| * Copyright (C) 2007 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 static com.google.inject.Asserts.assertContains; |
| |
| import com.google.common.collect.ImmutableSet; |
| import com.google.inject.AbstractModule; |
| import com.google.inject.Binding; |
| import com.google.inject.ConfigurationException; |
| import com.google.inject.CreationException; |
| import com.google.inject.Guice; |
| import com.google.inject.Inject; |
| import com.google.inject.Injector; |
| import com.google.inject.Key; |
| import com.google.inject.Provider; |
| import com.google.inject.TypeLiteral; |
| import com.google.inject.assistedinject.FactoryProviderTest.Equals.ComparisonMethod; |
| import com.google.inject.assistedinject.FactoryProviderTest.Equals.Impl; |
| import com.google.inject.name.Named; |
| import com.google.inject.name.Names; |
| import com.google.inject.spi.Dependency; |
| import com.google.inject.spi.HasDependencies; |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.Set; |
| import junit.framework.TestCase; |
| |
| /** |
| * @author jmourits@google.com (Jerome Mourits) |
| * @author jessewilson@google.com (Jesse Wilson) |
| */ |
| @SuppressWarnings("deprecation") |
| public class FactoryProviderTest extends TestCase { |
| |
| private enum Color { |
| BLUE, |
| GREEN, |
| RED, |
| GRAY, |
| BLACK, |
| ORANGE, |
| PINK |
| } |
| |
| public void testAssistedFactory() { |
| Injector injector = |
| Guice.createInjector( |
| new AbstractModule() { |
| @Override |
| protected void configure() { |
| bind(Double.class).toInstance(5.0d); |
| bind(ColoredCarFactory.class) |
| .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, Mustang.class)); |
| } |
| }); |
| ColoredCarFactory carFactory = injector.getInstance(ColoredCarFactory.class); |
| |
| Mustang blueMustang = (Mustang) carFactory.create(Color.BLUE); |
| assertEquals(Color.BLUE, blueMustang.color); |
| assertEquals(5.0d, blueMustang.engineSize, 0.0); |
| |
| Mustang redMustang = (Mustang) carFactory.create(Color.RED); |
| assertEquals(Color.RED, redMustang.color); |
| assertEquals(5.0d, redMustang.engineSize, 0.0); |
| } |
| |
| public void testFactoryBindingDependencies() { |
| Injector injector = |
| Guice.createInjector( |
| new AbstractModule() { |
| @Override |
| protected void configure() { |
| bind(Double.class).toInstance(5.0d); |
| bind(ColoredCarFactory.class) |
| .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, Mustang.class)); |
| } |
| }); |
| |
| Binding<?> binding = injector.getBinding(ColoredCarFactory.class); |
| HasDependencies hasDependencies = (HasDependencies) binding; |
| assertEquals( |
| ImmutableSet.<Dependency<?>>of(Dependency.get(Key.get(double.class))), |
| hasDependencies.getDependencies()); |
| } |
| |
| public void testAssistedFactoryWithAnnotations() { |
| Injector injector = |
| Guice.createInjector( |
| new AbstractModule() { |
| @Override |
| protected void configure() { |
| bind(int.class).annotatedWith(Names.named("horsePower")).toInstance(250); |
| bind(int.class).annotatedWith(Names.named("modelYear")).toInstance(1984); |
| bind(ColoredCarFactory.class) |
| .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, Camaro.class)); |
| } |
| }); |
| |
| ColoredCarFactory carFactory = injector.getInstance(ColoredCarFactory.class); |
| |
| Camaro blueCamaro = (Camaro) carFactory.create(Color.BLUE); |
| assertEquals(Color.BLUE, blueCamaro.color); |
| assertEquals(1984, blueCamaro.modelYear); |
| assertEquals(250, blueCamaro.horsePower); |
| |
| Camaro redCamaro = (Camaro) carFactory.create(Color.RED); |
| assertEquals(Color.RED, redCamaro.color); |
| assertEquals(1984, redCamaro.modelYear); |
| assertEquals(250, redCamaro.horsePower); |
| } |
| |
| interface Car {} |
| |
| interface ColoredCarFactory { |
| Car create(Color color); |
| } |
| |
| public static class Mustang implements Car { |
| private final double engineSize; |
| private final Color color; |
| |
| @AssistedInject |
| public Mustang(double engineSize, @Assisted Color color) { |
| this.engineSize = engineSize; |
| this.color = color; |
| } |
| } |
| |
| public static class Camaro implements Car { |
| private final int horsePower; |
| private final int modelYear; |
| private final Color color; |
| |
| @AssistedInject |
| public Camaro( |
| @Named("horsePower") int horsePower, |
| @Named("modelYear") int modelYear, |
| @Assisted Color color) { |
| this.horsePower = horsePower; |
| this.modelYear = modelYear; |
| this.color = color; |
| } |
| } |
| |
| interface SummerCarFactory { |
| Car create(Color color, boolean convertable); |
| |
| Car createConvertible(Color color); |
| } |
| |
| public void testFactoryWithMultipleMethods() { |
| Injector injector = |
| Guice.createInjector( |
| new AbstractModule() { |
| @Override |
| protected void configure() { |
| bind(float.class).toInstance(140f); |
| bind(SummerCarFactory.class) |
| .toProvider(FactoryProvider.newFactory(SummerCarFactory.class, Corvette.class)); |
| } |
| }); |
| |
| SummerCarFactory carFactory = injector.getInstance(SummerCarFactory.class); |
| |
| Corvette blueCorvette = (Corvette) carFactory.createConvertible(Color.BLUE); |
| assertEquals(Color.BLUE, blueCorvette.color); |
| assertEquals(100f, blueCorvette.maxMph, 0.0f); |
| assertTrue(blueCorvette.isConvertable); |
| |
| Corvette redCorvette = (Corvette) carFactory.create(Color.RED, false); |
| assertEquals(Color.RED, redCorvette.color); |
| assertEquals(140f, redCorvette.maxMph, 0.0f); |
| assertFalse(redCorvette.isConvertable); |
| } |
| |
| public static class Corvette implements Car { |
| private boolean isConvertable; |
| private Color color; |
| private float maxMph; |
| |
| @AssistedInject |
| public Corvette(@Assisted Color color) { |
| this(color, 100f, true); |
| } |
| |
| @SuppressWarnings("unused") |
| public Corvette(@Assisted Color color, @Assisted boolean isConvertable) { |
| throw new IllegalStateException("Not an @AssistedInject constructor"); |
| } |
| |
| @AssistedInject |
| public Corvette(@Assisted Color color, Float maxMph, @Assisted boolean isConvertable) { |
| this.isConvertable = isConvertable; |
| this.color = color; |
| this.maxMph = maxMph; |
| } |
| } |
| |
| public void testFactoryMethodsMismatch() { |
| try { |
| FactoryProvider.newFactory(SummerCarFactory.class, Beetle.class); |
| fail(); |
| } catch (ConfigurationException e) { |
| assertContains(e.getMessage(), "Constructor mismatch"); |
| } |
| } |
| |
| public static class Beetle implements Car { |
| @AssistedInject |
| @SuppressWarnings("unused") |
| public Beetle(@Assisted Color color) { |
| throw new IllegalStateException("Conflicting constructors"); |
| } |
| |
| @AssistedInject |
| @SuppressWarnings("unused") |
| public Beetle(@Assisted Color color, @Assisted boolean isConvertable) { |
| throw new IllegalStateException("Conflicting constructors"); |
| } |
| |
| @AssistedInject |
| @SuppressWarnings("unused") |
| public Beetle(@Assisted Color color, @Assisted boolean isConvertable, float maxMph) { |
| throw new IllegalStateException("Conflicting constructors"); |
| } |
| } |
| |
| public void testMethodsAndFieldsGetInjected() { |
| Injector injector = |
| Guice.createInjector( |
| new AbstractModule() { |
| @Override |
| protected void configure() { |
| bind(String.class).toInstance("turbo"); |
| bind(int.class).toInstance(911); |
| bind(double.class).toInstance(50000d); |
| bind(ColoredCarFactory.class) |
| .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, Porshe.class)); |
| } |
| }); |
| ColoredCarFactory carFactory = injector.getInstance(ColoredCarFactory.class); |
| |
| Porshe grayPorshe = (Porshe) carFactory.create(Color.GRAY); |
| assertEquals(Color.GRAY, grayPorshe.color); |
| assertEquals(50000d, grayPorshe.price, 0.0); |
| assertEquals(911, grayPorshe.model); |
| assertEquals("turbo", grayPorshe.name); |
| } |
| |
| public static class Porshe implements Car { |
| private final Color color; |
| private final double price; |
| private @Inject String name; |
| private int model; |
| |
| @AssistedInject |
| public Porshe(@Assisted Color color, double price) { |
| this.color = color; |
| this.price = price; |
| } |
| |
| @Inject |
| void setModel(int model) { |
| this.model = model; |
| } |
| } |
| |
| public void testProviderInjection() { |
| Injector injector = |
| Guice.createInjector( |
| new AbstractModule() { |
| @Override |
| protected void configure() { |
| bind(String.class).toInstance("trans am"); |
| bind(ColoredCarFactory.class) |
| .toProvider( |
| FactoryProvider.newFactory(ColoredCarFactory.class, Firebird.class)); |
| } |
| }); |
| ColoredCarFactory carFactory = injector.getInstance(ColoredCarFactory.class); |
| |
| Firebird blackFirebird = (Firebird) carFactory.create(Color.BLACK); |
| assertEquals(Color.BLACK, blackFirebird.color); |
| assertEquals("trans am", blackFirebird.modifiersProvider.get()); |
| } |
| |
| public static class Firebird implements Car { |
| private final Provider<String> modifiersProvider; |
| private final Color color; |
| |
| @AssistedInject |
| public Firebird(Provider<String> modifiersProvider, @Assisted Color color) { |
| this.modifiersProvider = modifiersProvider; |
| this.color = color; |
| } |
| } |
| |
| public void testTypeTokenInjection() { |
| Injector injector = |
| Guice.createInjector( |
| new AbstractModule() { |
| @Override |
| protected void configure() { |
| bind(new TypeLiteral<Set<String>>() {}) |
| .toInstance(Collections.singleton("Flux Capacitor")); |
| bind(new TypeLiteral<Set<Integer>>() {}).toInstance(Collections.singleton(88)); |
| bind(ColoredCarFactory.class) |
| .toProvider( |
| FactoryProvider.newFactory(ColoredCarFactory.class, DeLorean.class)); |
| } |
| }); |
| ColoredCarFactory carFactory = injector.getInstance(ColoredCarFactory.class); |
| |
| DeLorean deLorean = (DeLorean) carFactory.create(Color.GRAY); |
| assertEquals(Color.GRAY, deLorean.color); |
| assertEquals("Flux Capacitor", deLorean.features.iterator().next()); |
| assertEquals(Integer.valueOf(88), deLorean.featureActivationSpeeds.iterator().next()); |
| } |
| |
| public static class DeLorean implements Car { |
| private final Set<String> features; |
| private final Set<Integer> featureActivationSpeeds; |
| private final Color color; |
| |
| @AssistedInject |
| public DeLorean( |
| Set<String> extraFeatures, Set<Integer> featureActivationSpeeds, @Assisted Color color) { |
| this.features = extraFeatures; |
| this.featureActivationSpeeds = featureActivationSpeeds; |
| this.color = color; |
| } |
| } |
| |
| public void testTypeTokenProviderInjection() { |
| Injector injector = |
| Guice.createInjector( |
| new AbstractModule() { |
| @Override |
| protected void configure() { |
| bind(new TypeLiteral<Set<String>>() {}).toInstance(Collections.singleton("Datsun")); |
| bind(ColoredCarFactory.class) |
| .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, Z.class)); |
| } |
| }); |
| ColoredCarFactory carFactory = injector.getInstance(ColoredCarFactory.class); |
| |
| Z orangeZ = (Z) carFactory.create(Color.ORANGE); |
| assertEquals(Color.ORANGE, orangeZ.color); |
| assertEquals("Datsun", orangeZ.manufacturersProvider.get().iterator().next()); |
| } |
| |
| public static class Z implements Car { |
| private final Provider<Set<String>> manufacturersProvider; |
| private final Color color; |
| |
| @AssistedInject |
| public Z(Provider<Set<String>> manufacturersProvider, @Assisted Color color) { |
| this.manufacturersProvider = manufacturersProvider; |
| this.color = color; |
| } |
| } |
| |
| public static class Prius implements Car { |
| @SuppressWarnings("unused") |
| private final Color color; |
| |
| @AssistedInject |
| private Prius(@Assisted Color color) { |
| this.color = color; |
| } |
| } |
| |
| public void testAssistInjectionInNonPublicConstructor() { |
| Injector injector = |
| Guice.createInjector( |
| new AbstractModule() { |
| @Override |
| protected void configure() { |
| bind(ColoredCarFactory.class) |
| .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, Prius.class)); |
| } |
| }); |
| injector.getInstance(ColoredCarFactory.class).create(Color.ORANGE); |
| } |
| |
| public static class ExplodingCar implements Car { |
| @AssistedInject |
| public ExplodingCar(@SuppressWarnings("unused") @Assisted Color color) { |
| throw new IllegalStateException("kaboom!"); |
| } |
| } |
| |
| public void testExceptionDuringConstruction() { |
| Injector injector = |
| Guice.createInjector( |
| new AbstractModule() { |
| @Override |
| protected void configure() { |
| bind(ColoredCarFactory.class) |
| .toProvider( |
| FactoryProvider.newFactory(ColoredCarFactory.class, ExplodingCar.class)); |
| } |
| }); |
| try { |
| injector.getInstance(ColoredCarFactory.class).create(Color.ORANGE); |
| fail(); |
| } catch (IllegalStateException e) { |
| assertEquals("kaboom!", e.getMessage()); |
| } |
| } |
| |
| public static class DefectiveCar implements Car { |
| @AssistedInject |
| public DefectiveCar() throws ExplosionException { |
| throw new ExplosionException(); |
| } |
| } |
| |
| public static class ExplosionException extends Exception {} |
| |
| public static class FireException extends Exception {} |
| |
| public interface DefectiveCarFactoryWithNoExceptions { |
| Car createCar(); |
| } |
| |
| public interface DefectiveCarFactory { |
| Car createCar() throws FireException; |
| } |
| |
| public void testFactoryMethodMustDeclareAllConstructorExceptions() { |
| try { |
| FactoryProvider.newFactory(DefectiveCarFactoryWithNoExceptions.class, DefectiveCar.class); |
| fail(); |
| } catch (ConfigurationException expected) { |
| assertContains(expected.getMessage(), "no compatible exception is thrown"); |
| } |
| } |
| |
| public interface CorrectDefectiveCarFactory { |
| Car createCar() throws FireException, ExplosionException; |
| } |
| |
| public void testConstructorExceptionsAreThrownByFactory() { |
| Injector injector = |
| Guice.createInjector( |
| new AbstractModule() { |
| @Override |
| protected void configure() { |
| bind(CorrectDefectiveCarFactory.class) |
| .toProvider( |
| FactoryProvider.newFactory( |
| CorrectDefectiveCarFactory.class, DefectiveCar.class)); |
| } |
| }); |
| try { |
| injector.getInstance(CorrectDefectiveCarFactory.class).createCar(); |
| fail(); |
| } catch (FireException e) { |
| fail(); |
| } catch (ExplosionException expected) { |
| } |
| } |
| |
| public static class MultipleConstructorDefectiveCar implements Car { |
| @AssistedInject |
| public MultipleConstructorDefectiveCar() throws ExplosionException { |
| throw new ExplosionException(); |
| } |
| |
| @AssistedInject |
| public MultipleConstructorDefectiveCar(@SuppressWarnings("unused") @Assisted Color c) |
| throws FireException { |
| throw new FireException(); |
| } |
| } |
| |
| public interface MultipleConstructorDefectiveCarFactory { |
| Car createCar() throws ExplosionException; |
| |
| Car createCar(Color r) throws FireException; |
| } |
| |
| public void testMultipleConstructorExceptionMatching() { |
| Injector injector = |
| Guice.createInjector( |
| new AbstractModule() { |
| @Override |
| protected void configure() { |
| bind(MultipleConstructorDefectiveCarFactory.class) |
| .toProvider( |
| FactoryProvider.newFactory( |
| MultipleConstructorDefectiveCarFactory.class, |
| MultipleConstructorDefectiveCar.class)); |
| } |
| }); |
| MultipleConstructorDefectiveCarFactory factory = |
| injector.getInstance(MultipleConstructorDefectiveCarFactory.class); |
| try { |
| factory.createCar(); |
| fail(); |
| } catch (ExplosionException expected) { |
| } |
| |
| try { |
| factory.createCar(Color.RED); |
| fail(); |
| } catch (FireException expected) { |
| } |
| } |
| |
| public static class WildcardCollection { |
| |
| public interface Factory { |
| WildcardCollection create(Collection<?> items); |
| } |
| |
| @AssistedInject |
| public WildcardCollection(@SuppressWarnings("unused") @Assisted Collection<?> items) {} |
| } |
| |
| public void testWildcardGenerics() { |
| Injector injector = |
| Guice.createInjector( |
| new AbstractModule() { |
| @Override |
| protected void configure() { |
| bind(WildcardCollection.Factory.class) |
| .toProvider( |
| FactoryProvider.newFactory( |
| WildcardCollection.Factory.class, WildcardCollection.class)); |
| } |
| }); |
| WildcardCollection.Factory factory = injector.getInstance(WildcardCollection.Factory.class); |
| factory.create(Collections.emptyList()); |
| } |
| |
| public static class SteeringWheel {} |
| |
| public static class Fiat implements Car { |
| @SuppressWarnings("unused") |
| private final SteeringWheel steeringWheel; |
| |
| @SuppressWarnings("unused") |
| private final Color color; |
| |
| @AssistedInject |
| public Fiat(SteeringWheel steeringWheel, @Assisted Color color) { |
| this.steeringWheel = steeringWheel; |
| this.color = color; |
| } |
| } |
| |
| public void testFactoryWithImplicitBindings() { |
| Injector injector = |
| Guice.createInjector( |
| new AbstractModule() { |
| @Override |
| protected void configure() { |
| bind(ColoredCarFactory.class) |
| .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, Fiat.class)); |
| } |
| }); |
| |
| ColoredCarFactory coloredCarFactory = injector.getInstance(ColoredCarFactory.class); |
| Fiat fiat = (Fiat) coloredCarFactory.create(Color.GREEN); |
| assertEquals(Color.GREEN, fiat.color); |
| assertNotNull(fiat.steeringWheel); |
| } |
| |
| public void testFactoryFailsWithMissingBinding() { |
| try { |
| Guice.createInjector( |
| new AbstractModule() { |
| @Override |
| protected void configure() { |
| bind(ColoredCarFactory.class) |
| .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, Mustang.class)); |
| } |
| }); |
| fail(); |
| } catch (CreationException expected) { |
| assertContains( |
| expected.getMessage(), |
| "1) Parameter of type 'double' is not injectable or annotated with @Assisted"); |
| } |
| } |
| |
| @SuppressWarnings("SelfEquals") |
| public void testMethodsDeclaredInObject() { |
| Injector injector = |
| Guice.createInjector( |
| new AbstractModule() { |
| @Override |
| protected void configure() { |
| bind(Double.class).toInstance(5.0d); |
| bind(ColoredCarFactory.class) |
| .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, Mustang.class)); |
| } |
| }); |
| |
| ColoredCarFactory carFactory = injector.getInstance(ColoredCarFactory.class); |
| |
| carFactory.equals(carFactory); |
| carFactory.hashCode(); |
| carFactory.toString(); |
| } |
| |
| public void testAssistedInjectConstructorAndAssistedFactoryParameterMustNotMix() { |
| try { |
| Guice.createInjector( |
| new AbstractModule() { |
| @Override |
| protected void configure() { |
| bind(Double.class).toInstance(5.0d); |
| bind(AssistedParamsFactory.class) |
| .toProvider( |
| FactoryProvider.newFactory(AssistedParamsFactory.class, Mustang.class)); |
| } |
| }); |
| fail(); |
| } catch (CreationException expected) { |
| assertContains( |
| expected.getMessage(), |
| "Factory method " |
| + AssistedParamsFactory.class.getName() |
| + ".create() has an @Assisted parameter, which " |
| + "is incompatible with the deprecated @AssistedInject annotation."); |
| } |
| } |
| |
| interface AssistedParamsFactory { |
| Car create(@Assisted Color color); |
| } |
| |
| interface GenericColoredCarFactory<T extends Car> { |
| T create(Color color); |
| } |
| |
| public void testGenericAssistedFactory() { |
| final TypeLiteral<GenericColoredCarFactory<Mustang>> mustangTypeLiteral = |
| new TypeLiteral<GenericColoredCarFactory<Mustang>>() {}; |
| final TypeLiteral<GenericColoredCarFactory<Camaro>> camaroTypeLiteral = |
| new TypeLiteral<GenericColoredCarFactory<Camaro>>() {}; |
| |
| Injector injector = |
| Guice.createInjector( |
| new AbstractModule() { |
| @Override |
| protected void configure() { |
| bind(Double.class).toInstance(5.0d); |
| bind(int.class).annotatedWith(Names.named("horsePower")).toInstance(250); |
| bind(int.class).annotatedWith(Names.named("modelYear")).toInstance(1984); |
| bind(mustangTypeLiteral) |
| .toProvider( |
| FactoryProvider.newFactory( |
| mustangTypeLiteral, TypeLiteral.get(Mustang.class))); |
| bind(camaroTypeLiteral) |
| .toProvider( |
| FactoryProvider.newFactory( |
| camaroTypeLiteral, TypeLiteral.get(Camaro.class))); |
| } |
| }); |
| |
| GenericColoredCarFactory<Mustang> mustangFactory = |
| injector.getInstance(Key.get(mustangTypeLiteral)); |
| GenericColoredCarFactory<Camaro> camaroFactory = |
| injector.getInstance(Key.get(camaroTypeLiteral)); |
| |
| Mustang blueMustang = mustangFactory.create(Color.BLUE); |
| assertEquals(Color.BLUE, blueMustang.color); |
| assertEquals(5.0d, blueMustang.engineSize, 0.0); |
| |
| Camaro redCamaro = camaroFactory.create(Color.RED); |
| assertEquals(Color.RED, redCamaro.color); |
| assertEquals(1984, redCamaro.modelYear); |
| assertEquals(250, redCamaro.horsePower); |
| } |
| |
| @SuppressWarnings("unused") |
| public interface Insurance<T extends Car> {} |
| |
| public static class MustangInsurance implements Insurance<Mustang> { |
| private final double premium; |
| private final double limit; |
| |
| @SuppressWarnings("unused") |
| private Mustang car; |
| |
| @AssistedInject |
| public MustangInsurance( |
| @Named("lowLimit") double limit, @Assisted Mustang car, @Assisted double premium) { |
| this.premium = premium; |
| this.limit = limit; |
| this.car = car; |
| } |
| |
| public void sell() {} |
| } |
| |
| public static class CamaroInsurance implements Insurance<Camaro> { |
| private final double premium; |
| private final double limit; |
| |
| @SuppressWarnings("unused") |
| private Camaro car; |
| |
| @AssistedInject |
| public CamaroInsurance( |
| @Named("highLimit") double limit, @Assisted Camaro car, @Assisted double premium) { |
| this.premium = premium; |
| this.limit = limit; |
| this.car = car; |
| } |
| |
| public void sell() {} |
| } |
| |
| public interface MustangInsuranceFactory { |
| public Insurance<Mustang> create(Mustang car, double premium); |
| } |
| |
| public interface CamaroInsuranceFactory { |
| public Insurance<Camaro> create(Camaro car, double premium); |
| } |
| |
| public void testAssistedFactoryForConcreteType() { |
| |
| Injector injector = |
| Guice.createInjector( |
| new AbstractModule() { |
| @Override |
| protected void configure() { |
| bind(Double.class).annotatedWith(Names.named("lowLimit")).toInstance(50000.0d); |
| bind(Double.class).annotatedWith(Names.named("highLimit")).toInstance(100000.0d); |
| bind(MustangInsuranceFactory.class) |
| .toProvider( |
| FactoryProvider.newFactory( |
| MustangInsuranceFactory.class, MustangInsurance.class)); |
| bind(CamaroInsuranceFactory.class) |
| .toProvider( |
| FactoryProvider.newFactory( |
| CamaroInsuranceFactory.class, CamaroInsurance.class)); |
| } |
| }); |
| |
| MustangInsuranceFactory mustangInsuranceFactory = |
| injector.getInstance(MustangInsuranceFactory.class); |
| CamaroInsuranceFactory camaroInsuranceFactory = |
| injector.getInstance(CamaroInsuranceFactory.class); |
| |
| Mustang mustang = new Mustang(5000d, Color.BLACK); |
| MustangInsurance mustangPolicy = |
| (MustangInsurance) mustangInsuranceFactory.create(mustang, 800.0d); |
| assertEquals(800.0d, mustangPolicy.premium, 0.0); |
| assertEquals(50000.0d, mustangPolicy.limit, 0.0); |
| |
| Camaro camaro = new Camaro(3000, 1967, Color.BLUE); |
| CamaroInsurance camaroPolicy = (CamaroInsurance) camaroInsuranceFactory.create(camaro, 800.0d); |
| assertEquals(800.0d, camaroPolicy.premium, 0.0); |
| assertEquals(100000.0d, camaroPolicy.limit, 0.0); |
| } |
| |
| public interface InsuranceFactory<T extends Car> { |
| public Insurance<T> create(T car, double premium); |
| } |
| |
| public void testAssistedFactoryForParameterizedType() { |
| final TypeLiteral<InsuranceFactory<Mustang>> mustangInsuranceFactoryType = |
| new TypeLiteral<InsuranceFactory<Mustang>>() {}; |
| final TypeLiteral<InsuranceFactory<Camaro>> camaroInsuranceFactoryType = |
| new TypeLiteral<InsuranceFactory<Camaro>>() {}; |
| |
| Injector injector = |
| Guice.createInjector( |
| new AbstractModule() { |
| @Override |
| protected void configure() { |
| bind(Double.class).annotatedWith(Names.named("lowLimit")).toInstance(50000.0d); |
| bind(Double.class).annotatedWith(Names.named("highLimit")).toInstance(100000.0d); |
| bind(mustangInsuranceFactoryType) |
| .toProvider( |
| FactoryProvider.newFactory( |
| mustangInsuranceFactoryType, TypeLiteral.get(MustangInsurance.class))); |
| bind(camaroInsuranceFactoryType) |
| .toProvider( |
| FactoryProvider.newFactory( |
| camaroInsuranceFactoryType, TypeLiteral.get(CamaroInsurance.class))); |
| } |
| }); |
| |
| InsuranceFactory<Mustang> mustangInsuranceFactory = |
| injector.getInstance(Key.get(mustangInsuranceFactoryType)); |
| InsuranceFactory<Camaro> camaroInsuranceFactory = |
| injector.getInstance(Key.get(camaroInsuranceFactoryType)); |
| |
| Mustang mustang = new Mustang(5000d, Color.BLACK); |
| MustangInsurance mustangPolicy = |
| (MustangInsurance) mustangInsuranceFactory.create(mustang, 800.0d); |
| assertEquals(800.0d, mustangPolicy.premium, 0.0); |
| assertEquals(50000.0d, mustangPolicy.limit, 0.0); |
| |
| Camaro camaro = new Camaro(3000, 1967, Color.BLUE); |
| CamaroInsurance camaroPolicy = (CamaroInsurance) camaroInsuranceFactory.create(camaro, 800.0d); |
| assertEquals(800.0d, camaroPolicy.premium, 0.0); |
| assertEquals(100000.0d, camaroPolicy.limit, 0.0); |
| } |
| |
| public static class AutoInsurance<T extends Car> implements Insurance<T> { |
| private final double premium; |
| private final double limit; |
| private final T car; |
| |
| @AssistedInject |
| public AutoInsurance(double limit, @Assisted T car, @Assisted double premium) { |
| this.limit = limit; |
| this.car = car; |
| this.premium = premium; |
| } |
| |
| public void sell() {} |
| } |
| |
| public void testAssistedFactoryForTypeVariableParameters() { |
| final TypeLiteral<InsuranceFactory<Camaro>> camaroInsuranceFactoryType = |
| new TypeLiteral<InsuranceFactory<Camaro>>() {}; |
| |
| Injector injector = |
| Guice.createInjector( |
| new AbstractModule() { |
| @Override |
| protected void configure() { |
| bind(Double.class).toInstance(50000.0d); |
| bind(camaroInsuranceFactoryType) |
| .toProvider( |
| FactoryProvider.newFactory( |
| camaroInsuranceFactoryType, |
| new TypeLiteral<AutoInsurance<Camaro>>() {})); |
| } |
| }); |
| |
| InsuranceFactory<Camaro> camaroInsuranceFactory = |
| injector.getInstance(Key.get(camaroInsuranceFactoryType)); |
| |
| Camaro camaro = new Camaro(3000, 1967, Color.BLUE); |
| AutoInsurance<?> camaroPolicy = |
| (AutoInsurance<?>) camaroInsuranceFactory.create(camaro, 800.0d); |
| assertEquals(800.0d, camaroPolicy.premium, 0.0); |
| assertEquals(50000.0d, camaroPolicy.limit, 0.0); |
| assertEquals(camaro, camaroPolicy.car); |
| } |
| |
| public void testDuplicateAssistedFactoryBinding() { |
| Injector injector = |
| Guice.createInjector( |
| new AbstractModule() { |
| @Override |
| protected void configure() { |
| bind(Double.class).toInstance(5.0d); |
| bind(ColoredCarFactory.class) |
| .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, Mustang.class)); |
| bind(ColoredCarFactory.class) |
| .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, Mustang.class)); |
| } |
| }); |
| ColoredCarFactory carFactory = injector.getInstance(ColoredCarFactory.class); |
| |
| Mustang blueMustang = (Mustang) carFactory.create(Color.BLUE); |
| assertEquals(Color.BLUE, blueMustang.color); |
| assertEquals(5.0d, blueMustang.engineSize, 0.0); |
| |
| Mustang redMustang = (Mustang) carFactory.create(Color.RED); |
| assertEquals(Color.RED, redMustang.color); |
| assertEquals(5.0d, redMustang.engineSize, 0.0); |
| } |
| |
| public interface Equals { |
| |
| enum ComparisonMethod { |
| SHALLOW, |
| DEEP; |
| } |
| |
| interface Factory { |
| Equals equals(Equals.ComparisonMethod comparisonMethod); |
| } |
| |
| public static class Impl implements Equals { |
| private final double sigma; |
| private final ComparisonMethod comparisonMethod; |
| |
| @Inject |
| public Impl(double sigma, @Assisted ComparisonMethod comparisonMethod) { |
| this.sigma = sigma; |
| this.comparisonMethod = comparisonMethod; |
| } |
| } |
| } |
| |
| public void testFactoryMethodCalledEquals() { |
| Injector injector = |
| Guice.createInjector( |
| new AbstractModule() { |
| @Override |
| protected void configure() { |
| bind(Double.class).toInstance(0.01d); |
| bind(Equals.Factory.class) |
| .toProvider( |
| FactoryProvider.newFactory(Equals.Factory.class, Equals.Impl.class)); |
| } |
| }); |
| Equals.Factory equalsFactory = injector.getInstance(Equals.Factory.class); |
| Equals.Impl shallowEquals = (Impl) equalsFactory.equals(ComparisonMethod.SHALLOW); |
| assertEquals(ComparisonMethod.SHALLOW, shallowEquals.comparisonMethod); |
| assertEquals(0.01d, shallowEquals.sigma, 0.0); |
| } |
| } |