1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.juneau.junit.bct;
18
19 import static org.apache.juneau.commons.utils.CollectionUtils.*;
20 import static org.apache.juneau.junit.bct.BctAssertions.*;
21 import static org.junit.jupiter.api.Assertions.*;
22
23 import java.io.*;
24 import java.nio.file.*;
25 import java.time.format.*;
26 import java.util.*;
27
28 import org.apache.juneau.*;
29 import org.junit.jupiter.api.*;
30 import org.junit.jupiter.params.*;
31 import org.junit.jupiter.params.provider.*;
32
33
34
35
36 class Stringifiers_Test extends TestBase {
37
38 @Nested
39 class A_mapEntryStringifier extends TestBase {
40
41 @Test
42 void a01_stringifySimpleEntry() {
43 var converter = BasicBeanConverter.builder().defaultSettings().build();
44 var stringifier = Stringifiers.mapEntryStringifier();
45 var entry = Map.entry("key", "value");
46 var result = stringifier.apply(converter, entry);
47
48 assertEquals("key=value", result);
49 }
50
51 @Test
52 void a02_stringifyWithNullKey() {
53 var converter = BasicBeanConverter.builder().defaultSettings().build();
54 var stringifier = Stringifiers.mapEntryStringifier();
55 var entry = new AbstractMap.SimpleEntry<String, String>(null, "value");
56 var result = stringifier.apply(converter, entry);
57
58 assertEquals("<null>=value", result);
59 }
60
61 @Test
62 void a03_stringifyWithNullValue() {
63 var converter = BasicBeanConverter.builder().defaultSettings().build();
64 var stringifier = Stringifiers.mapEntryStringifier();
65 var entry = new AbstractMap.SimpleEntry<>("key", null);
66 var result = stringifier.apply(converter, entry);
67
68 assertEquals("key=<null>", result);
69 }
70
71 @Test
72 void a04_stringifyWithCustomSeparator() {
73 var converter = BasicBeanConverter.builder()
74 .defaultSettings()
75 .addSetting("mapEntrySeparator", ": ")
76 .build();
77 var stringifier = Stringifiers.mapEntryStringifier();
78 var entry = Map.entry("name", "John");
79 var result = stringifier.apply(converter, entry);
80
81 assertEquals("name: John", result);
82 }
83
84 @Test
85 void a05_stringifyWithComplexValues() {
86 var converter = BasicBeanConverter.builder().defaultSettings().build();
87 var stringifier = Stringifiers.mapEntryStringifier();
88 var entry = Map.entry("list", l("a", "b"));
89 var result = stringifier.apply(converter, entry);
90
91 assertEquals("list=[a,b]", result);
92 }
93 }
94
95 @Nested
96 class B_calendarStringifier extends TestBase {
97
98 @Test
99 void b01_stringifyGregorianCalendar() {
100 var converter = BasicBeanConverter.builder().defaultSettings().build();
101 var stringifier = Stringifiers.calendarStringifier();
102 var calendar = new GregorianCalendar(2023, Calendar.JANUARY, 15, 10, 30, 0);
103 calendar.setTimeZone(TimeZone.getTimeZone("UTC"));
104 var result = stringifier.apply(converter, calendar);
105
106 assertMatchesGlob("2023-01-15T*", result);
107 }
108
109 @Test
110 void b02_stringifyWithCustomFormat() {
111 var converter = BasicBeanConverter.builder()
112 .defaultSettings()
113 .addSetting("calendarFormat", DateTimeFormatter.ISO_LOCAL_DATE)
114 .build();
115 var stringifier = Stringifiers.calendarStringifier();
116 var calendar = new GregorianCalendar(2023, Calendar.DECEMBER, 25);
117 var result = stringifier.apply(converter, calendar);
118
119 assertMatchesGlob("2023-12-25", result);
120 }
121 }
122
123 @Nested
124 class C_dateStringifier extends TestBase {
125
126 @Test
127 void c01_stringifyDate() {
128 var stringifier = Stringifiers.dateStringifier();
129 var date = new Date(1673780400000L);
130 var result = stringifier.apply(null, date);
131
132 assertEquals("2023-01-15T11:00:00Z", result);
133 }
134
135 @Test
136 void c02_stringifyDateWithConverter() {
137 var converter = BasicBeanConverter.builder().defaultSettings().build();
138 var stringifier = Stringifiers.dateStringifier();
139 var date = new Date(0);
140 var result = stringifier.apply(converter, date);
141
142 assertEquals("1970-01-01T00:00:00Z", result);
143 }
144 }
145
146 @Nested
147 class D_inputStreamStringifier extends TestBase {
148
149 @Test
150 void d01_stringifyInputStream() {
151 var stringifier = Stringifiers.inputStreamStringifier();
152 var input = new ByteArrayInputStream(bytes(0x48, 0x65, 0x6C, 0x6C, 0x6F));
153 var result = stringifier.apply(null, input);
154
155 assertEquals("48656C6C6F", result);
156 }
157
158 @Test
159 void d02_stringifyEmptyInputStream() {
160 var stringifier = Stringifiers.inputStreamStringifier();
161 var input = new ByteArrayInputStream(new byte[0]);
162 var result = stringifier.apply(null, input);
163
164 assertEquals("", result);
165 }
166
167 @Test
168 void d03_stringifyInputStreamWithZeros() {
169 var stringifier = Stringifiers.inputStreamStringifier();
170 var input = new ByteArrayInputStream(bytes(0x00, (byte)0xFF, 0x7F));
171 var result = stringifier.apply(null, input);
172
173 assertEquals("00FF7F", result);
174 }
175 }
176
177 @Nested
178 class E_byteArrayStringifier extends TestBase {
179
180 @Test
181 void e01_stringifyByteArray() {
182 var stringifier = Stringifiers.byteArrayStringifier();
183 var input = bytes(0x48, 0x65, 0x6C, 0x6C, 0x6F);
184 var result = stringifier.apply(null, input);
185
186 assertEquals("48656C6C6F", result);
187 }
188
189 @Test
190 void e02_stringifyEmptyByteArray() {
191 var stringifier = Stringifiers.byteArrayStringifier();
192 var input = new byte[0];
193 var result = stringifier.apply(null, input);
194
195 assertEquals("", result);
196 }
197
198 @Test
199 void e03_stringifyByteArrayWithAllValues() {
200 var stringifier = Stringifiers.byteArrayStringifier();
201 var input = bytes(0x00, (byte)0xFF, 0x7F, (byte)0x80);
202 var result = stringifier.apply(null, input);
203
204 assertEquals("00FF7F80", result);
205 }
206 }
207
208 @Nested
209 class F_charArrayStringifier extends TestBase {
210
211 @Test
212 void f01_stringifyCharArray() {
213 var stringifier = Stringifiers.charArrayStringifier();
214 var input = chars('H', 'e', 'l', 'l', 'o');
215 var result = stringifier.apply(null, input);
216
217 assertEquals("Hello", result);
218 }
219
220 @Test
221 void f02_stringifyEmptyCharArray() {
222 var stringifier = Stringifiers.charArrayStringifier();
223 var input = new char[0];
224 var result = stringifier.apply(null, input);
225
226 assertEquals("", result);
227 }
228
229 @Test
230 void f03_stringifyCharArrayWithHexChars() {
231 var stringifier = Stringifiers.charArrayStringifier();
232 var input = chars('0', '0', '0', '0');
233 var result = stringifier.apply(null, input);
234
235 assertEquals("0000", result);
236 }
237
238 @Test
239 void f04_stringifyCharArrayWithSpecialChars() {
240 var stringifier = Stringifiers.charArrayStringifier();
241 var input = chars('A', 'B', 'C', 'D', 'E', 'F');
242 var result = stringifier.apply(null, input);
243
244 assertEquals("ABCDEF", result);
245 }
246
247 @Test
248 void f05_stringifyCharArrayWithMixedChars() {
249 var stringifier = Stringifiers.charArrayStringifier();
250 var input = chars('a', '1', 'B', '2', 'c', '3');
251 var result = stringifier.apply(null, input);
252
253 assertEquals("a1B2c3", result);
254 }
255 }
256
257 @Nested
258 class G_readerStringifier extends TestBase {
259
260 @ParameterizedTest
261 @ValueSource(strings = {
262 "Hello World",
263 "",
264 "Line 1\nLine 2\nLine 3"
265 })
266 void g01_stringifyReader(String input) {
267 var stringifier = Stringifiers.readerStringifier();
268 var reader = new StringReader(input);
269 var result = stringifier.apply(null, reader);
270
271 assertEquals(input, result);
272 }
273 }
274
275 @Nested
276 class G_fileStringifier extends TestBase {
277
278 @Test
279 void g01_stringifyTempFile() throws Exception {
280 var stringifier = Stringifiers.fileStringifier();
281 var tempFile = Files.createTempFile("test", ".txt");
282 Files.writeString(tempFile, "Test content");
283
284 try {
285 var result = stringifier.apply(null, tempFile.toFile());
286 assertEquals("Test content", result);
287 } finally {
288 Files.deleteIfExists(tempFile);
289 }
290 }
291
292 @Test
293 void g02_stringifyEmptyFile() throws Exception {
294 var stringifier = Stringifiers.fileStringifier();
295 var tempFile = Files.createTempFile("empty", ".txt");
296
297 try {
298 var result = stringifier.apply(null, tempFile.toFile());
299 assertEquals("", result);
300 } finally {
301 Files.deleteIfExists(tempFile);
302 }
303 }
304 }
305
306 @Nested
307 class H_enumStringifier extends TestBase {
308
309 enum TestEnum { VALUE1, VALUE2, LONG_VALUE_NAME }
310
311 @Test
312 void h01_stringifyEnum() {
313 var stringifier = Stringifiers.enumStringifier();
314 var result = stringifier.apply(null, TestEnum.VALUE1);
315
316 assertEquals("VALUE1", result);
317 }
318
319 @Test
320 void h02_stringifyEnumWithLongName() {
321 var stringifier = Stringifiers.enumStringifier();
322 var result = stringifier.apply(null, TestEnum.LONG_VALUE_NAME);
323
324 assertEquals("LONG_VALUE_NAME", result);
325 }
326
327 @Test
328 void h03_stringifyStandardEnum() {
329 var stringifier = Stringifiers.enumStringifier();
330 var result = stringifier.apply(null, Thread.State.RUNNABLE);
331
332 assertEquals("RUNNABLE", result);
333 }
334 }
335
336 @Nested
337 class I_classStringifier extends TestBase {
338
339 @Test
340 void i01_stringifyClassSimple() {
341 var converter = BasicBeanConverter.builder()
342 .defaultSettings()
343 .addSetting("classNameFormat", "simple")
344 .build();
345 var stringifier = Stringifiers.classStringifier();
346 var result = stringifier.apply(converter, String.class);
347
348 assertEquals("String", result);
349 }
350
351 @Test
352 void i02_stringifyClassCanonical() {
353 var converter = BasicBeanConverter.builder()
354 .defaultSettings()
355 .addSetting("classNameFormat", "canonical")
356 .build();
357 var stringifier = Stringifiers.classStringifier();
358 var result = stringifier.apply(converter, ArrayList.class);
359
360 assertEquals("java.util.ArrayList", result);
361 }
362
363 @Test
364 void i03_stringifyClassFull() {
365 var converter = BasicBeanConverter.builder()
366 .defaultSettings()
367 .addSetting("classNameFormat", "full")
368 .build();
369 var stringifier = Stringifiers.classStringifier();
370 var result = stringifier.apply(converter, HashMap.class);
371
372 assertEquals("java.util.HashMap", result);
373 }
374
375 @Test
376 void i04_stringifyPrimitiveClass() {
377 var converter = BasicBeanConverter.builder().defaultSettings().build();
378 var stringifier = Stringifiers.classStringifier();
379 var result = stringifier.apply(converter, int.class);
380
381 assertEquals("int", result);
382 }
383 }
384
385 @Nested
386 class J_constructorStringifier extends TestBase {
387
388 @Test
389 void j01_stringifyNoArgConstructor() throws Exception {
390 var converter = BasicBeanConverter.builder().defaultSettings().build();
391 var stringifier = Stringifiers.constructorStringifier();
392 var constructor = ArrayList.class.getConstructor();
393 var result = stringifier.apply(converter, constructor);
394
395 assertEquals("ArrayList()", result);
396 }
397
398 @Test
399 void j02_stringifyParameterizedConstructor() throws Exception {
400 var converter = BasicBeanConverter.builder().defaultSettings().build();
401 var stringifier = Stringifiers.constructorStringifier();
402 var constructor = String.class.getConstructor(char[].class);
403 var result = stringifier.apply(converter, constructor);
404
405 assertEquals("String(char[])", result);
406 }
407
408 @Test
409 void j03_stringifyMultiParameterConstructor() throws Exception {
410 var converter = BasicBeanConverter.builder().defaultSettings().build();
411 var stringifier = Stringifiers.constructorStringifier();
412 var constructor = String.class.getConstructor(byte[].class, int.class, int.class);
413 var result = stringifier.apply(converter, constructor);
414
415 assertEquals("String(byte[],int,int)", result);
416 }
417 }
418
419 @Nested
420 class K_methodStringifier extends TestBase {
421
422 @Test
423 void k01_stringifyNoArgMethod() throws Exception {
424 var converter = BasicBeanConverter.builder().defaultSettings().build();
425 var stringifier = Stringifiers.methodStringifier();
426 var method = Object.class.getMethod("toString");
427 var result = stringifier.apply(converter, method);
428
429 assertEquals("toString()", result);
430 }
431
432 @Test
433 void k02_stringifyParameterizedMethod() throws Exception {
434 var converter = BasicBeanConverter.builder().defaultSettings().build();
435 var stringifier = Stringifiers.methodStringifier();
436 var method = String.class.getMethod("substring", int.class);
437 var result = stringifier.apply(converter, method);
438
439 assertEquals("substring(int)", result);
440 }
441
442 @Test
443 void k03_stringifyMultiParameterMethod() throws Exception {
444 var converter = BasicBeanConverter.builder().defaultSettings().build();
445 var stringifier = Stringifiers.methodStringifier();
446 var method = String.class.getMethod("substring", int.class, int.class);
447 var result = stringifier.apply(converter, method);
448
449 assertEquals("substring(int,int)", result);
450 }
451 }
452
453 @Nested
454 class L_listStringifier extends TestBase {
455
456 @Test
457 void l01_stringifyList() {
458 var converter = BasicBeanConverter.builder().defaultSettings().build();
459 var stringifier = Stringifiers.listStringifier();
460 var input = l("a", "b", "c");
461 var result = stringifier.apply(converter, input);
462
463 assertEquals("[a,b,c]", result);
464 }
465
466 @Test
467 void l02_stringifyEmptyList() {
468 var converter = BasicBeanConverter.builder().defaultSettings().build();
469 var stringifier = Stringifiers.listStringifier();
470 var input = l();
471 var result = stringifier.apply(converter, input);
472
473 assertEquals("[]", result);
474 }
475
476 @Test
477 void l03_stringifyWithCustomDelimiters() {
478 var converter = BasicBeanConverter.builder()
479 .defaultSettings()
480 .addSetting("fieldSeparator", "; ")
481 .addSetting("collectionPrefix", "(")
482 .addSetting("collectionSuffix", ")")
483 .build();
484 var stringifier = Stringifiers.listStringifier();
485 var input = l("x", "y", "z");
486 var result = stringifier.apply(converter, input);
487
488 assertEquals("(x; y; z)", result);
489 }
490
491 @Test
492 void l04_stringifyWithNullElements() {
493 var converter = BasicBeanConverter.builder().defaultSettings().build();
494 var stringifier = Stringifiers.listStringifier();
495 var input = l("a", null, "c");
496 var result = stringifier.apply(converter, input);
497
498 assertEquals("[a,<null>,c]", result);
499 }
500 }
501
502 @Nested
503 class M_mapStringifier extends TestBase {
504
505 @Test
506 void m01_stringifyMap() {
507 var converter = BasicBeanConverter.builder().defaultSettings().build();
508 var stringifier = Stringifiers.mapStringifier();
509 var input = m("key1", "value1", "key2", "value2");
510 var result = stringifier.apply(converter, input);
511
512
513 assertTrue(result.equals("{key1=value1,key2=value2}") ||
514 result.equals("{key2=value2,key1=value1}"));
515 }
516
517 @Test
518 void m02_stringifyEmptyMap() {
519 var converter = BasicBeanConverter.builder().defaultSettings().build();
520 var stringifier = Stringifiers.mapStringifier();
521 var input = m();
522 var result = stringifier.apply(converter, input);
523
524 assertEquals("{}", result);
525 }
526
527 @Test
528 void m03_stringifyWithCustomDelimiters() {
529 var converter = BasicBeanConverter.builder()
530 .defaultSettings()
531 .addSetting("fieldSeparator", "; ")
532 .addSetting("mapPrefix", "<")
533 .addSetting("mapSuffix", ">")
534 .build();
535 var stringifier = Stringifiers.mapStringifier();
536 var input = m("a", "1");
537 var result = stringifier.apply(converter, input);
538
539 assertEquals("<a=1>", result);
540 }
541
542 @Test
543 void m04_stringifyWithNullValues() {
544 var converter = BasicBeanConverter.builder().defaultSettings().build();
545 var stringifier = Stringifiers.mapStringifier();
546 var input = new HashMap<String, String>();
547 input.put("key1", "value1");
548 input.put("key2", null);
549 var result = stringifier.apply(converter, input);
550
551 assertTrue(result.contains("key1=value1"));
552 assertTrue(result.contains("key2=<null>"));
553 }
554 }
555
556 @Nested
557 class N_integration extends TestBase {
558
559 @Test
560 void n01_useInBasicBeanConverter() {
561
562 assertBean(Map.entry("k", "v"), "<self>", "k=v");
563 assertBean(l("a", "b"), "<self>", "[a,b]");
564 assertBean(m("x", "y"), "<self>", "{x=y}");
565 assertBean(TestEnum.VALUE1, "<self>", "VALUE1");
566 assertBean(String.class, "<self>", "String");
567 }
568
569 @Test
570 void n02_customStringifierRegistration() {
571
572 assertBean(l("custom"), "<self>", "[custom]");
573 }
574
575 @Test
576 void n03_stringifierChaining() {
577
578 var complexMap = m("items", l("a", "b"));
579 assertMatchesGlob("*items=[a,b]*", BasicBeanConverter.DEFAULT.stringify(complexMap));
580 }
581
582 private enum TestEnum { VALUE1, VALUE2 }
583 }
584 }