PageRenderTime 139ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/test/com/google/inject/testing/guiceberry/controllable/InterceptingBindingsBuilderTest.java

http://guiceberry.googlecode.com/
Java | 236 lines | 180 code | 33 blank | 23 comment | 0 complexity | 1b5e7321b4ab4f308f69923645d61476 MD5 | raw file
Possible License(s): Apache-2.0
  1. /*
  2. * Copyright (C) 2008 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.testing.guiceberry.controllable;
  17. import com.google.inject.AbstractModule;
  18. import com.google.inject.CreationException;
  19. import com.google.inject.Guice;
  20. import com.google.inject.Injector;
  21. import com.google.inject.Key;
  22. import com.google.inject.Module;
  23. import com.google.inject.Provider;
  24. import com.google.inject.Scopes;
  25. import com.google.inject.TypeLiteral;
  26. import com.google.inject.name.Names;
  27. import junit.framework.AssertionFailedError;
  28. import junit.framework.TestCase;
  29. import java.util.ArrayList;
  30. import java.util.Arrays;
  31. import java.util.Collection;
  32. import java.util.HashMap;
  33. import java.util.HashSet;
  34. import java.util.LinkedList;
  35. import java.util.List;
  36. import java.util.Map;
  37. import java.util.Set;
  38. /**
  39. * @author Jesse Wilson
  40. */
  41. public class InterceptingBindingsBuilderTest extends TestCase {
  42. private final ProvisionInterceptor failingInterceptor = new ProvisionInterceptor() {
  43. public <T> T intercept(Key<T> key, Provider<? extends T> delegate) {
  44. throw new AssertionFailedError();
  45. }
  46. };
  47. public void testInterceptProvisionInterceptor() {
  48. InterceptingBindingsBuilder builder = new InterceptingBindingsBuilder();
  49. try {
  50. builder.intercept(ProvisionInterceptor.class);
  51. fail();
  52. } catch(IllegalArgumentException expected) {
  53. }
  54. }
  55. public void testProvisionInterception() {
  56. final ProvisionInterceptor interceptor = new ProvisionInterceptor() {
  57. @SuppressWarnings({"unchecked"})
  58. public <T> T intercept(Key<T> key, Provider<? extends T> delegate) {
  59. assertEquals(Key.get(String.class), key);
  60. assertEquals("A", delegate.get());
  61. return (T) "B";
  62. }
  63. };
  64. Module module = new AbstractModule() {
  65. @Override
  66. protected void configure() {
  67. bind(String.class).toInstance("A");
  68. bind(ProvisionInterceptor.class).toInstance(interceptor);
  69. }
  70. };
  71. Injector injector = Guice.createInjector(new InterceptingBindingsBuilder()
  72. .intercept(String.class)
  73. .install(module)
  74. .build());
  75. assertEquals("B", injector.getInstance(String.class));
  76. }
  77. /**
  78. * The user's provider is scoped but the interceptor is not. As this testcase
  79. * demonstrates, the user's provider gets called only once (in singleton
  80. * scope) but the interceptor gets called for each provision.
  81. */
  82. public void testInterceptionIsNotScoped() {
  83. final Provider<Integer> sequenceProvider = new Provider<Integer>() {
  84. private int next = 100;
  85. public Integer get() {
  86. return next++;
  87. }
  88. };
  89. final ProvisionInterceptor interceptor = new ProvisionInterceptor() {
  90. private int next = 1;
  91. @SuppressWarnings({"unchecked"})
  92. public <T> T intercept(Key<T> key, Provider<? extends T> delegate) {
  93. assertEquals(100, delegate.get());
  94. return (T) new Integer(next++);
  95. }
  96. };
  97. Module module = new AbstractModule() {
  98. @Override
  99. protected void configure() {
  100. bind(Integer.class).toProvider(sequenceProvider).in(Scopes.SINGLETON);
  101. bind(ProvisionInterceptor.class).toInstance(interceptor);
  102. }
  103. };
  104. Injector injector = Guice.createInjector(new InterceptingBindingsBuilder()
  105. .intercept(Integer.class)
  106. .install(module)
  107. .build());
  108. assertEquals(1, (int) injector.getInstance(Integer.class));
  109. assertEquals(2, (int) injector.getInstance(Integer.class));
  110. }
  111. public void testInterceptionIsWhitelistedKeysOnly() {
  112. final ProvisionInterceptor interceptor = new ProvisionInterceptor() {
  113. @SuppressWarnings({"unchecked"})
  114. public <T> T intercept(Key<T> key, Provider<? extends T> delegate) {
  115. assertEquals(ArrayList.class, delegate.get().getClass());
  116. return (T) new LinkedList();
  117. }
  118. };
  119. Module module = new AbstractModule() {
  120. @Override
  121. protected void configure() {
  122. bind(Collection.class).to(ArrayList.class);
  123. bind(List.class).to(ArrayList.class);
  124. bind(ProvisionInterceptor.class).toInstance(interceptor);
  125. }
  126. };
  127. Injector injector = Guice.createInjector(new InterceptingBindingsBuilder()
  128. .intercept(List.class)
  129. .install(module)
  130. .build());
  131. assertEquals(LinkedList.class, injector.getInstance(List.class).getClass());
  132. assertEquals(ArrayList.class, injector.getInstance(Collection.class).getClass());
  133. }
  134. public void testCannotInterceptBareBinding() {
  135. Module module = new AbstractModule() {
  136. @Override
  137. protected void configure() {
  138. bind(ArrayList.class);
  139. }
  140. };
  141. Module built = new InterceptingBindingsBuilder()
  142. .intercept(ArrayList.class)
  143. .install(module)
  144. .build();
  145. try {
  146. Guice.createInjector(built);
  147. fail();
  148. } catch(CreationException expected) {
  149. }
  150. }
  151. public void testAllInterceptedKeysMustBeBound() {
  152. Module module = new AbstractModule() {
  153. @Override
  154. protected void configure() {
  155. bind(ProvisionInterceptor.class).toInstance(failingInterceptor);
  156. }
  157. };
  158. Module built = new InterceptingBindingsBuilder()
  159. .intercept(ArrayList.class)
  160. .install(module)
  161. .build();
  162. try {
  163. Guice.createInjector(built);
  164. fail();
  165. } catch(CreationException expected) {
  166. }
  167. }
  168. public void testTolerateUnmatchedInterceptions() {
  169. Module module = new AbstractModule() {
  170. @Override
  171. protected void configure() {
  172. bind(ProvisionInterceptor.class).toInstance(failingInterceptor);
  173. }
  174. };
  175. Injector injector = Guice.createInjector(new InterceptingBindingsBuilder()
  176. .intercept(ArrayList.class)
  177. .tolerateUnmatchedInterceptions()
  178. .install(module)
  179. .build());
  180. assertEquals(new ArrayList<Object>(), injector.getInstance(ArrayList.class));
  181. }
  182. @SuppressWarnings("unchecked")
  183. public void testBindingForSetOfInterceptedKeys() {
  184. Module module = new AbstractModule() {
  185. @Override
  186. protected void configure() {
  187. bind(ProvisionInterceptor.class).toInstance(failingInterceptor);
  188. bind(List.class).to(LinkedList.class);
  189. bind(Map.class).to(HashMap.class);
  190. bind(Collection.class).to(ArrayList.class);
  191. }
  192. };
  193. Injector injector = Guice.createInjector(new InterceptingBindingsBuilder()
  194. .intercept(List.class)
  195. .intercept(Collection.class)
  196. .install(module)
  197. .build());
  198. Set<Key<?>> interceptableKeys = injector.getInstance(
  199. Key.get(new TypeLiteral<Set<Key<?>>>() {}, Names.named("Interceptable")));
  200. assertEquals(new HashSet<Key>(Arrays.asList(Key.get(List.class), Key.get(Collection.class))),
  201. interceptableKeys);
  202. }
  203. }