PageRenderTime 3312ms CodeModel.GetById 19ms RepoModel.GetById 3ms app.codeStats 0ms

/core/test/com/googlecode/guice/Jsr330Test.java

https://gitlab.com/metamorphiccode/guice
Java | 475 lines | 378 code | 75 blank | 22 comment | 6 complexity | 0f740794a2bbd97dae5b1f53b87bca67 MD5 | raw file
  1. /**
  2. * Copyright (C) 2009 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.googlecode.guice;
  17. import static com.google.inject.Asserts.assertContains;
  18. import static java.lang.annotation.RetentionPolicy.RUNTIME;
  19. import com.google.inject.AbstractModule;
  20. import com.google.inject.Binding;
  21. import com.google.inject.CreationException;
  22. import com.google.inject.Guice;
  23. import com.google.inject.Injector;
  24. import com.google.inject.Key;
  25. import com.google.inject.Scope;
  26. import com.google.inject.Scopes;
  27. import com.google.inject.Stage;
  28. import com.google.inject.TypeLiteral;
  29. import com.google.inject.name.Names;
  30. import com.google.inject.spi.Dependency;
  31. import com.google.inject.spi.HasDependencies;
  32. import com.google.inject.util.Providers;
  33. import junit.framework.TestCase;
  34. import java.lang.annotation.Annotation;
  35. import java.lang.annotation.Retention;
  36. import java.util.Set;
  37. import javax.inject.Inject;
  38. import javax.inject.Named;
  39. import javax.inject.Provider;
  40. import javax.inject.Qualifier;
  41. import javax.inject.Singleton;
  42. public class Jsr330Test extends TestCase {
  43. private final B b = new B();
  44. private final C c = new C();
  45. private final D d = new D();
  46. private final E e = new E();
  47. @Override protected void setUp() throws Exception {
  48. J.nextInstanceId = 0;
  49. K.nextInstanceId = 0;
  50. }
  51. public void testInject() {
  52. Injector injector = Guice.createInjector(new AbstractModule() {
  53. protected void configure() {
  54. bind(B.class).toInstance(b);
  55. bind(C.class).toInstance(c);
  56. bind(D.class).toInstance(d);
  57. bind(E.class).toInstance(e);
  58. bind(A.class);
  59. }
  60. });
  61. A a = injector.getInstance(A.class);
  62. assertSame(b, a.b);
  63. assertSame(c, a.c);
  64. assertSame(d, a.d);
  65. assertSame(e, a.e);
  66. }
  67. public void testQualifiedInject() {
  68. Injector injector = Guice.createInjector(new AbstractModule() {
  69. protected void configure() {
  70. bind(B.class).annotatedWith(Names.named("jodie")).toInstance(b);
  71. bind(C.class).annotatedWith(Red.class).toInstance(c);
  72. bind(D.class).annotatedWith(RED).toInstance(d);
  73. bind(E.class).annotatedWith(Names.named("jesse")).toInstance(e);
  74. bind(F.class);
  75. }
  76. });
  77. F f = injector.getInstance(F.class);
  78. assertSame(b, f.b);
  79. assertSame(c, f.c);
  80. assertSame(d, f.d);
  81. assertSame(e, f.e);
  82. }
  83. public void testProviderInject() {
  84. Injector injector = Guice.createInjector(new AbstractModule() {
  85. protected void configure() {
  86. bind(B.class).annotatedWith(Names.named("jodie")).toInstance(b);
  87. bind(C.class).toInstance(c);
  88. bind(D.class).annotatedWith(RED).toInstance(d);
  89. bind(E.class).toInstance(e);
  90. bind(G.class);
  91. }
  92. });
  93. G g = injector.getInstance(G.class);
  94. assertSame(b, g.bProvider.get());
  95. assertSame(c, g.cProvider.get());
  96. assertSame(d, g.dProvider.get());
  97. assertSame(e, g.eProvider.get());
  98. }
  99. public void testScopeAnnotation() {
  100. final TestScope scope = new TestScope();
  101. Injector injector = Guice.createInjector(new AbstractModule() {
  102. protected void configure() {
  103. bind(B.class).in(scope);
  104. bind(C.class).in(TestScoped.class);
  105. bindScope(TestScoped.class, scope);
  106. }
  107. });
  108. B b = injector.getInstance(B.class);
  109. assertSame(b, injector.getInstance(B.class));
  110. assertSame(b, injector.getInstance(B.class));
  111. C c = injector.getInstance(C.class);
  112. assertSame(c, injector.getInstance(C.class));
  113. assertSame(c, injector.getInstance(C.class));
  114. H h = injector.getInstance(H.class);
  115. assertSame(h, injector.getInstance(H.class));
  116. assertSame(h, injector.getInstance(H.class));
  117. scope.reset();
  118. assertNotSame(b, injector.getInstance(B.class));
  119. assertNotSame(c, injector.getInstance(C.class));
  120. assertNotSame(h, injector.getInstance(H.class));
  121. }
  122. public void testSingleton() {
  123. Injector injector = Guice.createInjector(new AbstractModule() {
  124. protected void configure() {
  125. bind(B.class).in(Singleton.class);
  126. }
  127. });
  128. B b = injector.getInstance(B.class);
  129. assertSame(b, injector.getInstance(B.class));
  130. assertSame(b, injector.getInstance(B.class));
  131. J j = injector.getInstance(J.class);
  132. assertSame(j, injector.getInstance(J.class));
  133. assertSame(j, injector.getInstance(J.class));
  134. }
  135. public void testEagerSingleton() {
  136. Guice.createInjector(Stage.PRODUCTION, new AbstractModule() {
  137. protected void configure() {
  138. bind(J.class);
  139. bind(K.class).in(Singleton.class);
  140. }
  141. });
  142. assertEquals(1, J.nextInstanceId);
  143. assertEquals(1, K.nextInstanceId);
  144. }
  145. public void testScopesIsSingleton() {
  146. Injector injector = Guice.createInjector(new AbstractModule() {
  147. protected void configure() {
  148. bind(J.class);
  149. bind(K.class).in(Singleton.class);
  150. }
  151. });
  152. assertTrue(Scopes.isSingleton(injector.getBinding(J.class)));
  153. assertTrue(Scopes.isSingleton(injector.getBinding(K.class)));
  154. }
  155. public void testInjectingFinalFieldsIsForbidden() {
  156. try {
  157. Guice.createInjector(new AbstractModule() {
  158. protected void configure() {
  159. bind(L.class);
  160. }
  161. });
  162. fail();
  163. } catch (CreationException expected) {
  164. assertContains(expected.getMessage(),
  165. "1) Injected field " + L.class.getName() + ".b cannot be final.");
  166. }
  167. }
  168. public void testInjectingAbstractMethodsIsForbidden() {
  169. try {
  170. Guice.createInjector(new AbstractModule() {
  171. protected void configure() {
  172. bind(M.class);
  173. }
  174. });
  175. fail();
  176. } catch (CreationException expected) {
  177. assertContains(expected.getMessage(),
  178. "1) Injected method " + AbstractM.class.getName() + ".setB() cannot be abstract.");
  179. }
  180. }
  181. public void testInjectingMethodsWithTypeParametersIsForbidden() {
  182. try {
  183. Guice.createInjector(new AbstractModule() {
  184. protected void configure() {
  185. bind(N.class);
  186. }
  187. });
  188. fail();
  189. } catch (CreationException expected) {
  190. assertContains(expected.getMessage(), "1) Injected method " + N.class.getName()
  191. + ".setB() cannot declare type parameters of its own.");
  192. }
  193. }
  194. public void testInjectingMethodsWithNonVoidReturnTypes() {
  195. Guice.createInjector(new AbstractModule() {
  196. protected void configure() {
  197. bind(P.class);
  198. }
  199. });
  200. }
  201. /**
  202. * This test verifies that we can compile bindings to provider instances
  203. * whose compile-time type implements javax.inject.Provider but not
  204. * com.google.inject.Provider. For binary compatibility, we don't (and won't)
  205. * support binding to instances of javax.inject.Provider.
  206. */
  207. public void testBindProviderClass() {
  208. Injector injector = Guice.createInjector(new AbstractModule() {
  209. protected void configure() {
  210. bind(B.class).toProvider(BProvider.class);
  211. bind(B.class).annotatedWith(Names.named("1")).toProvider(BProvider.class);
  212. bind(B.class).annotatedWith(Names.named("2")).toProvider(Key.get(BProvider.class));
  213. bind(B.class).annotatedWith(Names.named("3")).toProvider(TypeLiteral.get(BProvider.class));
  214. }
  215. });
  216. injector.getInstance(Key.get(B.class));
  217. injector.getInstance(Key.get(B.class, Names.named("1")));
  218. injector.getInstance(Key.get(B.class, Names.named("2")));
  219. injector.getInstance(Key.get(B.class, Names.named("3")));
  220. }
  221. public void testGuicify330Provider() {
  222. Provider<String> jsr330Provider = new Provider<String>() {
  223. public String get() {
  224. return "A";
  225. }
  226. @Override public String toString() {
  227. return "jsr330Provider";
  228. }
  229. };
  230. com.google.inject.Provider<String> guicified = Providers.guicify(jsr330Provider);
  231. assertEquals("guicified(jsr330Provider)", guicified.toString());
  232. assertEquals("A", guicified.get());
  233. // when you guicify the Guice-friendly, it's a no-op
  234. assertSame(guicified, Providers.guicify(guicified));
  235. assertFalse(guicified instanceof HasDependencies);
  236. }
  237. public void testGuicifyWithDependencies() {
  238. Provider<String> jsr330Provider = new Provider<String>() {
  239. @Inject double d;
  240. int i;
  241. @Inject void injectMe(int i) {
  242. this.i = i;
  243. }
  244. public String get() {
  245. return d + "-" + i;
  246. }
  247. };
  248. final com.google.inject.Provider<String> guicified =
  249. Providers.guicify(jsr330Provider);
  250. assertTrue(guicified instanceof HasDependencies);
  251. Set<Dependency<?>> actual = ((HasDependencies)guicified).getDependencies();
  252. validateDependencies(actual, jsr330Provider.getClass());
  253. Injector injector = Guice.createInjector(new AbstractModule() {
  254. @Override
  255. protected void configure() {
  256. bind(String.class).toProvider(guicified);
  257. bind(int.class).toInstance(1);
  258. bind(double.class).toInstance(2.0d);
  259. }
  260. });
  261. Binding<String> binding = injector.getBinding(String.class);
  262. assertEquals("2.0-1", binding.getProvider().get());
  263. validateDependencies(actual, jsr330Provider.getClass());
  264. }
  265. private void validateDependencies(Set<Dependency<?>> actual, Class<?> owner) {
  266. assertEquals(actual.toString(), 2, actual.size());
  267. Dependency<?> dDep = null;
  268. Dependency<?> iDep = null;
  269. for(Dependency<?> dep : actual) {
  270. if(dep.getKey().equals(Key.get(Double.class))) {
  271. dDep = dep;
  272. } else if(dep.getKey().equals(Key.get(Integer.class))) {
  273. iDep = dep;
  274. }
  275. }
  276. assertNotNull(dDep);
  277. assertNotNull(iDep);
  278. assertEquals(TypeLiteral.get(owner), dDep.getInjectionPoint().getDeclaringType());
  279. assertEquals("d", dDep.getInjectionPoint().getMember().getName());
  280. assertEquals(-1, dDep.getParameterIndex());
  281. assertEquals(TypeLiteral.get(owner), iDep.getInjectionPoint().getDeclaringType());
  282. assertEquals("injectMe", iDep.getInjectionPoint().getMember().getName());
  283. assertEquals(0, iDep.getParameterIndex());
  284. }
  285. static class A {
  286. final B b;
  287. @Inject C c;
  288. D d;
  289. E e;
  290. @Inject A(B b) {
  291. this.b = b;
  292. }
  293. @Inject void injectD(D d, E e) {
  294. this.d = d;
  295. this.e = e;
  296. }
  297. }
  298. static class B {}
  299. static class C {}
  300. static class D {}
  301. static class E {}
  302. static class F {
  303. final B b;
  304. @Inject @Red C c;
  305. D d;
  306. E e;
  307. @Inject F(@Named("jodie") B b) {
  308. this.b = b;
  309. }
  310. @Inject void injectD(@Red D d, @Named("jesse") E e) {
  311. this.d = d;
  312. this.e = e;
  313. }
  314. }
  315. @Qualifier @Retention(RUNTIME)
  316. @interface Red {}
  317. public static final Red RED = new Red() {
  318. public Class<? extends Annotation> annotationType() {
  319. return Red.class;
  320. }
  321. @Override public boolean equals(Object obj) {
  322. return obj instanceof Red;
  323. }
  324. @Override public int hashCode() {
  325. return 0;
  326. }
  327. };
  328. static class G {
  329. final Provider<B> bProvider;
  330. @Inject Provider<C> cProvider;
  331. Provider<D> dProvider;
  332. Provider<E> eProvider;
  333. @Inject G(@Named("jodie") Provider<B> bProvider) {
  334. this.bProvider = bProvider;
  335. }
  336. @Inject void injectD(@Red Provider<D> dProvider, Provider<E> eProvider) {
  337. this.dProvider = dProvider;
  338. this.eProvider = eProvider;
  339. }
  340. }
  341. @javax.inject.Scope @Retention(RUNTIME)
  342. @interface TestScoped {}
  343. static class TestScope implements Scope {
  344. private int now = 0;
  345. public <T> com.google.inject.Provider<T> scope(Key<T> key,
  346. final com.google.inject.Provider<T> unscoped) {
  347. return new com.google.inject.Provider<T>() {
  348. private T value;
  349. private int snapshotTime = -1;
  350. public T get() {
  351. if (snapshotTime != now) {
  352. value = unscoped.get();
  353. snapshotTime = now;
  354. }
  355. return value;
  356. }
  357. };
  358. }
  359. public void reset() {
  360. now++;
  361. }
  362. }
  363. @TestScoped
  364. static class H {}
  365. @Singleton
  366. static class J {
  367. static int nextInstanceId = 0;
  368. int instanceId = nextInstanceId++;
  369. }
  370. static class K {
  371. static int nextInstanceId = 0;
  372. int instanceId = nextInstanceId++;
  373. }
  374. static class L {
  375. @SuppressWarnings("InjectJavaxInjectOnFinalField")
  376. @Inject
  377. final B b = null;
  378. }
  379. static abstract class AbstractM {
  380. @SuppressWarnings("InjectJavaxInjectOnAbstractMethod")
  381. @Inject
  382. abstract void setB(B b);
  383. }
  384. static class M extends AbstractM {
  385. void setB(B b) {}
  386. }
  387. static class N {
  388. @Inject <T> void setB(B b) {}
  389. }
  390. static class P {
  391. @Inject B setB(B b) {
  392. return b;
  393. }
  394. }
  395. static class BProvider implements Provider<B> {
  396. public B get() {
  397. return new B();
  398. }
  399. }
  400. }