1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.grouplens.grapht;
21
22 import org.grouplens.grapht.annotation.DefaultImplementation;
23 import org.grouplens.grapht.context.ContextElements;
24 import org.grouplens.grapht.context.ContextPattern;
25 import org.grouplens.grapht.context.Multiplicity;
26 import org.junit.Before;
27 import org.junit.Test;
28
29 import javax.annotation.Nullable;
30 import javax.inject.Inject;
31
32 import static org.hamcrest.CoreMatchers.*;
33 import static org.junit.Assert.assertThat;
34
35
36
37
38
39
40 public class ContextOverrideTest {
41 private InjectorBuilder build;
42
43 @Before
44 public void setup() {
45 build = InjectorBuilder.create();
46 }
47
48
49
50
51
52 @Test
53 public void testDeeperOverride() throws InjectionException {
54 build.within(Outer.class)
55 .bind(IPlug.class)
56 .to(PlugH.class);
57 build.within(Inner.class)
58 .bind(IPlug.class)
59 .to(PlugA.class);
60 Injector inj = build.build();
61
62 Inner in = inj.getInstance(Inner.class);
63 assertThat(in, notNullValue());
64 assertThat(in.plug, instanceOf(PlugA.class));
65
66 Outer out = inj.getInstance(Outer.class);
67 assertThat(out, notNullValue());
68 assertThat(out.plug, instanceOf(PlugH.class));
69 assertThat(out.inner, notNullValue());
70 assertThat(out.inner.plug, instanceOf(PlugA.class));
71 }
72
73
74
75
76 @Test
77 public void testNullDeepConcrete() throws InjectionException {
78
79
80 build.within(COuter.class)
81 .bind(Plug.class)
82 .toNull();
83 build.within(CInner.class)
84 .bind(Plug.class)
85 .to(Plug.class, false);
86 Injector inj = build.build();
87
88 CInner in = inj.getInstance(CInner.class);
89 assertThat(in, notNullValue());
90 assertThat(in.plug, notNullValue());
91
92 COuter out = inj.getInstance(COuter.class);
93 assertThat(out, notNullValue());
94 assertThat(out.plug, nullValue());
95 assertThat(out.inner, notNullValue());
96 assertThat(out.inner.plug, notNullValue());
97 assertThat(out.inner.plug, instanceOf(Plug.class));
98 }
99
100
101
102
103
104 @Test
105 public void testNullDeepConcreteAnchored() throws InjectionException {
106
107 build.at(COuter.class)
108 .bind(Plug.class)
109 .toNull();
110 Injector inj = build.build();
111
112 CInner in = inj.getInstance(CInner.class);
113 assertThat(in, notNullValue());
114 assertThat(in.plug, notNullValue());
115
116 COuter out = inj.getInstance(COuter.class);
117 assertThat(out, notNullValue());
118 assertThat(out.plug, nullValue());
119 assertThat(out.inner, notNullValue());
120 assertThat(out.inner.plug, notNullValue());
121 assertThat(out.inner.plug, instanceOf(Plug.class));
122 }
123
124
125
126
127 @Test
128 public void testAnchoredToRoot() throws InjectionException {
129 build.bind(IPlug.class)
130 .to(PlugA.class);
131 build.at(null)
132 .bind(IPlug.class)
133 .to(PlugH.class);
134 Injector inj = build.build();
135
136
137 assertThat(inj.getInstance(IPlug.class),
138 instanceOf(PlugH.class));
139
140
141 Outer out = inj.getInstance(Outer.class);
142 assertThat(out.plug,
143 instanceOf(PlugA.class));
144 assertThat(out.inner.plug,
145 instanceOf(PlugA.class));
146 assertThat(out.plug, sameInstance(out.inner.plug));
147
148
149 assertThat(inj.getInstance(IPlug.class),
150 instanceOf(PlugH.class));
151 }
152
153 @Test
154 public void testPatternForPlug() throws InjectionException {
155 build.matching(ContextPattern.any()
156 .append(CInner.class)
157 .append(ContextElements.invertMatch(ContextElements.matchType(PlugW.class)),
158 Multiplicity.ZERO_OR_MORE))
159 .bind(Plug.class)
160 .to(PlugW.class);
161 Injector inj = build.build();
162 CInner c = inj.getInstance(CInner.class);
163 assertThat(c.plug, instanceOf(PlugW.class));
164 assert c.plug != null;
165 assertThat(((PlugW) c.plug).inner.getClass(),
166 equalTo((Class) Plug.class));
167 }
168
169 @DefaultImplementation(PlugA.class)
170 public static interface IPlug {}
171 public static class PlugA implements IPlug {}
172 public static class PlugH implements IPlug {}
173
174 public static class Inner {
175 final IPlug plug;
176
177 @Inject
178 public Inner(IPlug p) {
179 plug = p;
180 }
181 }
182
183 public static class Outer {
184 final IPlug plug;
185 final Inner inner;
186
187 @Inject
188 public Outer(Inner in, @Nullable IPlug p) {
189 plug = p;
190 inner = in;
191 }
192 }
193
194 public static class Plug {}
195
196 public static class CInner {
197 final Plug plug;
198
199 @Inject
200 public CInner(@Nullable Plug p) {
201 plug = p;
202 }
203 }
204
205 public static class COuter {
206 final Plug plug;
207 final CInner inner;
208
209 @Inject
210 public COuter(CInner in, @Nullable Plug p) {
211 plug = p;
212 inner = in;
213 }
214 }
215
216 public static class PlugW extends Plug {
217 private final Plug inner;
218
219 @Inject
220 public PlugW(Plug wrapped) {
221 inner = wrapped;
222 }
223 }
224 }