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

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

https://gitlab.com/metamorphiccode/guice
Java | 210 lines | 163 code | 26 blank | 21 comment | 20 complexity | 01a8ede311ac0d961daf542b9d781723 MD5 | raw file
  1. /**
  2. * Copyright (C) 2010 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.name.Names.named;
  18. import com.google.common.collect.ImmutableList;
  19. import com.google.common.collect.ImmutableSet;
  20. import com.google.common.collect.Iterables;
  21. import com.google.common.collect.Lists;
  22. import com.google.common.collect.Sets;
  23. import com.google.inject.AbstractModule;
  24. import com.google.inject.Binding;
  25. import com.google.inject.Guice;
  26. import com.google.inject.Inject;
  27. import com.google.inject.Injector;
  28. import com.google.inject.Key;
  29. import com.google.inject.Stage;
  30. import com.google.inject.name.Named;
  31. import com.google.inject.spi.DefaultBindingTargetVisitor;
  32. import com.google.inject.spi.Dependency;
  33. import com.google.inject.spi.Element;
  34. import com.google.inject.spi.Elements;
  35. import junit.framework.AssertionFailedError;
  36. import junit.framework.TestCase;
  37. import java.util.List;
  38. import java.util.Set;
  39. import java.util.logging.Logger;
  40. /**
  41. * Tests for AssistedInject Spi.
  42. *
  43. * @author ramakrishna@google.com (Ramakrishna Rajanna)
  44. */
  45. public class ExtensionSpiTest extends TestCase {
  46. public final void testSpiOnElements() throws Exception {
  47. AssistedInjectSpiVisitor visitor = new AssistedInjectSpiVisitor();
  48. Integer count = 0;
  49. for(Element element : Elements.getElements(new Module())) {
  50. if(element instanceof Binding) {
  51. assertEquals(count++, ((Binding<?>)element).acceptTargetVisitor(visitor));
  52. }
  53. }
  54. validateVisitor(visitor);
  55. }
  56. public void testSpiOnVisitor() throws Exception {
  57. AssistedInjectSpiVisitor visitor = new AssistedInjectSpiVisitor();
  58. Integer count = 0;
  59. Injector injector = Guice.createInjector(new Module());
  60. for(Binding<?> binding : injector.getBindings().values()) {
  61. assertEquals(count++, binding.acceptTargetVisitor(visitor));
  62. }
  63. validateVisitor(visitor);
  64. }
  65. private void validateVisitor(AssistedInjectSpiVisitor visitor) throws Exception {
  66. assertEquals(1, visitor.assistedBindingCount);
  67. List<AssistedMethod> assistedMethods =
  68. Lists.newArrayList(Iterables.getOnlyElement(
  69. visitor.assistedInjectBindings).getAssistedMethods());
  70. assertEquals(7, assistedMethods.size());
  71. assertEquals(1, visitor.assistedBindingCount);
  72. assertEquals(1, visitor.assistedInjectBindings.size());
  73. // Validate for each of the methods in AnimalFactory
  74. Set<String> names = Sets.newHashSet();
  75. for (AssistedMethod method : assistedMethods) {
  76. String name = method.getFactoryMethod().getName();
  77. names.add(name);
  78. if (name.equals("createAStrangeCatAsAnimal")) {
  79. validateAssistedMethod(method, name, StrangeCat.class, ImmutableList.<Key<?>>of());
  80. } else if (name.equals("createStrangeCatWithConstructorForOwner")) {
  81. validateAssistedMethod(method, name, StrangeCat.class, ImmutableList.<Key<?>>of());
  82. } else if (name.equals("createStrangeCatWithConstructorForAge")) {
  83. validateAssistedMethod(method, name, StrangeCat.class, ImmutableList.<Key<?>>of());
  84. } else if (name.equals("createCatWithANonAssistedDependency")) {
  85. validateAssistedMethod(method, name, CatWithAName.class,
  86. ImmutableList.<Key<?>>of(Key.get(String.class, named("catName2"))));
  87. } else if (name.equals("createCat")) {
  88. validateAssistedMethod(method, name, Cat.class, ImmutableList.<Key<?>>of());
  89. } else if (name.equals("createASimpleCatAsAnimal")) {
  90. validateAssistedMethod(method, name, SimpleCat.class, ImmutableList.<Key<?>>of());
  91. } else if (name.equals("createCatWithNonAssistedDependencies")) {
  92. List<Key<?>> dependencyKeys = ImmutableList.<Key<?>>of(
  93. Key.get(String.class, named("catName1")),
  94. Key.get(String.class, named("petName")),
  95. Key.get(Integer.class, named("age")));
  96. validateAssistedMethod(method, name, ExplodingCat.class, dependencyKeys);
  97. } else {
  98. fail("Invalid method: " + method);
  99. }
  100. }
  101. assertEquals(names, ImmutableSet.of("createAStrangeCatAsAnimal",
  102. "createStrangeCatWithConstructorForOwner",
  103. "createStrangeCatWithConstructorForAge",
  104. "createCatWithANonAssistedDependency",
  105. "createCat",
  106. "createASimpleCatAsAnimal",
  107. "createCatWithNonAssistedDependencies"));
  108. }
  109. private void validateAssistedMethod(AssistedMethod assistedMethod, String factoryMethodName,
  110. Class clazz, List<Key<?>> dependencyKeys){
  111. assertEquals(factoryMethodName, assistedMethod.getFactoryMethod().getName());
  112. assertEquals(clazz, assistedMethod.getImplementationConstructor().getDeclaringClass());
  113. assertEquals(dependencyKeys.size(), assistedMethod.getDependencies().size());
  114. for (Dependency<?> dependency : assistedMethod.getDependencies()) {
  115. assertTrue(dependencyKeys.contains(dependency.getKey()));
  116. }
  117. assertEquals(clazz, assistedMethod.getImplementationType().getType());
  118. }
  119. interface AnimalFactory {
  120. Cat createCat(String owner);
  121. CatWithAName createCatWithANonAssistedDependency(String owner);
  122. @Named("SimpleCat") Animal createASimpleCatAsAnimal(String owner);
  123. Animal createAStrangeCatAsAnimal(String owner);
  124. StrangeCat createStrangeCatWithConstructorForOwner(String owner);
  125. StrangeCat createStrangeCatWithConstructorForAge(Integer age);
  126. ExplodingCat createCatWithNonAssistedDependencies(String owner);
  127. }
  128. interface Animal {}
  129. private static class Cat implements Animal {
  130. @Inject Cat(@Assisted String owner) {}
  131. }
  132. private static class SimpleCat implements Animal {
  133. @Inject SimpleCat(@Assisted String owner) {
  134. }
  135. }
  136. private static class StrangeCat implements Animal {
  137. @AssistedInject StrangeCat(@Assisted String owner) {}
  138. @AssistedInject StrangeCat(@Assisted Integer age) {}
  139. }
  140. private static class ExplodingCat implements Animal {
  141. @Inject public ExplodingCat(@Named("catName1") String name, @Assisted String owner,
  142. @Named("age") Integer age, @Named("petName") String petName) {}
  143. }
  144. private static class CatWithAName extends Cat {
  145. @Inject CatWithAName(@Assisted String owner, @Named("catName2") String name) {
  146. super(owner);
  147. }
  148. }
  149. public class Module extends AbstractModule{
  150. @Override
  151. protected void configure() {
  152. bind(String.class).annotatedWith(named("catName1")).toInstance("kitty1");
  153. bind(String.class).annotatedWith(named("catName2")).toInstance("kitty2");
  154. bind(String.class).annotatedWith(named("petName")).toInstance("pussy");
  155. bind(Integer.class).annotatedWith(named("age")).toInstance(12);
  156. install(new FactoryModuleBuilder()
  157. .implement(Animal.class, StrangeCat.class)
  158. .implement(Animal.class, named("SimpleCat"), SimpleCat.class)
  159. .build(AnimalFactory.class));
  160. }
  161. }
  162. public class AssistedInjectSpiVisitor extends DefaultBindingTargetVisitor<Object, Integer>
  163. implements AssistedInjectTargetVisitor<Object, Integer> {
  164. private final Set<Class> allowedClasses =
  165. ImmutableSet.<Class> of(
  166. Injector.class, Stage.class, Logger.class,
  167. String.class, Integer.class);
  168. private int assistedBindingCount = 0;
  169. private int currentCount = 0;
  170. private List<AssistedInjectBinding<?>> assistedInjectBindings = Lists.newArrayList();
  171. public Integer visit(AssistedInjectBinding assistedInjectBinding) {
  172. assistedInjectBindings.add(assistedInjectBinding);
  173. assistedBindingCount++;
  174. return currentCount++;
  175. }
  176. @Override
  177. protected Integer visitOther(Binding<? extends Object> binding) {
  178. if(!allowedClasses.contains(binding.getKey().getTypeLiteral().getRawType())) {
  179. throw new AssertionFailedError("invalid other binding: " + binding);
  180. }
  181. return currentCount++;
  182. }
  183. }
  184. }