1 package com.atlassian.pageobjects.binder;
2
3 import com.atlassian.pageobjects.Page;
4 import com.atlassian.pageobjects.PageBinder;
5 import com.atlassian.pageobjects.ProductInstance;
6 import com.atlassian.pageobjects.TestedProduct;
7 import com.atlassian.pageobjects.Tester;
8 import com.atlassian.pageobjects.inject.ConfigurableInjectionContext;
9 import com.google.inject.Binder;
10 import com.google.inject.Module;
11 import org.hamcrest.CoreMatchers;
12 import org.junit.Before;
13 import org.junit.Test;
14
15 import javax.inject.Inject;
16
17 import static junit.framework.Assert.assertNotNull;
18 import static junit.framework.Assert.assertTrue;
19 import static org.junit.Assert.assertEquals;
20 import static org.junit.Assert.assertThat;
21 import static org.mockito.Mockito.mock;
22
23
24
25
26 @SuppressWarnings("unchecked")
27 public class TestInjectPageBinder
28 {
29 private MyTestedProduct product;
30
31 @Before
32 public void setUp() throws Exception
33 {
34 product = new MyTestedProduct(new SetTester());
35 }
36
37 private InjectPageBinder createBinder()
38 {
39 return createBinder(null, null);
40 }
41 private InjectPageBinder createBinder(final Class<?> key, final Class impl)
42 {
43 return new InjectPageBinder(mock(ProductInstance.class), mock(Tester.class), new StandardModule(product),
44 new Module()
45 {
46 public void configure(Binder binder)
47 {
48 if (key != null)
49 {
50 binder.bind(key).to(impl);
51 }
52 }
53 });
54 }
55
56 @Test
57 public void testInject()
58 {
59 PageBinder binder = createBinder(StringField.class, StringFieldImpl.class);
60 OneFieldPage page = binder.bind(OneFieldPage.class);
61 assertEquals("Bob", page.name.getValue());
62 }
63
64 @Test
65 public void testInjectDefaults()
66 {
67 PageBinder binder = createBinder();
68 DefaultsPage page = binder.bind(DefaultsPage.class);
69 assertNotNull(page.testedProduct);
70 assertNotNull(page.myTestedProduct);
71 assertNotNull(page.tester);
72 assertNotNull(page.setTester);
73 assertNotNull(page.pageBinder);
74 assertNotNull(page.productInstance);
75 }
76
77 @Test(expected = IllegalArgumentException.class)
78 public void testInjectMissing()
79 {
80 PageBinder binder = createBinder();
81 OneFieldPage page = binder.bind(OneFieldPage.class);
82 int x = 0;
83 }
84
85 @Test
86 public void testInjectWithArgument()
87 {
88 PageBinder binder = createBinder();
89 ConstructorArgumentPage page = binder.bind(ConstructorArgumentPage.class, "foo");
90 assertEquals("foo", page.name);
91 }
92
93 @Test
94 public void testInstantiateWithPrimitiveArguments()
95 {
96 PageBinder binder = createBinder();
97 ConstructorArgumentPrimitive object = binder.bind(ConstructorArgumentPrimitive.class, 5, true);
98 assertNotNull(object);
99 assertEquals(5, object.intField);
100 assertTrue(object.booleanField);
101 }
102
103 @Test
104 public void testInjectWithArgumentSubclass()
105 {
106 PageBinder binder = createBinder();
107 ConstructorArgumentPage page = binder.bind(ConstructorArgumentPage.class, 43);
108 assertEquals(43, page.age);
109 }
110
111 @Test
112 public void testInitAfterInject()
113 {
114 PageBinder binder = createBinder(StringField.class, StringFieldImpl.class);
115 OneFieldWithInitPage page = binder.bind(OneFieldWithInitPage.class);
116 assertEquals("Bob Jones", page.name);
117 }
118
119 @Test
120 public void testPrivateInitAfterInject()
121 {
122 PageBinder binder = createBinder(StringField.class, StringFieldImpl.class);
123 OneFieldWithPrivateInitPage page = binder.bind(OneFieldWithPrivateInitPage.class);
124 assertEquals("Bob Private", page.name);
125 }
126
127 @Test
128 public void testOneFieldWithSuperClassInit()
129 {
130 PageBinder binder = createBinder(StringField.class, StringFieldImpl.class);
131 OneFieldWithSuperClassInitPage page = binder.bind(OneFieldWithSuperClassInitPage.class);
132 assertEquals("Bob Private", page.getName());
133
134 }
135
136 @Test
137 public void testProtectedInitAfterInject()
138 {
139 PageBinder binder = createBinder(StringField.class, StringFieldImpl.class);
140 OneFieldWithProtectedInitPage page = binder.bind(OneFieldWithProtectedInitPage.class);
141 assertEquals("Bob Protected", page.name);
142 }
143
144 @Test
145 public void testParentInject()
146 {
147 PageBinder binder = createBinder(StringField.class, StringFieldImpl.class);
148 ChildNoNamePage page = binder.bind(ChildNoNamePage.class);
149 assertEquals("Bob", page.name.getValue());
150 }
151
152 @Test
153 public void shouldImplementConfigurableInjectionContext()
154 {
155 final PageBinder binder = createBinder(StringField.class, StringFieldImpl.class);
156 assertThat(binder, CoreMatchers.instanceOf(ConfigurableInjectionContext.class));
157 assertEquals("Bob", binder.bind(OneFieldPage.class).name.getValue());
158 ConfigurableInjectionContext.class.cast(binder)
159 .configure()
160 .addImplementation(StringField.class, AnotherStringFieldImpl.class)
161 .finish();
162 assertEquals("Rob", binder.bind(OneFieldPage.class).name.getValue());
163 }
164
165 @Test
166 public void shouldAllowConfiguringNewSingletonInstanceThatIsSubclassOfInterfaceType()
167 {
168 final PageBinder binder = createBinder();
169 ConfigurableInjectionContext.class.cast(binder)
170 .configure()
171 .addSingleton(StringField.class, new StringFieldImpl())
172 .finish();
173 assertEquals("Bob", binder.bind(OneFieldPage.class).name.getValue());
174 }
175
176 @Test
177 public void shouldAllowConfiguringNewImplementationInstance()
178 {
179 final PageBinder binder = createBinder(StringField.class, StringFieldImpl.class);
180 assertEquals("Bob", binder.bind(OneFieldPage.class).name.getValue());
181 ConfigurableInjectionContext.class.cast(binder)
182 .configure()
183 .addSingleton(StringField.class, new StringField()
184 {
185 @Override
186 public String getValue()
187 {
188 return "Boom!";
189 }
190 })
191 .finish();
192 assertEquals("Boom!", binder.bind(OneFieldPage.class).name.getValue());
193 }
194
195
196 static class AbstractPage implements Page
197 {
198 public String getUrl()
199 {
200 return null;
201 }
202 }
203
204 static class OneFieldPage extends AbstractPage
205 {
206 @Inject
207 private StringField name;
208 }
209
210 static class ConstructorArgumentPrimitive
211 {
212 private final int intField;
213 private final boolean booleanField;
214
215 public ConstructorArgumentPrimitive(int intArg, boolean booleanArg)
216 {
217 this.intField = intArg;
218 this.booleanField = booleanArg;
219 }
220 }
221
222
223 static class ConstructorArgumentPage extends AbstractPage
224 {
225 private final String name;
226 private final Number age;
227
228 public ConstructorArgumentPage(String name)
229 {
230 this.name = name;
231 this.age = null;
232 }
233
234 public ConstructorArgumentPage(Number age)
235 {
236 this.age = age;
237 this.name = null;
238 }
239 }
240
241 static class ParentNamePage extends AbstractPage
242 {
243 @Inject
244 protected StringField name;
245 }
246
247 static class ChildNoNamePage extends ParentNamePage
248 {
249 }
250
251 static class DefaultsPage extends AbstractPage
252 {
253 @Inject
254 private ProductInstance productInstance;
255
256 @Inject
257 private TestedProduct testedProduct;
258
259 @Inject
260 private MyTestedProduct myTestedProduct;
261
262 @Inject
263 private Tester tester;
264
265 @Inject
266 private SetTester setTester;
267
268 @Inject
269 private PageBinder pageBinder;
270 }
271
272 static class OneFieldWithInitPage extends AbstractPage
273 {
274 @Inject
275 private StringField field;
276
277 private String name;
278 @Init
279 public void init()
280 {
281 name = field.getValue() + " Jones";
282 }
283 }
284
285 static interface StringField
286 {
287 String getValue();
288 }
289
290 static class StringFieldImpl implements StringField
291 {
292 public String getValue()
293 {
294 return "Bob";
295 }
296 }
297
298 static class AnotherStringFieldImpl implements StringField
299 {
300 public String getValue()
301 {
302 return "Rob";
303 }
304 }
305
306 static class OneFieldWithPrivateInitPage extends AbstractPage
307 {
308 @Inject
309 private StringField field;
310
311 private String name;
312
313 @Init
314 private void init()
315 {
316 name = field.getValue() + " Private";
317 }
318
319 public String getName()
320 {
321 return name;
322 }
323 }
324
325 static class OneFieldWithProtectedInitPage extends AbstractPage
326 {
327 @Inject
328 private StringField field;
329
330 private String name;
331
332 @Init
333 protected void init()
334 {
335 name = field.getValue() + " Protected";
336 }
337 }
338
339 static class OneFieldWithSuperClassInitPage extends OneFieldWithPrivateInitPage
340 {
341 }
342
343 }