PageRenderTime 34ms CodeModel.GetById 0ms RepoModel.GetById 0ms app.codeStats 0ms

/core/test/com/google/inject/GenericInjectionTest.java

https://gitlab.com/metamorphiccode/guice
Java | 187 lines | 134 code | 30 blank | 23 comment | 0 complexity | f70ce0eec8019e0e272790284814c858 MD5 | raw file
  1. /**
  2. * Copyright (C) 2006 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;
  17. import com.google.common.collect.ImmutableMap;
  18. import com.google.common.collect.ImmutableSet;
  19. import com.google.inject.util.Modules;
  20. import junit.framework.TestCase;
  21. import java.util.Arrays;
  22. import java.util.Collection;
  23. import java.util.List;
  24. import java.util.Map;
  25. import java.util.Set;
  26. /**
  27. * @author crazybob@google.com (Bob Lee)
  28. */
  29. public class GenericInjectionTest extends TestCase {
  30. public void testGenericInjection() throws CreationException {
  31. final List<String> names = Arrays.asList("foo", "bar", "bob");
  32. Injector injector = Guice.createInjector((Module) new AbstractModule() {
  33. protected void configure() {
  34. bind(new TypeLiteral<List<String>>() {}).toInstance(names);
  35. }
  36. });
  37. Foo foo = injector.getInstance(Foo.class);
  38. assertEquals(names, foo.names);
  39. }
  40. static class Foo {
  41. @Inject List<String> names;
  42. }
  43. /**
  44. * Although we may not have intended to support this behaviour, this test
  45. * passes under Guice 1.0. The workaround is to add an explicit binding for
  46. * the parameterized type. See {@link #testExplicitBindingOfGenericType()}.
  47. */
  48. public void testImplicitBindingOfGenericType() {
  49. Parameterized<String> parameterized
  50. = Guice.createInjector().getInstance(Key.get(new TypeLiteral<Parameterized<String>>() {}));
  51. assertNotNull(parameterized);
  52. }
  53. public void testExplicitBindingOfGenericType() {
  54. Injector injector = Guice.createInjector(new AbstractModule() {
  55. protected void configure() {
  56. bind(Key.get(new TypeLiteral<Parameterized<String>>() {}))
  57. .to((Class) Parameterized.class);
  58. }
  59. });
  60. Parameterized<String> parameterized
  61. = injector.getInstance(Key.get(new TypeLiteral<Parameterized<String>>() { }));
  62. assertNotNull(parameterized);
  63. }
  64. static class Parameterized<T> {
  65. @Inject
  66. Parameterized() { }
  67. }
  68. public void testInjectingParameterizedDependenciesForImplicitBinding() {
  69. assertParameterizedDepsInjected(new Key<ParameterizedDeps<String, Integer>>() {},
  70. Modules.EMPTY_MODULE);
  71. }
  72. public void testInjectingParameterizedDependenciesForBindingTarget() {
  73. final TypeLiteral<ParameterizedDeps<String, Integer>> type
  74. = new TypeLiteral<ParameterizedDeps<String, Integer>>() {};
  75. assertParameterizedDepsInjected(Key.get(Object.class), new AbstractModule() {
  76. protected void configure() {
  77. bind(Object.class).to(type);
  78. }
  79. });
  80. }
  81. public void testInjectingParameterizedDependenciesForBindingSource() {
  82. final TypeLiteral<ParameterizedDeps<String, Integer>> type
  83. = new TypeLiteral<ParameterizedDeps<String, Integer>>() {};
  84. assertParameterizedDepsInjected(Key.get(type), new AbstractModule() {
  85. protected void configure() {
  86. bind(type);
  87. }
  88. });
  89. }
  90. public void testBindingToSubtype() {
  91. final TypeLiteral<ParameterizedDeps<String, Integer>> type
  92. = new TypeLiteral<ParameterizedDeps<String, Integer>>() {};
  93. assertParameterizedDepsInjected(Key.get(type), new AbstractModule() {
  94. protected void configure() {
  95. bind(type).to(new TypeLiteral<SubParameterizedDeps<String, Long, Integer>>() {});
  96. }
  97. });
  98. }
  99. public void testBindingSubtype() {
  100. final TypeLiteral<SubParameterizedDeps<String, Long, Integer>> type
  101. = new TypeLiteral<SubParameterizedDeps<String, Long, Integer>>() {};
  102. assertParameterizedDepsInjected(Key.get(type), new AbstractModule() {
  103. protected void configure() {
  104. bind(type);
  105. }
  106. });
  107. }
  108. @SuppressWarnings("unchecked")
  109. public void assertParameterizedDepsInjected(Key<?> key, Module bindingModule) {
  110. Module bindDataModule = new AbstractModule() {
  111. protected void configure() {}
  112. @Provides Map<String, Integer> provideMap() {
  113. return ImmutableMap.of("one", 1, "two", 2);
  114. }
  115. @Provides Set<String> provideSet(Map<String, Integer> map) {
  116. return map.keySet();
  117. }
  118. @Provides Collection<Integer> provideCollection(Map<String, Integer> map) {
  119. return map.values();
  120. }
  121. };
  122. Injector injector = Guice.createInjector(bindDataModule, bindingModule);
  123. ParameterizedDeps<String, Integer> parameterizedDeps
  124. = (ParameterizedDeps<String, Integer>) injector.getInstance(key);
  125. assertEquals(ImmutableMap.of("one", 1, "two", 2), parameterizedDeps.map);
  126. assertEquals(ImmutableSet.of("one", "two"), parameterizedDeps.keys);
  127. assertEquals(ImmutableSet.of(1, 2), ImmutableSet.copyOf(parameterizedDeps.values));
  128. }
  129. static class SubParameterizedDeps<A, B, C> extends ParameterizedDeps<A, C> {
  130. @Inject SubParameterizedDeps(Set<A> keys) {
  131. super(keys);
  132. }
  133. }
  134. static class ParameterizedDeps<K, V> {
  135. @Inject private Map<K, V> map;
  136. private Set<K> keys;
  137. private Collection<V> values;
  138. @Inject ParameterizedDeps(Set<K> keys) {
  139. this.keys = keys;
  140. }
  141. @Inject void method(Collection<V> values) {
  142. this.values = values;
  143. }
  144. }
  145. public void testImmediateTypeVariablesAreInjected() {
  146. Injector injector = Guice.createInjector(new AbstractModule() {
  147. protected void configure() {
  148. bind(String.class).toInstance("tee");
  149. }
  150. });
  151. InjectsT<String> injectsT = injector.getInstance(new Key<InjectsT<String>>() {});
  152. assertEquals("tee", injectsT.t);
  153. }
  154. static class InjectsT<T> {
  155. @Inject T t;
  156. }
  157. }