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