PageRenderTime 26ms CodeModel.GetById 0ms RepoModel.GetById 1ms app.codeStats 0ms

/extensions/assistedinject/test/com/google/inject/assistedinject/FactoryProviderTest.java

https://gitlab.com/metamorphiccode/guice
Java | 840 lines | 697 code | 124 blank | 19 comment | 0 complexity | eae1f031a69fdabed5d3b459697360b8 MD5 | raw file
  1. /**
  2. * Copyright (C) 2007 Google Inc.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package com.google.inject.assistedinject;
  17. import static com.google.inject.Asserts.assertContains;
  18. import com.google.common.collect.ImmutableSet;
  19. import com.google.inject.AbstractModule;
  20. import com.google.inject.Binding;
  21. import com.google.inject.ConfigurationException;
  22. import com.google.inject.CreationException;
  23. import com.google.inject.Guice;
  24. import com.google.inject.Inject;
  25. import com.google.inject.Injector;
  26. import com.google.inject.Key;
  27. import com.google.inject.Provider;
  28. import com.google.inject.TypeLiteral;
  29. import com.google.inject.assistedinject.FactoryProviderTest.Equals.ComparisonMethod;
  30. import com.google.inject.assistedinject.FactoryProviderTest.Equals.Impl;
  31. import com.google.inject.name.Named;
  32. import com.google.inject.name.Names;
  33. import com.google.inject.spi.Dependency;
  34. import com.google.inject.spi.HasDependencies;
  35. import junit.framework.TestCase;
  36. import java.util.Collection;
  37. import java.util.Collections;
  38. import java.util.Set;
  39. /**
  40. * @author jmourits@google.com (Jerome Mourits)
  41. * @author jessewilson@google.com (Jesse Wilson)
  42. */
  43. @SuppressWarnings("deprecation")
  44. public class FactoryProviderTest extends TestCase {
  45. private enum Color { BLUE, GREEN, RED, GRAY, BLACK, ORANGE, PINK }
  46. public void testAssistedFactory() {
  47. Injector injector = Guice.createInjector(new AbstractModule() {
  48. @Override
  49. protected void configure() {
  50. bind(Double.class).toInstance(5.0d);
  51. bind(ColoredCarFactory.class)
  52. .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, Mustang.class));
  53. }
  54. });
  55. ColoredCarFactory carFactory = injector.getInstance(ColoredCarFactory.class);
  56. Mustang blueMustang = (Mustang) carFactory.create(Color.BLUE);
  57. assertEquals(Color.BLUE, blueMustang.color);
  58. assertEquals(5.0d, blueMustang.engineSize);
  59. Mustang redMustang = (Mustang) carFactory.create(Color.RED);
  60. assertEquals(Color.RED, redMustang.color);
  61. assertEquals(5.0d, redMustang.engineSize);
  62. }
  63. public void testFactoryBindingDependencies() {
  64. Injector injector = Guice.createInjector(new AbstractModule() {
  65. @Override
  66. protected void configure() {
  67. bind(Double.class).toInstance(5.0d);
  68. bind(ColoredCarFactory.class)
  69. .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, Mustang.class));
  70. }
  71. });
  72. Binding<?> binding = injector.getBinding(ColoredCarFactory.class);
  73. HasDependencies hasDependencies = (HasDependencies) binding;
  74. assertEquals(ImmutableSet.<Dependency<?>>of(Dependency.get(Key.get(double.class))),
  75. hasDependencies.getDependencies());
  76. }
  77. public void testAssistedFactoryWithAnnotations() {
  78. Injector injector = Guice.createInjector(new AbstractModule() {
  79. @Override
  80. protected void configure() {
  81. bind(int.class).annotatedWith(Names.named("horsePower")).toInstance(250);
  82. bind(int.class).annotatedWith(Names.named("modelYear")).toInstance(1984);
  83. bind(ColoredCarFactory.class)
  84. .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, Camaro.class));
  85. }
  86. });
  87. ColoredCarFactory carFactory = injector.getInstance(ColoredCarFactory.class);
  88. Camaro blueCamaro = (Camaro) carFactory.create(Color.BLUE);
  89. assertEquals(Color.BLUE, blueCamaro.color);
  90. assertEquals(1984, blueCamaro.modelYear);
  91. assertEquals(250, blueCamaro.horsePower);
  92. Camaro redCamaro = (Camaro) carFactory.create(Color.RED);
  93. assertEquals(Color.RED, redCamaro.color);
  94. assertEquals(1984, redCamaro.modelYear);
  95. assertEquals(250, redCamaro.horsePower);
  96. }
  97. interface Car {
  98. }
  99. interface ColoredCarFactory {
  100. Car create(Color color);
  101. }
  102. public static class Mustang implements Car {
  103. private final double engineSize;
  104. private final Color color;
  105. @AssistedInject
  106. public Mustang(double engineSize, @Assisted Color color) {
  107. this.engineSize = engineSize;
  108. this.color = color;
  109. }
  110. }
  111. public static class Camaro implements Car {
  112. private final int horsePower;
  113. private final int modelYear;
  114. private final Color color;
  115. @AssistedInject
  116. public Camaro(
  117. @Named("horsePower")int horsePower,
  118. @Named("modelYear")int modelYear,
  119. @Assisted Color color) {
  120. this.horsePower = horsePower;
  121. this.modelYear = modelYear;
  122. this.color = color;
  123. }
  124. }
  125. interface SummerCarFactory {
  126. Car create(Color color, boolean convertable);
  127. Car createConvertible(Color color);
  128. }
  129. public void testFactoryWithMultipleMethods() {
  130. Injector injector = Guice.createInjector(new AbstractModule() {
  131. @Override
  132. protected void configure() {
  133. bind(float.class).toInstance(140f);
  134. bind(SummerCarFactory.class).toProvider(
  135. FactoryProvider.newFactory(SummerCarFactory.class, Corvette.class));
  136. }
  137. });
  138. SummerCarFactory carFactory = injector.getInstance(SummerCarFactory.class);
  139. Corvette blueCorvette = (Corvette) carFactory.createConvertible(Color.BLUE);
  140. assertEquals(Color.BLUE, blueCorvette.color);
  141. assertEquals(100f, blueCorvette.maxMph);
  142. assertTrue(blueCorvette.isConvertable);
  143. Corvette redCorvette = (Corvette) carFactory.create(Color.RED, false);
  144. assertEquals(Color.RED, redCorvette.color);
  145. assertEquals(140f, redCorvette.maxMph);
  146. assertFalse(redCorvette.isConvertable);
  147. }
  148. public static class Corvette implements Car {
  149. private boolean isConvertable;
  150. private Color color;
  151. private float maxMph;
  152. @AssistedInject
  153. public Corvette(@Assisted Color color) {
  154. this(color, 100f, true);
  155. }
  156. @SuppressWarnings("unused")
  157. public Corvette(@Assisted Color color, @Assisted boolean isConvertable) {
  158. throw new IllegalStateException("Not an @AssistedInject constructor");
  159. }
  160. @AssistedInject
  161. public Corvette(@Assisted Color color, Float maxMph, @Assisted boolean isConvertable) {
  162. this.isConvertable = isConvertable;
  163. this.color = color;
  164. this.maxMph = maxMph;
  165. }
  166. }
  167. public void testFactoryMethodsMismatch() {
  168. try {
  169. FactoryProvider.newFactory(SummerCarFactory.class, Beetle.class);
  170. fail();
  171. } catch(ConfigurationException e) {
  172. assertContains(e.getMessage(), "Constructor mismatch");
  173. }
  174. }
  175. public static class Beetle implements Car {
  176. @AssistedInject
  177. @SuppressWarnings("unused")
  178. public Beetle(@Assisted Color color) {
  179. throw new IllegalStateException("Conflicting constructors");
  180. }
  181. @AssistedInject
  182. @SuppressWarnings("unused")
  183. public Beetle(@Assisted Color color, @Assisted boolean isConvertable) {
  184. throw new IllegalStateException("Conflicting constructors");
  185. }
  186. @AssistedInject
  187. @SuppressWarnings("unused")
  188. public Beetle(@Assisted Color color, @Assisted boolean isConvertable, float maxMph) {
  189. throw new IllegalStateException("Conflicting constructors");
  190. }
  191. }
  192. public void testMethodsAndFieldsGetInjected() {
  193. Injector injector = Guice.createInjector(new AbstractModule() {
  194. @Override
  195. protected void configure() {
  196. bind(String.class).toInstance("turbo");
  197. bind(int.class).toInstance(911);
  198. bind(double.class).toInstance(50000d);
  199. bind(ColoredCarFactory.class)
  200. .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, Porshe.class));
  201. }
  202. });
  203. ColoredCarFactory carFactory = injector.getInstance(ColoredCarFactory.class);
  204. Porshe grayPorshe = (Porshe) carFactory.create(Color.GRAY);
  205. assertEquals(Color.GRAY, grayPorshe.color);
  206. assertEquals(50000d, grayPorshe.price);
  207. assertEquals(911, grayPorshe.model);
  208. assertEquals("turbo", grayPorshe.name);
  209. }
  210. public static class Porshe implements Car {
  211. private final Color color;
  212. private final double price;
  213. private @Inject String name;
  214. private int model;
  215. @AssistedInject
  216. public Porshe(@Assisted Color color, double price) {
  217. this.color = color;
  218. this.price = price;
  219. }
  220. @Inject void setModel(int model) {
  221. this.model = model;
  222. }
  223. }
  224. public void testProviderInjection() {
  225. Injector injector = Guice.createInjector(new AbstractModule() {
  226. @Override
  227. protected void configure() {
  228. bind(String.class).toInstance("trans am");
  229. bind(ColoredCarFactory.class)
  230. .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, Firebird.class));
  231. }
  232. });
  233. ColoredCarFactory carFactory = injector.getInstance(ColoredCarFactory.class);
  234. Firebird blackFirebird = (Firebird) carFactory.create(Color.BLACK);
  235. assertEquals(Color.BLACK, blackFirebird.color);
  236. assertEquals("trans am", blackFirebird.modifiersProvider.get());
  237. }
  238. public static class Firebird implements Car {
  239. private final Provider<String> modifiersProvider;
  240. private final Color color;
  241. @AssistedInject
  242. public Firebird(Provider<String> modifiersProvider, @Assisted Color color) {
  243. this.modifiersProvider = modifiersProvider;
  244. this.color = color;
  245. }
  246. }
  247. public void testTypeTokenInjection() {
  248. Injector injector = Guice.createInjector(new AbstractModule() {
  249. @Override
  250. protected void configure() {
  251. bind(new TypeLiteral<Set<String>>() {}).toInstance(Collections.singleton("Flux Capacitor"));
  252. bind(new TypeLiteral<Set<Integer>>() {}).toInstance(Collections.singleton(88));
  253. bind(ColoredCarFactory.class)
  254. .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, DeLorean.class));
  255. }
  256. });
  257. ColoredCarFactory carFactory = injector.getInstance(ColoredCarFactory.class);
  258. DeLorean deLorean = (DeLorean) carFactory.create(Color.GRAY);
  259. assertEquals(Color.GRAY, deLorean.color);
  260. assertEquals("Flux Capacitor", deLorean.features.iterator().next());
  261. assertEquals(new Integer(88), deLorean.featureActivationSpeeds.iterator().next());
  262. }
  263. public static class DeLorean implements Car {
  264. private final Set<String> features;
  265. private final Set<Integer> featureActivationSpeeds;
  266. private final Color color;
  267. @AssistedInject
  268. public DeLorean(
  269. Set<String> extraFeatures, Set<Integer> featureActivationSpeeds, @Assisted Color color) {
  270. this.features = extraFeatures;
  271. this.featureActivationSpeeds = featureActivationSpeeds;
  272. this.color = color;
  273. }
  274. }
  275. public void testTypeTokenProviderInjection() {
  276. Injector injector = Guice.createInjector(new AbstractModule() {
  277. @Override
  278. protected void configure() {
  279. bind(new TypeLiteral<Set<String>>() { }).toInstance(Collections.singleton("Datsun"));
  280. bind(ColoredCarFactory.class)
  281. .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, Z.class));
  282. }
  283. });
  284. ColoredCarFactory carFactory = injector.getInstance(ColoredCarFactory.class);
  285. Z orangeZ = (Z) carFactory.create(Color.ORANGE);
  286. assertEquals(Color.ORANGE, orangeZ.color);
  287. assertEquals("Datsun", orangeZ.manufacturersProvider.get().iterator().next());
  288. }
  289. public static class Z implements Car {
  290. private final Provider<Set<String>> manufacturersProvider;
  291. private final Color color;
  292. @AssistedInject
  293. public Z(Provider<Set<String>> manufacturersProvider, @Assisted Color color) {
  294. this.manufacturersProvider = manufacturersProvider;
  295. this.color = color;
  296. }
  297. }
  298. public static class Prius implements Car {
  299. @SuppressWarnings("unused")
  300. private final Color color;
  301. @AssistedInject
  302. private Prius(@Assisted Color color) {
  303. this.color = color;
  304. }
  305. }
  306. public void testAssistInjectionInNonPublicConstructor() {
  307. Injector injector = Guice.createInjector(new AbstractModule() {
  308. @Override
  309. protected void configure() {
  310. bind(ColoredCarFactory.class)
  311. .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, Prius.class));
  312. }
  313. });
  314. injector.getInstance(ColoredCarFactory.class).create(Color.ORANGE);
  315. }
  316. public static class ExplodingCar implements Car {
  317. @AssistedInject
  318. public ExplodingCar(@SuppressWarnings("unused") @Assisted Color color) {
  319. throw new IllegalStateException("kaboom!");
  320. }
  321. }
  322. public void testExceptionDuringConstruction() {
  323. Injector injector = Guice.createInjector(new AbstractModule() {
  324. @Override
  325. protected void configure() {
  326. bind(ColoredCarFactory.class).toProvider(
  327. FactoryProvider.newFactory(ColoredCarFactory.class, ExplodingCar.class));
  328. }
  329. });
  330. try {
  331. injector.getInstance(ColoredCarFactory.class).create(Color.ORANGE);
  332. fail();
  333. } catch (IllegalStateException e) {
  334. assertEquals("kaboom!", e.getMessage());
  335. }
  336. }
  337. public static class DefectiveCar implements Car {
  338. @AssistedInject
  339. public DefectiveCar() throws ExplosionException {
  340. throw new ExplosionException();
  341. }
  342. }
  343. public static class ExplosionException extends Exception { }
  344. public static class FireException extends Exception { }
  345. public interface DefectiveCarFactoryWithNoExceptions {
  346. Car createCar();
  347. }
  348. public interface DefectiveCarFactory {
  349. Car createCar() throws FireException;
  350. }
  351. public void testFactoryMethodMustDeclareAllConstructorExceptions() {
  352. try {
  353. FactoryProvider.newFactory(DefectiveCarFactoryWithNoExceptions.class, DefectiveCar.class);
  354. fail();
  355. } catch (ConfigurationException expected) {
  356. assertContains(expected.getMessage(), "no compatible exception is thrown");
  357. }
  358. }
  359. public interface CorrectDefectiveCarFactory {
  360. Car createCar() throws FireException, ExplosionException;
  361. }
  362. public void testConstructorExceptionsAreThrownByFactory() {
  363. Injector injector = Guice.createInjector(new AbstractModule() {
  364. @Override
  365. protected void configure() {
  366. bind(CorrectDefectiveCarFactory.class).toProvider(
  367. FactoryProvider.newFactory(
  368. CorrectDefectiveCarFactory.class, DefectiveCar.class));
  369. }
  370. });
  371. try {
  372. injector.getInstance(CorrectDefectiveCarFactory.class).createCar();
  373. fail();
  374. } catch (FireException e) {
  375. fail();
  376. } catch (ExplosionException expected) {
  377. }
  378. }
  379. public static class MultipleConstructorDefectiveCar implements Car {
  380. @AssistedInject
  381. public MultipleConstructorDefectiveCar() throws ExplosionException {
  382. throw new ExplosionException();
  383. }
  384. @AssistedInject
  385. public MultipleConstructorDefectiveCar(@SuppressWarnings("unused") @Assisted Color c)
  386. throws FireException {
  387. throw new FireException();
  388. }
  389. }
  390. public interface MultipleConstructorDefectiveCarFactory {
  391. Car createCar() throws ExplosionException;
  392. Car createCar(Color r) throws FireException;
  393. }
  394. public void testMultipleConstructorExceptionMatching() {
  395. Injector injector = Guice.createInjector(new AbstractModule() {
  396. @Override
  397. protected void configure() {
  398. bind(MultipleConstructorDefectiveCarFactory.class).toProvider(
  399. FactoryProvider.newFactory(
  400. MultipleConstructorDefectiveCarFactory.class,
  401. MultipleConstructorDefectiveCar.class));
  402. }
  403. });
  404. MultipleConstructorDefectiveCarFactory factory
  405. = injector.getInstance(MultipleConstructorDefectiveCarFactory.class);
  406. try {
  407. factory.createCar();
  408. fail();
  409. } catch (ExplosionException expected) {
  410. }
  411. try {
  412. factory.createCar(Color.RED);
  413. fail();
  414. } catch (FireException expected) {
  415. }
  416. }
  417. public static class WildcardCollection {
  418. public interface Factory {
  419. WildcardCollection create(Collection<?> items);
  420. }
  421. @AssistedInject
  422. public WildcardCollection(@SuppressWarnings("unused") @Assisted Collection<?> items) { }
  423. }
  424. public void testWildcardGenerics() {
  425. Injector injector = Guice.createInjector(new AbstractModule() {
  426. @Override
  427. protected void configure() {
  428. bind(WildcardCollection.Factory.class).toProvider(
  429. FactoryProvider.newFactory(
  430. WildcardCollection.Factory.class,
  431. WildcardCollection.class));
  432. }
  433. });
  434. WildcardCollection.Factory factory = injector.getInstance(WildcardCollection.Factory.class);
  435. factory.create(Collections.emptyList());
  436. }
  437. public static class SteeringWheel {}
  438. public static class Fiat implements Car {
  439. @SuppressWarnings("unused")
  440. private final SteeringWheel steeringWheel;
  441. @SuppressWarnings("unused")
  442. private final Color color;
  443. @AssistedInject
  444. public Fiat(SteeringWheel steeringWheel, @Assisted Color color) {
  445. this.steeringWheel = steeringWheel;
  446. this.color = color;
  447. }
  448. }
  449. public void testFactoryWithImplicitBindings() {
  450. Injector injector = Guice.createInjector(new AbstractModule() {
  451. @Override
  452. protected void configure() {
  453. bind(ColoredCarFactory.class).toProvider(
  454. FactoryProvider.newFactory(
  455. ColoredCarFactory.class,
  456. Fiat.class));
  457. }
  458. });
  459. ColoredCarFactory coloredCarFactory = injector.getInstance(ColoredCarFactory.class);
  460. Fiat fiat = (Fiat) coloredCarFactory.create(Color.GREEN);
  461. assertEquals(Color.GREEN, fiat.color);
  462. assertNotNull(fiat.steeringWheel);
  463. }
  464. public void testFactoryFailsWithMissingBinding() {
  465. try {
  466. Guice.createInjector(new AbstractModule() {
  467. @Override protected void configure() {
  468. bind(ColoredCarFactory.class)
  469. .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, Mustang.class));
  470. }
  471. });
  472. fail();
  473. } catch (CreationException expected) {
  474. assertContains(expected.getMessage(),
  475. "1) Parameter of type 'double' is not injectable or annotated with @Assisted");
  476. }
  477. }
  478. public void testMethodsDeclaredInObject() {
  479. Injector injector = Guice.createInjector(new AbstractModule() {
  480. @Override protected void configure() {
  481. bind(Double.class).toInstance(5.0d);
  482. bind(ColoredCarFactory.class)
  483. .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, Mustang.class));
  484. }
  485. });
  486. ColoredCarFactory carFactory = injector.getInstance(ColoredCarFactory.class);
  487. carFactory.equals(carFactory);
  488. carFactory.hashCode();
  489. carFactory.toString();
  490. }
  491. public void testAssistedInjectConstructorAndAssistedFactoryParameterMustNotMix() {
  492. try {
  493. Guice.createInjector(new AbstractModule() {
  494. @Override protected void configure() {
  495. bind(Double.class).toInstance(5.0d);
  496. bind(AssistedParamsFactory.class)
  497. .toProvider(FactoryProvider.newFactory(AssistedParamsFactory.class, Mustang.class));
  498. }
  499. });
  500. fail();
  501. } catch (CreationException expected) {
  502. assertContains(expected.getMessage(), "Factory method "
  503. + AssistedParamsFactory.class.getName() + ".create() has an @Assisted parameter, which "
  504. + "is incompatible with the deprecated @AssistedInject annotation.");
  505. }
  506. }
  507. interface AssistedParamsFactory {
  508. Car create(@Assisted Color color);
  509. }
  510. interface GenericColoredCarFactory<T extends Car> {
  511. T create(Color color);
  512. }
  513. public void testGenericAssistedFactory() {
  514. final TypeLiteral<GenericColoredCarFactory<Mustang>> mustangTypeLiteral
  515. = new TypeLiteral<GenericColoredCarFactory<Mustang>>() {};
  516. final TypeLiteral<GenericColoredCarFactory<Camaro>> camaroTypeLiteral
  517. = new TypeLiteral<GenericColoredCarFactory<Camaro>>() {};
  518. Injector injector = Guice.createInjector(new AbstractModule() {
  519. @Override
  520. protected void configure() {
  521. bind(Double.class).toInstance(5.0d);
  522. bind(int.class).annotatedWith(Names.named("horsePower")).toInstance(250);
  523. bind(int.class).annotatedWith(Names.named("modelYear")).toInstance(1984);
  524. bind(mustangTypeLiteral).toProvider(
  525. FactoryProvider.newFactory(mustangTypeLiteral, TypeLiteral.get(Mustang.class)));
  526. bind(camaroTypeLiteral).toProvider(
  527. FactoryProvider.newFactory(camaroTypeLiteral, TypeLiteral.get(Camaro.class)));
  528. }
  529. });
  530. GenericColoredCarFactory<Mustang> mustangFactory
  531. = injector.getInstance(Key.get(mustangTypeLiteral));
  532. GenericColoredCarFactory<Camaro> camaroFactory
  533. = injector.getInstance(Key.get(camaroTypeLiteral));
  534. Mustang blueMustang = mustangFactory.create(Color.BLUE);
  535. assertEquals(Color.BLUE, blueMustang.color);
  536. assertEquals(5.0d, blueMustang.engineSize);
  537. Camaro redCamaro = camaroFactory.create(Color.RED);
  538. assertEquals(Color.RED, redCamaro.color);
  539. assertEquals(1984, redCamaro.modelYear);
  540. assertEquals(250, redCamaro.horsePower);
  541. }
  542. @SuppressWarnings("unused")
  543. public interface Insurance<T extends Car> {
  544. }
  545. public static class MustangInsurance implements Insurance<Mustang> {
  546. private final double premium;
  547. private final double limit;
  548. @SuppressWarnings("unused") private Mustang car;
  549. @AssistedInject
  550. public MustangInsurance(@Named("lowLimit") double limit, @Assisted Mustang car,
  551. @Assisted double premium) {
  552. this.premium = premium;
  553. this.limit = limit;
  554. this.car = car;
  555. }
  556. public void sell() {}
  557. }
  558. public static class CamaroInsurance implements Insurance<Camaro> {
  559. private final double premium;
  560. private final double limit;
  561. @SuppressWarnings("unused") private Camaro car;
  562. @AssistedInject
  563. public CamaroInsurance(@Named("highLimit") double limit, @Assisted Camaro car,
  564. @Assisted double premium) {
  565. this.premium = premium;
  566. this.limit = limit;
  567. this.car = car;
  568. }
  569. public void sell() {}
  570. }
  571. public interface MustangInsuranceFactory {
  572. public Insurance<Mustang> create(Mustang car, double premium);
  573. }
  574. public interface CamaroInsuranceFactory {
  575. public Insurance<Camaro> create(Camaro car, double premium);
  576. }
  577. public void testAssistedFactoryForConcreteType() {
  578. Injector injector = Guice.createInjector(new AbstractModule() {
  579. @Override
  580. protected void configure() {
  581. bind(Double.class).annotatedWith(Names.named("lowLimit")).toInstance(50000.0d);
  582. bind(Double.class).annotatedWith(Names.named("highLimit")).toInstance(100000.0d);
  583. bind(MustangInsuranceFactory.class).toProvider(
  584. FactoryProvider.newFactory(MustangInsuranceFactory.class, MustangInsurance.class));
  585. bind(CamaroInsuranceFactory.class).toProvider(
  586. FactoryProvider.newFactory(CamaroInsuranceFactory.class, CamaroInsurance.class));
  587. }
  588. });
  589. MustangInsuranceFactory mustangInsuranceFactory =
  590. injector.getInstance(MustangInsuranceFactory.class);
  591. CamaroInsuranceFactory camaroInsuranceFactory =
  592. injector.getInstance(CamaroInsuranceFactory.class);
  593. Mustang mustang = new Mustang(5000d, Color.BLACK);
  594. MustangInsurance mustangPolicy =
  595. (MustangInsurance) mustangInsuranceFactory.create(mustang, 800.0d);
  596. assertEquals(800.0d, mustangPolicy.premium);
  597. assertEquals(50000.0d, mustangPolicy.limit);
  598. Camaro camaro = new Camaro(3000, 1967, Color.BLUE);
  599. CamaroInsurance camaroPolicy = (CamaroInsurance) camaroInsuranceFactory.create(camaro, 800.0d);
  600. assertEquals(800.0d, camaroPolicy.premium);
  601. assertEquals(100000.0d, camaroPolicy.limit);
  602. }
  603. public interface InsuranceFactory<T extends Car> {
  604. public Insurance<T> create(T car, double premium);
  605. }
  606. public void testAssistedFactoryForParameterizedType() {
  607. final TypeLiteral<InsuranceFactory<Mustang>> mustangInsuranceFactoryType =
  608. new TypeLiteral<InsuranceFactory<Mustang>>() {};
  609. final TypeLiteral<InsuranceFactory<Camaro>> camaroInsuranceFactoryType =
  610. new TypeLiteral<InsuranceFactory<Camaro>>() {};
  611. Injector injector = Guice.createInjector(new AbstractModule() {
  612. @Override
  613. protected void configure() {
  614. bind(Double.class).annotatedWith(Names.named("lowLimit")).toInstance(50000.0d);
  615. bind(Double.class).annotatedWith(Names.named("highLimit")).toInstance(100000.0d);
  616. bind(mustangInsuranceFactoryType).toProvider(FactoryProvider.newFactory(
  617. mustangInsuranceFactoryType, TypeLiteral.get(MustangInsurance.class)));
  618. bind(camaroInsuranceFactoryType).toProvider(FactoryProvider.newFactory(
  619. camaroInsuranceFactoryType, TypeLiteral.get(CamaroInsurance.class)));
  620. }
  621. });
  622. InsuranceFactory<Mustang> mustangInsuranceFactory =
  623. injector.getInstance(Key.get(mustangInsuranceFactoryType));
  624. InsuranceFactory<Camaro> camaroInsuranceFactory =
  625. injector.getInstance(Key.get(camaroInsuranceFactoryType));
  626. Mustang mustang = new Mustang(5000d, Color.BLACK);
  627. MustangInsurance mustangPolicy =
  628. (MustangInsurance) mustangInsuranceFactory.create(mustang, 800.0d);
  629. assertEquals(800.0d, mustangPolicy.premium);
  630. assertEquals(50000.0d, mustangPolicy.limit);
  631. Camaro camaro = new Camaro(3000, 1967, Color.BLUE);
  632. CamaroInsurance camaroPolicy = (CamaroInsurance) camaroInsuranceFactory.create(camaro, 800.0d);
  633. assertEquals(800.0d, camaroPolicy.premium);
  634. assertEquals(100000.0d, camaroPolicy.limit);
  635. }
  636. public static class AutoInsurance<T extends Car> implements Insurance<T> {
  637. private final double premium;
  638. private final double limit;
  639. private final T car;
  640. @AssistedInject
  641. public AutoInsurance(double limit, @Assisted T car, @Assisted double premium) {
  642. this.limit = limit;
  643. this.car = car;
  644. this.premium = premium;
  645. }
  646. public void sell() {}
  647. }
  648. public void testAssistedFactoryForTypeVariableParameters() {
  649. final TypeLiteral<InsuranceFactory<Camaro>> camaroInsuranceFactoryType =
  650. new TypeLiteral<InsuranceFactory<Camaro>>() {};
  651. Injector injector = Guice.createInjector(new AbstractModule() {
  652. @Override
  653. protected void configure() {
  654. bind(Double.class).toInstance(50000.0d);
  655. bind(camaroInsuranceFactoryType).toProvider(FactoryProvider.newFactory(
  656. camaroInsuranceFactoryType, new TypeLiteral<AutoInsurance<Camaro>>() {}));
  657. }
  658. });
  659. InsuranceFactory<Camaro> camaroInsuranceFactory =
  660. injector.getInstance(Key.get(camaroInsuranceFactoryType));
  661. Camaro camaro = new Camaro(3000, 1967, Color.BLUE);
  662. AutoInsurance<?> camaroPolicy =
  663. (AutoInsurance<?>) camaroInsuranceFactory.create(camaro, 800.0d);
  664. assertEquals(800.0d, camaroPolicy.premium);
  665. assertEquals(50000.0d, camaroPolicy.limit);
  666. assertEquals(camaro, camaroPolicy.car);
  667. }
  668. public void testDuplicateAssistedFactoryBinding() {
  669. Injector injector = Guice.createInjector(new AbstractModule() {
  670. @Override
  671. protected void configure() {
  672. bind(Double.class).toInstance(5.0d);
  673. bind(ColoredCarFactory.class)
  674. .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, Mustang.class));
  675. bind(ColoredCarFactory.class)
  676. .toProvider(FactoryProvider.newFactory(ColoredCarFactory.class, Mustang.class));
  677. }
  678. });
  679. ColoredCarFactory carFactory = injector.getInstance(ColoredCarFactory.class);
  680. Mustang blueMustang = (Mustang) carFactory.create(Color.BLUE);
  681. assertEquals(Color.BLUE, blueMustang.color);
  682. assertEquals(5.0d, blueMustang.engineSize);
  683. Mustang redMustang = (Mustang) carFactory.create(Color.RED);
  684. assertEquals(Color.RED, redMustang.color);
  685. assertEquals(5.0d, redMustang.engineSize);
  686. }
  687. public interface Equals {
  688. enum ComparisonMethod { SHALLOW, DEEP; }
  689. interface Factory {
  690. Equals equals(Equals.ComparisonMethod comparisonMethod);
  691. }
  692. public static class Impl implements Equals {
  693. private final double sigma;
  694. private final ComparisonMethod comparisonMethod;
  695. @Inject
  696. public Impl(double sigma, @Assisted ComparisonMethod comparisonMethod) {
  697. this.sigma = sigma;
  698. this.comparisonMethod = comparisonMethod;
  699. }
  700. }
  701. }
  702. public void testFactoryMethodCalledEquals() {
  703. Injector injector = Guice.createInjector(new AbstractModule() {
  704. @Override
  705. protected void configure() {
  706. bind(Double.class).toInstance(0.01d);
  707. bind(Equals.Factory.class).toProvider(
  708. FactoryProvider.newFactory(Equals.Factory.class, Equals.Impl.class));
  709. }
  710. });
  711. Equals.Factory equalsFactory = injector.getInstance(Equals.Factory.class);
  712. Equals.Impl shallowEquals = (Impl) equalsFactory.equals(ComparisonMethod.SHALLOW);
  713. assertEquals(ComparisonMethod.SHALLOW, shallowEquals.comparisonMethod);
  714. assertEquals(0.01d, shallowEquals.sigma);
  715. }
  716. }