1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.juneau.commons.reflect;
18
19 import static org.junit.jupiter.api.Assertions.*;
20
21 import org.apache.juneau.*;
22 import org.junit.jupiter.api.*;
23
24 class Property_Test extends TestBase {
25
26 public static class TestClass {
27 public String publicField;
28 private String privateField;
29 private int intField;
30
31 public void setPublicField(String value) {
32 publicField = value;
33 }
34
35 public String getPublicField() {
36 return publicField;
37 }
38
39 public void setPrivateField(String value) {
40 privateField = value;
41 }
42
43 public String getPrivateField() {
44 return privateField;
45 }
46
47 public void setIntField(int value) {
48 intField = value;
49 }
50
51 public int getIntField() {
52 return intField;
53 }
54 }
55
56
57
58
59 @Test
60 void a001_create() {
61 var builder = Property.create();
62 assertNotNull(builder);
63 }
64
65
66
67
68 @Test
69 void a002_functionGetterAndSetter() throws Exception {
70 var prop = Property.<TestClass, String>create()
71 .getter(obj -> obj.getPublicField())
72 .setter((obj, val) -> obj.setPublicField(val))
73 .build();
74
75 var obj = new TestClass();
76 prop.set(obj, "testValue");
77 assertEquals("testValue", prop.get(obj));
78 assertEquals("testValue", obj.getPublicField());
79 }
80
81
82
83
84 @Test
85 void a003_getterOnly() throws Exception {
86 var prop = Property.<TestClass, String>create()
87 .getter(obj -> obj.getPublicField())
88 .build();
89
90 var obj = new TestClass();
91 obj.setPublicField("testValue");
92 assertEquals("testValue", prop.get(obj));
93 assertTrue(prop.canRead());
94 assertFalse(prop.canWrite());
95 }
96
97
98
99
100 @Test
101 void a004_setterOnly() throws Exception {
102 var prop = Property.<TestClass, String>create()
103 .setter((obj, val) -> obj.setPublicField(val))
104 .build();
105
106 var obj = new TestClass();
107 prop.set(obj, "testValue");
108 assertEquals("testValue", obj.getPublicField());
109 assertFalse(prop.canRead());
110 assertTrue(prop.canWrite());
111 }
112
113
114
115
116 @Test
117 void a005_get_withNullProducer() throws Exception {
118 var prop = Property.<TestClass, String>create()
119 .setter((obj, val) -> obj.setPublicField(val))
120 .build();
121
122 var obj = new TestClass();
123 var ex = assertThrows(ExecutableException.class, () -> prop.get(obj));
124 assertTrue(ex.getMessage().contains("No getter defined"));
125 }
126
127
128
129
130 @Test
131 void a006_set_withNullConsumer() throws Exception {
132 var prop = Property.<TestClass, String>create()
133 .getter(obj -> obj.getPublicField())
134 .build();
135
136 var obj = new TestClass();
137 var ex = assertThrows(ExecutableException.class, () -> prop.set(obj, "test"));
138 assertTrue(ex.getMessage().contains("No setter defined"));
139 }
140
141
142
143
144 @Test
145 void a007_get_withNullObject() {
146 var prop = Property.<TestClass, String>create()
147 .getter(obj -> obj.getPublicField())
148 .build();
149
150 assertThrows(IllegalArgumentException.class, () -> prop.get(null));
151 }
152
153
154
155
156 @Test
157 void a008_set_withNullObject() {
158 var prop = Property.<TestClass, String>create()
159 .setter((obj, val) -> obj.setPublicField(val))
160 .build();
161
162 assertThrows(IllegalArgumentException.class, () -> prop.set(null, "test"));
163 }
164
165
166
167
168 @Test
169 void a009_field_publicField() throws Exception {
170 var field = ClassInfo.of(TestClass.class).getPublicFields().stream()
171 .filter(f -> f.getName().equals("publicField"))
172 .findFirst()
173 .orElseThrow();
174 var prop = Property.<TestClass, String>create()
175 .field(field)
176 .build();
177
178 var obj = new TestClass();
179 prop.set(obj, "testValue");
180 assertEquals("testValue", prop.get(obj));
181 assertEquals("testValue", obj.publicField);
182 }
183
184
185
186
187 @Test
188 void a010_field_privateField() throws Exception {
189 var field = ClassInfo.of(TestClass.class).getDeclaredFields().stream()
190 .filter(f -> f.getName().equals("privateField"))
191 .findFirst()
192 .orElseThrow();
193 var prop = Property.<TestClass, String>create()
194 .field(field)
195 .build();
196
197 var obj = new TestClass();
198 prop.set(obj, "testValue");
199 assertEquals("testValue", prop.get(obj));
200 assertEquals("testValue", obj.getPrivateField());
201 }
202
203
204
205
206 @Test
207 void a011_field_withNullField() {
208 assertThrows(IllegalArgumentException.class, () -> {
209 Property.<TestClass, String>create()
210 .field(null)
211 .build();
212 });
213 }
214
215
216
217
218 @Test
219 void a012_getter_methodInfo() throws Exception {
220 var getter = ClassInfo.of(TestClass.class).getPublicMethods().stream()
221 .filter(m -> m.hasName("getPublicField"))
222 .findFirst()
223 .orElseThrow();
224 var prop = Property.<TestClass, String>create()
225 .getter(getter)
226 .setter((obj, val) -> obj.setPublicField(val))
227 .build();
228
229 var obj = new TestClass();
230 obj.setPublicField("testValue");
231 assertEquals("testValue", prop.get(obj));
232 }
233
234
235
236
237 @Test
238 void a013_setter_methodInfo() throws Exception {
239 var setter = ClassInfo.of(TestClass.class).getPublicMethods().stream()
240 .filter(m -> m.hasName("setPublicField") && m.hasParameterTypes(String.class))
241 .findFirst()
242 .orElseThrow();
243 var prop = Property.<TestClass, String>create()
244 .getter(obj -> obj.getPublicField())
245 .setter(setter)
246 .build();
247
248 var obj = new TestClass();
249 prop.set(obj, "testValue");
250 assertEquals("testValue", obj.getPublicField());
251 }
252
253
254
255
256 @Test
257 void a014_getter_withNullMethod() {
258 assertThrows(IllegalArgumentException.class, () -> {
259 Property.<TestClass, String>create()
260 .getter((MethodInfo)null)
261 .build();
262 });
263 }
264
265
266
267
268 @Test
269 void a015_setter_withNullMethod() {
270 assertThrows(IllegalArgumentException.class, () -> {
271 Property.<TestClass, String>create()
272 .setter((MethodInfo)null)
273 .build();
274 });
275 }
276
277
278
279
280 @Test
281 void a016_field_primitiveType() throws Exception {
282 var field = ClassInfo.of(TestClass.class).getDeclaredFields().stream()
283 .filter(f -> f.getName().equals("intField"))
284 .findFirst()
285 .orElseThrow();
286 var prop = Property.<TestClass, Integer>create()
287 .field(field)
288 .build();
289
290 var obj = new TestClass();
291 prop.set(obj, 42);
292 assertEquals(Integer.valueOf(42), prop.get(obj));
293 assertEquals(42, obj.getIntField());
294 }
295
296
297
298
299 @Test
300 void a017_set_withNullValue() throws Exception {
301 var prop = Property.<TestClass, String>create()
302 .getter(obj -> obj.getPublicField())
303 .setter((obj, val) -> obj.setPublicField(val))
304 .build();
305
306 var obj = new TestClass();
307 obj.setPublicField("initial");
308 prop.set(obj, null);
309 assertNull(prop.get(obj));
310 assertNull(obj.getPublicField());
311 }
312
313
314
315
316 @Test
317 void a018_get_exceptionHandling() {
318 var prop = Property.<TestClass, String>create()
319 .getter(obj -> {
320 throw new RuntimeException("Test exception");
321 })
322 .build();
323
324 var obj = new TestClass();
325 var ex = assertThrows(RuntimeException.class, () -> prop.get(obj));
326 assertEquals("Test exception", ex.getMessage());
327 }
328
329
330
331
332 @Test
333 void a019_set_exceptionHandling() {
334 var prop = Property.<TestClass, String>create()
335 .setter((obj, val) -> {
336 throw new RuntimeException("Test exception");
337 })
338 .build();
339
340 var obj = new TestClass();
341 var ex = assertThrows(RuntimeException.class, () -> prop.set(obj, "test"));
342 assertEquals("Test exception", ex.getMessage());
343 }
344
345
346
347
348 @Test
349 void a020_get_executableExceptionPassThrough() {
350 var originalEx = new ExecutableException("Original exception");
351 var prop = Property.<TestClass, String>create()
352 .getter(obj -> {
353 throw originalEx;
354 })
355 .build();
356
357 var obj = new TestClass();
358 var ex = assertThrows(ExecutableException.class, () -> prop.get(obj));
359 assertSame(originalEx, ex);
360 }
361
362
363
364
365 @Test
366 void a021_set_executableExceptionPassThrough() {
367 var originalEx = new ExecutableException("Original exception");
368 var prop = Property.<TestClass, String>create()
369 .setter((obj, val) -> {
370 throw originalEx;
371 })
372 .build();
373
374 var obj = new TestClass();
375 var ex = assertThrows(ExecutableException.class, () -> prop.set(obj, "test"));
376 assertSame(originalEx, ex);
377 }
378
379
380
381
382 @Test
383 void a022_get_checkedExceptionWrapping() {
384 var prop = Property.<TestClass, String>create()
385 .getter(obj -> {
386 throw new java.io.IOException("IO error");
387 })
388 .build();
389
390 var obj = new TestClass();
391 var ex = assertThrows(RuntimeException.class, () -> prop.get(obj));
392 assertNotNull(ex.getCause());
393 assertTrue(ex.getCause() instanceof java.io.IOException);
394 assertEquals("IO error", ex.getCause().getMessage());
395 }
396
397
398
399
400 @Test
401 void a023_set_checkedExceptionWrapping() {
402 var prop = Property.<TestClass, String>create()
403 .setter((obj, val) -> {
404 throw new java.io.IOException("IO error");
405 })
406 .build();
407
408 var obj = new TestClass();
409 var ex = assertThrows(RuntimeException.class, () -> prop.set(obj, "test"));
410 assertNotNull(ex.getCause());
411 assertTrue(ex.getCause() instanceof java.io.IOException);
412 assertEquals("IO error", ex.getCause().getMessage());
413 }
414
415
416
417
418 @Test
419 void a024_builder_chaining() throws Exception {
420 var prop = Property.<TestClass, String>create()
421 .getter(obj -> obj.getPublicField())
422 .setter((obj, val) -> obj.setPublicField(val))
423 .build();
424
425 assertNotNull(prop);
426 assertTrue(prop.canRead());
427 assertTrue(prop.canWrite());
428 }
429
430
431
432
433 @Test
434 void a025_field_roundTrip() throws Exception {
435 var field = ClassInfo.of(TestClass.class).getPublicFields().stream()
436 .filter(f -> f.getName().equals("publicField"))
437 .findFirst()
438 .orElseThrow();
439 var prop = Property.<TestClass, String>create()
440 .field(field)
441 .build();
442
443 var obj = new TestClass();
444 prop.set(obj, "value1");
445 assertEquals("value1", prop.get(obj));
446 prop.set(obj, "value2");
447 assertEquals("value2", prop.get(obj));
448 prop.set(obj, null);
449 assertNull(prop.get(obj));
450 }
451
452
453
454
455 @Test
456 void a026_methodInfo_roundTrip() throws Exception {
457 var getter = ClassInfo.of(TestClass.class).getPublicMethods().stream()
458 .filter(m -> m.hasName("getPublicField"))
459 .findFirst()
460 .orElseThrow();
461 var setter = ClassInfo.of(TestClass.class).getPublicMethods().stream()
462 .filter(m -> m.hasName("setPublicField") && m.hasParameterTypes(String.class))
463 .findFirst()
464 .orElseThrow();
465 var prop = Property.<TestClass, String>create()
466 .getter(getter)
467 .setter(setter)
468 .build();
469
470 var obj = new TestClass();
471 prop.set(obj, "value1");
472 assertEquals("value1", prop.get(obj));
473 prop.set(obj, "value2");
474 assertEquals("value2", prop.get(obj));
475 prop.set(obj, null);
476 assertNull(prop.get(obj));
477 }
478 }
479