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.util.*;
24 import java.util.function.*;
25
26 import org.apache.juneau.*;
27 import org.junit.jupiter.api.*;
28
29
30
31
32
33
34
35 class Listifier_Test extends TestBase {
36
37
38
39
40
41 @Nested
42 class A_functionalInterfaceCompliance extends TestBase {
43
44 @SuppressWarnings("cast")
45 @Test
46 void a01_functionalInterfaceContract() {
47
48 Listifier<String> listifier = (converter, obj) -> l(obj, obj.toUpperCase());
49
50 assertNotNull(listifier);
51 assertTrue(listifier instanceof BiFunction);
52 assertTrue(listifier instanceof Listifier);
53 }
54
55 @Test
56 void a02_lambdaExpressionCompatibility() {
57
58 Listifier<String> lambda = (converter, str) -> l(str.toLowerCase(), str.toUpperCase());
59
60 var converter = BasicBeanConverter.DEFAULT;
61 var result = lambda.apply(converter, "Test");
62
63 assertSize(2, result);
64 assertEquals("test", result.get(0));
65 assertEquals("TEST", result.get(1));
66 }
67
68 @Test
69 void a03_methodReferenceCompatibility() {
70
71 Listifier<String> methodRef = ListifierMethods::splitToChars;
72
73 var converter = BasicBeanConverter.DEFAULT;
74 var result = methodRef.apply(converter, "abc");
75
76 assertSize(3, result);
77 assertEquals("a", result.get(0));
78 assertEquals("b", result.get(1));
79 assertEquals("c", result.get(2));
80 }
81
82 @Test
83 void a04_biFunctionInheritance() {
84
85 Listifier<String> listifier = (converter, str) -> l((Object[])str.split(""));
86
87
88 var converter = BasicBeanConverter.DEFAULT;
89 var result = listifier.apply(converter, "xy");
90 assertSize(2, result);
91 }
92 }
93
94
95
96
97
98 @Nested
99 class B_lambdaComposition extends TestBase {
100
101 @Test
102 void b01_andThenComposition() {
103 Listifier<String> base = (converter, str) -> l(str.toLowerCase());
104 Function<List<Object>, List<Object>> mapper = list -> {
105 List<Object> result = new ArrayList<>(list);
106 result.add("ADDED");
107 return result;
108 };
109
110 BiFunction<BeanConverter, String, List<Object>> composed = base.andThen(mapper);
111
112 var converter = BasicBeanConverter.DEFAULT;
113 var result = composed.apply(converter, "TEST");
114
115 assertSize(2, result);
116 assertEquals("test", result.get(0));
117 assertEquals("ADDED", result.get(1));
118 }
119
120 @Test
121 void b02_functionalComposition() {
122
123 Listifier<String> splitter = (converter, str) -> l((Object[])str.split(","));
124 Listifier<String> trimmer = (converter, str) -> l((Object[])str.trim().split("\\s+"));
125
126 var converter = BasicBeanConverter.DEFAULT;
127
128 var splitResult = splitter.apply(converter, "a,b,c");
129 assertSize(3, splitResult);
130
131 var trimResult = trimmer.apply(converter, " hello world ");
132 assertSize(2, trimResult);
133 assertEquals("hello", trimResult.get(0));
134 assertEquals("world", trimResult.get(1));
135 }
136 }
137
138
139
140
141
142 @Nested
143 class C_edgeCases extends TestBase {
144
145 @Test
146 void c01_nullInputHandling() {
147 Listifier<String> nullSafe = (converter, str) -> {
148 if (str == null) return l("NULL_INPUT");
149 return l(str);
150 };
151
152 var converter = BasicBeanConverter.DEFAULT;
153 var result = nullSafe.apply(converter, null);
154
155 assertSize(1, result);
156 assertEquals("NULL_INPUT", result.get(0));
157 }
158
159 @Test
160 void c02_emptyResultHandling() {
161 Listifier<String> emptyReturner = (converter, str) -> list();
162
163 var converter = BasicBeanConverter.DEFAULT;
164 var result = emptyReturner.apply(converter, "anything");
165
166 assertNotNull(result);
167 assertEmpty(result);
168 }
169
170 @Test
171 void c03_exceptionHandling() {
172 Listifier<String> throwing = (converter, str) -> {
173 if ("ERROR".equals(str)) {
174 throw new RuntimeException("Intentional test exception");
175 }
176 return l(str);
177 };
178
179 var converter = BasicBeanConverter.DEFAULT;
180
181
182 var normalResult = throwing.apply(converter, "normal");
183 assertSize(1, normalResult);
184 assertEquals("normal", normalResult.get(0));
185
186
187 assertThrows(RuntimeException.class, () -> throwing.apply(converter, "ERROR"));
188 }
189
190 @Test
191 void c04_largeListHandling() {
192 Listifier<Integer> largeListGenerator = (converter, count) -> {
193 List<Object> result = list();
194 for (var i = 0; i < count; i++) {
195 result.add("item_" + i);
196 }
197 return result;
198 };
199
200 var converter = BasicBeanConverter.DEFAULT;
201 var result = largeListGenerator.apply(converter, 1000);
202
203 assertSize(1000, result);
204 assertEquals("item_0", result.get(0));
205 assertEquals("item_999", result.get(999));
206 }
207 }
208
209
210
211
212
213 @Nested
214 class D_integration extends TestBase {
215
216 @Test
217 void d01_converterIntegration() {
218
219 var customConverter = BasicBeanConverter.builder()
220 .defaultSettings()
221 .addListifier(TestObject.class, (converter, obj) ->
222 l(obj.name, obj.value, "LISTIFIED"))
223 .build();
224
225 var test = new TestObject("test", 42);
226 var result = customConverter.listify(test);
227
228 assertSize(3, result);
229 assertEquals("test", result.get(0));
230 assertEquals(42, result.get(1));
231 assertEquals("LISTIFIED", result.get(2));
232 }
233
234 @Test
235 void d02_multipleListifierRegistration() {
236 var customConverter = BasicBeanConverter.builder()
237 .defaultSettings()
238 .addListifier(String.class, (converter, str) -> l(str.toLowerCase()))
239 .addListifier(Integer.class, (converter, num) -> l(num, num * 2))
240 .build();
241
242
243 var stringResult = customConverter.listify("TEST");
244 assertSize(1, stringResult);
245 assertEquals("test", stringResult.get(0));
246
247
248 var intResult = customConverter.listify(5);
249 assertSize(2, intResult);
250 assertEquals(5, intResult.get(0));
251 assertEquals(10, intResult.get(1));
252 }
253
254 @Test
255 void d03_converterPassthrough() {
256
257 Listifier<String> converterUser = (converter, str) -> {
258
259 String stringified = converter.stringify(l("nested", "call"));
260 return l(str, stringified);
261 };
262
263 var converter = BasicBeanConverter.DEFAULT;
264 var result = converterUser.apply(converter, "test");
265
266 assertSize(2, result);
267 assertEquals("test", result.get(0));
268 assertTrue(result.get(1).toString().contains("nested"));
269 }
270 }
271
272
273
274
275
276 @Nested
277 class E_performance extends TestBase {
278
279 @Test
280 void e01_performanceWithLargeLists() {
281 Listifier<Integer> rangeGenerator = (converter, count) -> {
282 List<Object> result = list();
283 for (var i = 0; i < count; i++) {
284 result.add(i);
285 }
286 return result;
287 };
288
289 var converter = BasicBeanConverter.DEFAULT;
290
291 var start = System.currentTimeMillis();
292 var result = rangeGenerator.apply(converter, 10000);
293 var end = System.currentTimeMillis();
294
295 assertSize(10000, result);
296 assertTrue(end - start < 1000, "Should complete within 1 second");
297 }
298
299 @Test
300 void e02_memoryEfficiency() {
301 Listifier<String> memoryTest = (converter, str) -> {
302
303 List<Object> result = list();
304 for (var i = 0; i < 1000; i++) {
305 result.add(str + "_" + i);
306 }
307 return result;
308 };
309
310 var converter = BasicBeanConverter.DEFAULT;
311 var result = memoryTest.apply(converter, "test");
312
313 assertSize(1000, result);
314 assertEquals("test_0", result.get(0));
315 assertEquals("test_999", result.get(999));
316 }
317 }
318
319
320
321
322
323 static class ListifierMethods {
324 static List<Object> splitToChars(BeanConverter converter, String str) {
325 return l((Object[])str.split(""));
326 }
327 }
328
329 static class TestObject {
330 final String name;
331 final int value;
332
333 TestObject(String name, int value) {
334 this.name = name;
335 this.value = value;
336 }
337 }
338 }