PageRenderTime 51ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 1ms

/spice-inject/guice-patches/vanilla.test/com/google/inject/ParentInjectorTest.java

https://github.com/peterlynch/spice
Java | 310 lines | 242 code | 48 blank | 20 comment | 0 complexity | 23a2b5a90ca8dab28c84f119d40c237d MD5 | raw file
  1. /*
  2. Copyright (C) 2007 Google Inc.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package com.google.inject;
  14. import static com.google.inject.Asserts.assertContains;
  15. import com.google.inject.internal.util.ImmutableList;
  16. import com.google.inject.matcher.Matchers;
  17. import com.google.inject.name.Names;
  18. import com.google.inject.spi.TypeConverter;
  19. import static java.lang.annotation.ElementType.TYPE;
  20. import java.lang.annotation.Retention;
  21. import static java.lang.annotation.RetentionPolicy.RUNTIME;
  22. import java.lang.annotation.Target;
  23. import java.util.List;
  24. import junit.framework.TestCase;
  25. /**
  26. * @author jessewilson@google.com (Jesse Wilson)
  27. */
  28. public class ParentInjectorTest extends TestCase {
  29. public void testParentAndChildCannotShareExplicitBindings() {
  30. Injector parent = Guice.createInjector(bindsA);
  31. try {
  32. parent.createChildInjector(bindsA);
  33. fail("Created the same explicit binding on both parent and child");
  34. } catch (CreationException e) {
  35. assertContains(e.getMessage(), "A binding to ", A.class.getName(), " was already configured",
  36. " at ", getClass().getName(), ".configure(ParentInjectorTest.java:",
  37. " at ", getClass().getName(), ".configure(ParentInjectorTest.java:");
  38. }
  39. }
  40. public void testParentJitBindingWontClobberChildBinding() {
  41. Injector parent = Guice.createInjector();
  42. parent.createChildInjector(bindsA);
  43. try {
  44. parent.getInstance(A.class);
  45. fail("Created a just-in-time binding on the parent that's the same as a child's binding");
  46. } catch (ConfigurationException e) {
  47. assertContains(e.getMessage(), "A binding to ", A.class.getName(),
  48. " already exists on a child injector.");
  49. }
  50. }
  51. public void testJustInTimeBindingsAreSharedWithParentIfPossible() {
  52. Injector parent = Guice.createInjector();
  53. Injector child = parent.createChildInjector();
  54. assertSame(child.getInstance(A.class), parent.getInstance(A.class));
  55. Injector anotherChild = parent.createChildInjector();
  56. assertSame(anotherChild.getInstance(A.class), parent.getInstance(A.class));
  57. Injector grandchild = child.createChildInjector();
  58. assertSame(grandchild.getInstance(A.class), parent.getInstance(A.class));
  59. }
  60. public void testBindingsInherited() {
  61. Injector parent = Guice.createInjector(bindsB);
  62. Injector child = parent.createChildInjector();
  63. assertSame(RealB.class, child.getInstance(B.class).getClass());
  64. }
  65. public void testGetParent() {
  66. Injector top = Guice.createInjector(bindsA);
  67. Injector middle = top.createChildInjector(bindsB);
  68. Injector bottom = middle.createChildInjector();
  69. assertSame(middle, bottom.getParent());
  70. assertSame(top, middle.getParent());
  71. assertNull(top.getParent());
  72. }
  73. public void testChildBindingsNotVisibleToParent() {
  74. Injector parent = Guice.createInjector();
  75. parent.createChildInjector(bindsB);
  76. try {
  77. parent.getBinding(B.class);
  78. fail();
  79. } catch (ConfigurationException expected) {
  80. }
  81. }
  82. public void testScopesInherited() {
  83. Injector parent = Guice.createInjector(new AbstractModule() {
  84. protected void configure() {
  85. bindScope(MyScope.class, Scopes.SINGLETON);
  86. }
  87. });
  88. Injector child = parent.createChildInjector(new AbstractModule() {
  89. @Override protected void configure() {
  90. bind(A.class).in(MyScope.class);
  91. }
  92. });
  93. assertSame(child.getInstance(A.class), child.getInstance(A.class));
  94. }
  95. /*if[AOP]*/
  96. private final org.aopalliance.intercept.MethodInterceptor returnNullInterceptor
  97. = new org.aopalliance.intercept.MethodInterceptor() {
  98. public Object invoke(org.aopalliance.intercept.MethodInvocation methodInvocation) {
  99. return null;
  100. }
  101. };
  102. public void testInterceptorsInherited() {
  103. Injector parent = Guice.createInjector(new AbstractModule() {
  104. protected void configure() {
  105. super.bindInterceptor(Matchers.any(), Matchers.returns(Matchers.identicalTo(A.class)),
  106. returnNullInterceptor);
  107. }
  108. });
  109. Injector child = parent.createChildInjector(new AbstractModule() {
  110. protected void configure() {
  111. bind(C.class);
  112. }
  113. });
  114. assertNull(child.getInstance(C.class).interceptedMethod());
  115. }
  116. /*end[AOP]*/
  117. public void testTypeConvertersInherited() {
  118. Injector parent = Guice.createInjector(bindListConverterModule);
  119. Injector child = parent.createChildInjector(bindStringNamedB);
  120. assertEquals(ImmutableList.of(), child.getInstance(Key.get(List.class, Names.named("B"))));
  121. }
  122. public void testTypeConvertersConflicting() {
  123. Injector parent = Guice.createInjector(bindListConverterModule);
  124. Injector child = parent.createChildInjector(bindListConverterModule, bindStringNamedB);
  125. try {
  126. child.getInstance(Key.get(List.class, Names.named("B")));
  127. fail();
  128. } catch (ConfigurationException expected) {
  129. Asserts.assertContains(expected.getMessage(), "Multiple converters can convert");
  130. }
  131. }
  132. public void testInjectorInjectionSpanningInjectors() {
  133. Injector parent = Guice.createInjector();
  134. Injector child = parent.createChildInjector(new AbstractModule() {
  135. protected void configure() {
  136. bind(D.class);
  137. }
  138. });
  139. D d = child.getInstance(D.class);
  140. assertSame(d.injector, child);
  141. E e = child.getInstance(E.class);
  142. assertSame(e.injector, parent);
  143. }
  144. public void testSeveralLayersOfHierarchy() {
  145. Injector top = Guice.createInjector(bindsA);
  146. Injector left = top.createChildInjector();
  147. Injector leftLeft = left.createChildInjector(bindsD);
  148. Injector right = top.createChildInjector(bindsD);
  149. assertSame(leftLeft, leftLeft.getInstance(D.class).injector);
  150. assertSame(right, right.getInstance(D.class).injector);
  151. assertSame(top, leftLeft.getInstance(E.class).injector);
  152. assertSame(top.getInstance(A.class), leftLeft.getInstance(A.class));
  153. Injector leftRight = left.createChildInjector(bindsD);
  154. assertSame(leftRight, leftRight.getInstance(D.class).injector);
  155. try {
  156. top.getInstance(D.class);
  157. fail();
  158. } catch (ConfigurationException expected) {
  159. }
  160. try {
  161. left.getInstance(D.class);
  162. fail();
  163. } catch (ConfigurationException expected) {
  164. }
  165. }
  166. public void testScopeBoundInChildInjectorOnly() {
  167. Injector parent = Guice.createInjector();
  168. Injector child = parent.createChildInjector(new AbstractModule() {
  169. protected void configure() {
  170. bindScope(MyScope.class, Scopes.SINGLETON);
  171. }
  172. });
  173. try {
  174. parent.getProvider(F.class);
  175. fail();
  176. } catch (ConfigurationException expected) {
  177. assertContains(expected.getMessage(),
  178. "No scope is bound to com.google.inject.ParentInjectorTest$MyScope.",
  179. "at " + F.class.getName() + ".class(ParentInjectorTest.java",
  180. " while locating " + F.class.getName());
  181. }
  182. assertNotNull(child.getProvider(F.class).get());
  183. }
  184. public void testErrorInParentButOkayInChild() {
  185. Injector parent = Guice.createInjector();
  186. Injector childInjector = parent.createChildInjector(new AbstractModule() {
  187. protected void configure() {
  188. bindScope(MyScope.class, Scopes.SINGLETON);
  189. bind(Object.class).to(F.class);
  190. }
  191. });
  192. Object one = childInjector.getInstance(Object.class);
  193. Object two = childInjector.getInstance(Object.class);
  194. assertSame(one, two);
  195. }
  196. public void testErrorInParentAndChild() {
  197. Injector parent = Guice.createInjector();
  198. Injector childInjector = parent.createChildInjector();
  199. try {
  200. childInjector.getInstance(G.class);
  201. fail();
  202. } catch(ConfigurationException expected) {
  203. assertContains(expected.getMessage(), "No scope is bound to " + MyScope.class.getName(),
  204. "at " + F.class.getName() + ".class(ParentInjectorTest.java:",
  205. " while locating " + G.class.getName());
  206. }
  207. }
  208. @Singleton
  209. static class A {}
  210. private final Module bindsA = new AbstractModule() {
  211. protected void configure() {
  212. bind(A.class).toInstance(new A());
  213. }
  214. };
  215. interface B {}
  216. static class RealB implements B {}
  217. private final Module bindsB = new AbstractModule() {
  218. protected void configure() {
  219. bind(B.class).to(RealB.class);
  220. }
  221. };
  222. @Target(TYPE) @Retention(RUNTIME) @ScopeAnnotation
  223. public @interface MyScope {}
  224. private final TypeConverter listConverter = new TypeConverter() {
  225. public Object convert(String value, TypeLiteral<?> toType) {
  226. return ImmutableList.of();
  227. }
  228. };
  229. private final Module bindListConverterModule = new AbstractModule() {
  230. protected void configure() {
  231. convertToTypes(Matchers.any(), listConverter);
  232. }
  233. };
  234. private final Module bindStringNamedB = new AbstractModule() {
  235. protected void configure() {
  236. bind(String.class).annotatedWith(Names.named("B")).toInstance("buzz");
  237. }
  238. };
  239. public static class C {
  240. public A interceptedMethod() {
  241. return new A();
  242. }
  243. }
  244. static class D {
  245. @Inject Injector injector;
  246. }
  247. static class E {
  248. @Inject Injector injector;
  249. }
  250. private final Module bindsD = new AbstractModule() {
  251. protected void configure() {
  252. bind(D.class);
  253. }
  254. };
  255. @MyScope
  256. static class F implements G {}
  257. @ImplementedBy(F.class)
  258. interface G {}
  259. }