1b71955639ab617e0a4115b1439c8b9982227a018sberlin/** 2b71955639ab617e0a4115b1439c8b9982227a018sberlin * Copyright (C) 2011 Google Inc. 3b71955639ab617e0a4115b1439c8b9982227a018sberlin * 4b71955639ab617e0a4115b1439c8b9982227a018sberlin * Licensed under the Apache License, Version 2.0 (the "License"); 5b71955639ab617e0a4115b1439c8b9982227a018sberlin * you may not use this file except in compliance with the License. 6b71955639ab617e0a4115b1439c8b9982227a018sberlin * You may obtain a copy of the License at 7b71955639ab617e0a4115b1439c8b9982227a018sberlin * 8b71955639ab617e0a4115b1439c8b9982227a018sberlin * http://www.apache.org/licenses/LICENSE-2.0 9b71955639ab617e0a4115b1439c8b9982227a018sberlin * 10b71955639ab617e0a4115b1439c8b9982227a018sberlin * Unless required by applicable law or agreed to in writing, software 11b71955639ab617e0a4115b1439c8b9982227a018sberlin * distributed under the License is distributed on an "AS IS" BASIS, 12b71955639ab617e0a4115b1439c8b9982227a018sberlin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b71955639ab617e0a4115b1439c8b9982227a018sberlin * See the License for the specific language governing permissions and 14b71955639ab617e0a4115b1439c8b9982227a018sberlin * limitations under the License. 15b71955639ab617e0a4115b1439c8b9982227a018sberlin */ 16b71955639ab617e0a4115b1439c8b9982227a018sberlin 17b71955639ab617e0a4115b1439c8b9982227a018sberlinpackage com.google.inject.grapher; 18b71955639ab617e0a4115b1439c8b9982227a018sberlin 19b71955639ab617e0a4115b1439c8b9982227a018sberlinimport com.google.common.collect.ImmutableList; 20b71955639ab617e0a4115b1439c8b9982227a018sberlinimport com.google.common.collect.ImmutableSet; 21b71955639ab617e0a4115b1439c8b9982227a018sberlinimport com.google.common.collect.Sets; 22b71955639ab617e0a4115b1439c8b9982227a018sberlinimport com.google.inject.AbstractModule; 23b71955639ab617e0a4115b1439c8b9982227a018sberlinimport com.google.inject.BindingAnnotation; 24b71955639ab617e0a4115b1439c8b9982227a018sberlinimport com.google.inject.Guice; 25b71955639ab617e0a4115b1439c8b9982227a018sberlinimport com.google.inject.Inject; 26b71955639ab617e0a4115b1439c8b9982227a018sberlinimport com.google.inject.Key; 27b71955639ab617e0a4115b1439c8b9982227a018sberlinimport com.google.inject.Provider; 28b71955639ab617e0a4115b1439c8b9982227a018sberlinimport com.google.inject.spi.InjectionPoint; 29b71955639ab617e0a4115b1439c8b9982227a018sberlin 30b71955639ab617e0a4115b1439c8b9982227a018sberlinimport junit.framework.TestCase; 31b71955639ab617e0a4115b1439c8b9982227a018sberlin 32b71955639ab617e0a4115b1439c8b9982227a018sberlinimport java.lang.annotation.Retention; 33b71955639ab617e0a4115b1439c8b9982227a018sberlinimport java.lang.annotation.RetentionPolicy; 34b71955639ab617e0a4115b1439c8b9982227a018sberlinimport java.lang.reflect.Member; 35b71955639ab617e0a4115b1439c8b9982227a018sberlinimport java.util.Set; 36b71955639ab617e0a4115b1439c8b9982227a018sberlin 37b71955639ab617e0a4115b1439c8b9982227a018sberlin/** 38b71955639ab617e0a4115b1439c8b9982227a018sberlin * Test cases for {@link AbstractInjectorGrapher}. This indirectly tests most classes in this 39b71955639ab617e0a4115b1439c8b9982227a018sberlin * package. 40b71955639ab617e0a4115b1439c8b9982227a018sberlin * 41b71955639ab617e0a4115b1439c8b9982227a018sberlin * @author bojand@google.com (Bojan Djordjevic) 42b71955639ab617e0a4115b1439c8b9982227a018sberlin */ 4345ef01760942b9575a6094effeb4eb034db9a113Sam Berlin 44b71955639ab617e0a4115b1439c8b9982227a018sberlinpublic class AbstractInjectorGrapherTest extends TestCase { 45b71955639ab617e0a4115b1439c8b9982227a018sberlin private static final String TEST_STRING = "test"; 46b71955639ab617e0a4115b1439c8b9982227a018sberlin 47b71955639ab617e0a4115b1439c8b9982227a018sberlin private static class FakeGrapher extends AbstractInjectorGrapher { 48b71955639ab617e0a4115b1439c8b9982227a018sberlin final Set<Node> nodes = Sets.newHashSet(); 49b71955639ab617e0a4115b1439c8b9982227a018sberlin final Set<Edge> edges = Sets.newHashSet(); 50b71955639ab617e0a4115b1439c8b9982227a018sberlin 51b71955639ab617e0a4115b1439c8b9982227a018sberlin @Override protected void reset() { 52b71955639ab617e0a4115b1439c8b9982227a018sberlin nodes.clear(); 53b71955639ab617e0a4115b1439c8b9982227a018sberlin edges.clear(); 54b71955639ab617e0a4115b1439c8b9982227a018sberlin } 55b71955639ab617e0a4115b1439c8b9982227a018sberlin 56b71955639ab617e0a4115b1439c8b9982227a018sberlin @Override protected void newInterfaceNode(InterfaceNode node) { 57b71955639ab617e0a4115b1439c8b9982227a018sberlin assertFalse(nodes.contains(node)); 58b71955639ab617e0a4115b1439c8b9982227a018sberlin nodes.add(node); 59b71955639ab617e0a4115b1439c8b9982227a018sberlin } 60b71955639ab617e0a4115b1439c8b9982227a018sberlin 61b71955639ab617e0a4115b1439c8b9982227a018sberlin @Override protected void newImplementationNode(ImplementationNode node) { 62b71955639ab617e0a4115b1439c8b9982227a018sberlin assertFalse(nodes.contains(node)); 63b71955639ab617e0a4115b1439c8b9982227a018sberlin nodes.add(node); 64b71955639ab617e0a4115b1439c8b9982227a018sberlin } 65b71955639ab617e0a4115b1439c8b9982227a018sberlin 66b71955639ab617e0a4115b1439c8b9982227a018sberlin @Override protected void newInstanceNode(InstanceNode node) { 67b71955639ab617e0a4115b1439c8b9982227a018sberlin assertFalse(nodes.contains(node)); 68b71955639ab617e0a4115b1439c8b9982227a018sberlin nodes.add(node); 69b71955639ab617e0a4115b1439c8b9982227a018sberlin } 70b71955639ab617e0a4115b1439c8b9982227a018sberlin 71b71955639ab617e0a4115b1439c8b9982227a018sberlin @Override protected void newDependencyEdge(DependencyEdge edge) { 72b71955639ab617e0a4115b1439c8b9982227a018sberlin assertFalse(edges.contains(edge)); 73b71955639ab617e0a4115b1439c8b9982227a018sberlin edges.add(edge); 74b71955639ab617e0a4115b1439c8b9982227a018sberlin } 75b71955639ab617e0a4115b1439c8b9982227a018sberlin 76b71955639ab617e0a4115b1439c8b9982227a018sberlin @Override protected void newBindingEdge(BindingEdge edge) { 77b71955639ab617e0a4115b1439c8b9982227a018sberlin assertFalse(edges.contains(edge)); 78b71955639ab617e0a4115b1439c8b9982227a018sberlin edges.add(edge); 79b71955639ab617e0a4115b1439c8b9982227a018sberlin } 80b71955639ab617e0a4115b1439c8b9982227a018sberlin 81b71955639ab617e0a4115b1439c8b9982227a018sberlin @Override protected void postProcess() {} 82b71955639ab617e0a4115b1439c8b9982227a018sberlin } 83b71955639ab617e0a4115b1439c8b9982227a018sberlin 84b71955639ab617e0a4115b1439c8b9982227a018sberlin private static final class Wrapper<T> { 85b71955639ab617e0a4115b1439c8b9982227a018sberlin T value; 86b71955639ab617e0a4115b1439c8b9982227a018sberlin } 87b71955639ab617e0a4115b1439c8b9982227a018sberlin 88b71955639ab617e0a4115b1439c8b9982227a018sberlin @BindingAnnotation 89b71955639ab617e0a4115b1439c8b9982227a018sberlin @Retention(RetentionPolicy.RUNTIME) 90b71955639ab617e0a4115b1439c8b9982227a018sberlin private static @interface Ann {} 91b71955639ab617e0a4115b1439c8b9982227a018sberlin private static interface IA {} 92b71955639ab617e0a4115b1439c8b9982227a018sberlin private static class A implements IA { 93b71955639ab617e0a4115b1439c8b9982227a018sberlin @Inject public A(String str) {} 94b71955639ab617e0a4115b1439c8b9982227a018sberlin } 95b71955639ab617e0a4115b1439c8b9982227a018sberlin private static class A2 implements IA { 96b71955639ab617e0a4115b1439c8b9982227a018sberlin @Inject public A2(Provider<String> strProvider) {} 97b71955639ab617e0a4115b1439c8b9982227a018sberlin } 98b71955639ab617e0a4115b1439c8b9982227a018sberlin 99b71955639ab617e0a4115b1439c8b9982227a018sberlin private Node aNode; 100b71955639ab617e0a4115b1439c8b9982227a018sberlin private Node a2Node; 101b71955639ab617e0a4115b1439c8b9982227a018sberlin private Node iaNode; 102b71955639ab617e0a4115b1439c8b9982227a018sberlin private Node iaAnnNode; 103b71955639ab617e0a4115b1439c8b9982227a018sberlin private Node stringNode; 104b71955639ab617e0a4115b1439c8b9982227a018sberlin private Node stringInstanceNode; 105b71955639ab617e0a4115b1439c8b9982227a018sberlin 106b71955639ab617e0a4115b1439c8b9982227a018sberlin private FakeGrapher grapher; 107b71955639ab617e0a4115b1439c8b9982227a018sberlin 108b71955639ab617e0a4115b1439c8b9982227a018sberlin @Override protected void setUp() throws Exception { 109b71955639ab617e0a4115b1439c8b9982227a018sberlin super.setUp(); 110b71955639ab617e0a4115b1439c8b9982227a018sberlin grapher = new FakeGrapher(); 111b71955639ab617e0a4115b1439c8b9982227a018sberlin Node.ignoreSourceInComparisons = true; 112b71955639ab617e0a4115b1439c8b9982227a018sberlin aNode = new ImplementationNode(NodeId.newTypeId(Key.get(A.class)), null, 113b71955639ab617e0a4115b1439c8b9982227a018sberlin ImmutableList.<Member>of(A.class.getConstructor(String.class))); 114b71955639ab617e0a4115b1439c8b9982227a018sberlin a2Node = new ImplementationNode(NodeId.newTypeId(Key.get(A2.class)), null, 115b71955639ab617e0a4115b1439c8b9982227a018sberlin ImmutableList.<Member>of(A2.class.getConstructor(Provider.class))); 116b71955639ab617e0a4115b1439c8b9982227a018sberlin iaNode = new InterfaceNode(NodeId.newTypeId(Key.get(IA.class)), null); 117b71955639ab617e0a4115b1439c8b9982227a018sberlin iaAnnNode = new InterfaceNode(NodeId.newTypeId(Key.get(IA.class, Ann.class)), null); 118b71955639ab617e0a4115b1439c8b9982227a018sberlin stringNode = new InterfaceNode(NodeId.newTypeId(Key.get(String.class)), null); 119b71955639ab617e0a4115b1439c8b9982227a018sberlin stringInstanceNode = new InstanceNode(NodeId.newInstanceId(Key.get(String.class)), null, 120b71955639ab617e0a4115b1439c8b9982227a018sberlin TEST_STRING, ImmutableList.<Member>of()); 121b71955639ab617e0a4115b1439c8b9982227a018sberlin } 122b71955639ab617e0a4115b1439c8b9982227a018sberlin 123b71955639ab617e0a4115b1439c8b9982227a018sberlin public void testLinkedAndInstanceBindings() throws Exception { 124b71955639ab617e0a4115b1439c8b9982227a018sberlin grapher.graph(Guice.createInjector(new AbstractModule() { 125b71955639ab617e0a4115b1439c8b9982227a018sberlin @Override protected void configure() { 126b71955639ab617e0a4115b1439c8b9982227a018sberlin bind(IA.class).to(A.class); 127b71955639ab617e0a4115b1439c8b9982227a018sberlin bind(IA.class).annotatedWith(Ann.class).to(A.class); 128b71955639ab617e0a4115b1439c8b9982227a018sberlin bind(String.class).toInstance(TEST_STRING); 129b71955639ab617e0a4115b1439c8b9982227a018sberlin } 130b71955639ab617e0a4115b1439c8b9982227a018sberlin })); 131b71955639ab617e0a4115b1439c8b9982227a018sberlin 132b71955639ab617e0a4115b1439c8b9982227a018sberlin Set<Node> expectedNodes = 133b71955639ab617e0a4115b1439c8b9982227a018sberlin ImmutableSet.<Node>of(iaNode, iaAnnNode, aNode, stringNode, stringInstanceNode); 134b71955639ab617e0a4115b1439c8b9982227a018sberlin Set<Edge> expectedEdges = ImmutableSet.<Edge>of( 135b71955639ab617e0a4115b1439c8b9982227a018sberlin new BindingEdge(iaNode.getId(), aNode.getId(), BindingEdge.Type.NORMAL), 136b71955639ab617e0a4115b1439c8b9982227a018sberlin new BindingEdge(iaAnnNode.getId(), aNode.getId(), BindingEdge.Type.NORMAL), 137b71955639ab617e0a4115b1439c8b9982227a018sberlin new BindingEdge(stringNode.getId(), stringInstanceNode.getId(), BindingEdge.Type.NORMAL), 138b71955639ab617e0a4115b1439c8b9982227a018sberlin new DependencyEdge(aNode.getId(), stringNode.getId(), 139b71955639ab617e0a4115b1439c8b9982227a018sberlin InjectionPoint.forConstructor(A.class.getConstructor(String.class)))); 140b71955639ab617e0a4115b1439c8b9982227a018sberlin assertEquals(expectedNodes, grapher.nodes); 141b71955639ab617e0a4115b1439c8b9982227a018sberlin assertEquals(expectedEdges, grapher.edges); 142b71955639ab617e0a4115b1439c8b9982227a018sberlin } 143b71955639ab617e0a4115b1439c8b9982227a018sberlin 144b71955639ab617e0a4115b1439c8b9982227a018sberlin public void testProviderBindings() throws Exception { 145b71955639ab617e0a4115b1439c8b9982227a018sberlin final Wrapper<Provider<A2>> wrapper = new Wrapper<Provider<A2>>(); 146b71955639ab617e0a4115b1439c8b9982227a018sberlin grapher.graph(Guice.createInjector(new AbstractModule() { 147b71955639ab617e0a4115b1439c8b9982227a018sberlin @Override protected void configure() { 148b71955639ab617e0a4115b1439c8b9982227a018sberlin wrapper.value = getProvider(A2.class); 149b71955639ab617e0a4115b1439c8b9982227a018sberlin bind(IA.class).toProvider(wrapper.value); 150b71955639ab617e0a4115b1439c8b9982227a018sberlin bind(A2.class); 151b71955639ab617e0a4115b1439c8b9982227a018sberlin bind(String.class).toInstance(TEST_STRING); 152b71955639ab617e0a4115b1439c8b9982227a018sberlin } 153b71955639ab617e0a4115b1439c8b9982227a018sberlin })); 154b71955639ab617e0a4115b1439c8b9982227a018sberlin 155b71955639ab617e0a4115b1439c8b9982227a018sberlin Node a2ProviderNode = new InstanceNode(NodeId.newInstanceId(Key.get(IA.class)), null, 156b71955639ab617e0a4115b1439c8b9982227a018sberlin wrapper.value, ImmutableList.<Member>of()); 157b71955639ab617e0a4115b1439c8b9982227a018sberlin Set<Node> expectedNodes = 158b71955639ab617e0a4115b1439c8b9982227a018sberlin ImmutableSet.<Node>of(iaNode, stringNode, a2Node, stringInstanceNode, a2ProviderNode); 159b71955639ab617e0a4115b1439c8b9982227a018sberlin Set<Edge> expectedEdges = ImmutableSet.<Edge>of( 160b71955639ab617e0a4115b1439c8b9982227a018sberlin new BindingEdge(stringNode.getId(), stringInstanceNode.getId(), BindingEdge.Type.NORMAL), 161b71955639ab617e0a4115b1439c8b9982227a018sberlin new BindingEdge(iaNode.getId(), a2ProviderNode.getId(), BindingEdge.Type.PROVIDER), 162b71955639ab617e0a4115b1439c8b9982227a018sberlin new DependencyEdge(a2Node.getId(), stringNode.getId(), 163cade897b45ffe5d9d4e48ae7009cf74d8a91e335Christian Edward Gruber InjectionPoint.forConstructor(A2.class.getConstructor(Provider.class))), 164cade897b45ffe5d9d4e48ae7009cf74d8a91e335Christian Edward Gruber new DependencyEdge(a2ProviderNode.getId(), a2Node.getId(), null)); 165cade897b45ffe5d9d4e48ae7009cf74d8a91e335Christian Edward Gruber assertEquals("wrong nodes", expectedNodes, grapher.nodes); 166cade897b45ffe5d9d4e48ae7009cf74d8a91e335Christian Edward Gruber assertEquals("wrong edges", expectedEdges, grapher.edges); 167b71955639ab617e0a4115b1439c8b9982227a018sberlin } 168b71955639ab617e0a4115b1439c8b9982227a018sberlin 169b71955639ab617e0a4115b1439c8b9982227a018sberlin public void testGraphWithGivenRoot() throws Exception { 170b71955639ab617e0a4115b1439c8b9982227a018sberlin grapher.graph(Guice.createInjector(new AbstractModule() { 171b71955639ab617e0a4115b1439c8b9982227a018sberlin @Override protected void configure() { 172b71955639ab617e0a4115b1439c8b9982227a018sberlin bind(IA.class).to(A.class); 173b71955639ab617e0a4115b1439c8b9982227a018sberlin bind(IA.class).annotatedWith(Ann.class).to(A.class); 174b71955639ab617e0a4115b1439c8b9982227a018sberlin bind(String.class).toInstance(TEST_STRING); 175b71955639ab617e0a4115b1439c8b9982227a018sberlin } 176b71955639ab617e0a4115b1439c8b9982227a018sberlin }), ImmutableSet.<Key<?>>of(Key.get(String.class))); 177b71955639ab617e0a4115b1439c8b9982227a018sberlin 178b71955639ab617e0a4115b1439c8b9982227a018sberlin Set<Node> expectedNodes = ImmutableSet.<Node>of(stringNode, stringInstanceNode); 179b71955639ab617e0a4115b1439c8b9982227a018sberlin Set<Edge> expectedEdges = ImmutableSet.<Edge>of( 180b71955639ab617e0a4115b1439c8b9982227a018sberlin new BindingEdge(stringNode.getId(), stringInstanceNode.getId(), BindingEdge.Type.NORMAL)); 181b71955639ab617e0a4115b1439c8b9982227a018sberlin assertEquals(expectedNodes, grapher.nodes); 182b71955639ab617e0a4115b1439c8b9982227a018sberlin assertEquals(expectedEdges, grapher.edges); 183b71955639ab617e0a4115b1439c8b9982227a018sberlin } 184b71955639ab617e0a4115b1439c8b9982227a018sberlin} 185