1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.juneau.urlencoding;
18
19 import static org.apache.juneau.TestUtils.*;
20 import static org.apache.juneau.junit.bct.BctAssertions.*;
21 import static org.junit.jupiter.api.Assertions.*;
22
23 import java.util.*;
24
25 import org.apache.juneau.*;
26 import org.apache.juneau.collections.*;
27 import org.apache.juneau.parser.*;
28 import org.junit.jupiter.api.*;
29
30 @SuppressWarnings("rawtypes")
31 class UrlEncodingParser_Test extends TestBase {
32
33 static UrlEncodingParser p = UrlEncodingParser.DEFAULT;
34 static BeanSession bs = p.getBeanContext().getSession();
35
36
37
38
39 @Test void a01_basic() throws Exception {
40
41
42
43 var t = "_value=a";
44 assertEquals("a", p.parse(t, Object.class));
45 assertEquals("a", p.parse(t, String.class));
46 t = "_value='a'";
47 assertEquals("a", p.parse(t, String.class));
48 assertEquals("a", p.parse(t, Object.class));
49 t = "_value= 'a' ";
50 assertEquals("a", p.parse(t, String.class));
51
52
53 t = "?a=a";
54 assertEquals("a", p.parse(t, Map.class).get("a"));
55
56
57
58 t = "?a=b&c=123&d=false&e=true&f=null";
59 var m = p.parse(t, Map.class);
60 assertEquals("b", m.get("a"));
61 assertTrue(m.get("c") instanceof Number);
62 assertEquals(123, m.get("c"));
63 assertTrue(m.get("d") instanceof Boolean);
64 assertEquals(Boolean.FALSE, m.get("d"));
65 assertTrue(m.get("e") instanceof Boolean);
66 assertEquals(Boolean.TRUE, m.get("e"));
67 assertNull(m.get("f"));
68
69 t = "?a=true";
70 m = p.parse(t, HashMap.class, String.class, Boolean.class);
71 assertTrue(m.get("a") instanceof Boolean);
72 assertEquals("true", m.get("a").toString());
73
74
75
76 t = "_value=null";
77 assertNull(p.parse(t, Object.class));
78
79
80 t = "?null=null";
81 m = p.parse(t, Map.class);
82 assertTrue(m.containsKey(null));
83 assertNull(m.get(null));
84
85 t = "?null=null";
86 m = p.parse(t, Map.class);
87 assertTrue(m.containsKey(null));
88 assertNull(m.get(null));
89
90
91 t = "?null=(null=null)";
92 m = p.parse(t, Map.class);
93 assertTrue(((Map)m.get(null)).containsKey(null));
94 assertNull(((Map)m.get(null)).get(null));
95
96
97
98
99 t = "?x=@()";
100 m = p.parse(t, HashMap.class, String.class, List.class);
101 assertTrue(m.containsKey("x"));
102 assertEmpty(m.get("x"));
103 m = (Map)p.parse(t, Object.class);
104 assertTrue(m.containsKey("x"));
105 assertEmpty(m.get("x"));
106 t = "?x=@()";
107 m = p.parse(t, HashMap.class, String.class, List.class);
108 assertTrue(m.containsKey("x"));
109 assertEmpty(m.get("x"));
110
111
112 t = "_value=@(@())";
113 var l = (List)p.parse(t, Object.class);
114 assertSize(1, l);
115 l = (List)l.get(0);
116 assertEmpty(l);
117 t = "0=@()";
118 l = p.parse(t, LinkedList.class, List.class);
119 assertSize(1, l);
120 l = (List)l.get(0);
121 assertEmpty(l);
122
123
124
125 t = "_value=@('')";
126 l = (List)p.parse(t, Object.class);
127 assertSize(1, l);
128 assertEquals("", l.get(0));
129 t = "0=''";
130 l = p.parse(t, List.class, String.class);
131 assertSize(1, l);
132 assertEquals("", l.get(0));
133
134
135 t = "?''=@('')";
136 m = (Map)p.parse(t, Object.class);
137 assertEquals("", ((List)m.get("")).get(0));
138 t = "?''=@('')";
139 m = p.parse(t, HashMap.class, String.class, List.class);
140 assertEquals("", ((List)m.get("")).get(0));
141
142
143 t = "_value=@('','','')";
144 l = (List)p.parse(t, Object.class);
145 assertSize(3, l);
146 assertEquals("", l.get(0));
147 assertEquals("", l.get(1));
148 assertEquals("", l.get(2));
149 t = "0=''&1=''&2=''";
150 l = p.parse(t, List.class, Object.class);
151 assertSize(3, l);
152 assertEquals("", l.get(0));
153 assertEquals("", l.get(1));
154 assertEquals("", l.get(2));
155
156
157
158 t = "_value='\u0000'";
159 assertEquals("\u0000", p.parse(t, Object.class));
160 t = "_value='\u0000'";
161 assertEquals("\u0000", p.parse(t, String.class));
162 assertEquals("\u0000", p.parse(t, Object.class));
163
164
165 t = "?'\u0000'='\u0000'";
166 m = (Map)p.parse(t, Object.class);
167 assertSize(1, m);
168 assertEquals("\u0000", m.get("\u0000"));
169 m = p.parse(t, HashMap.class, String.class, Object.class);
170 assertSize(1, m);
171 assertEquals("\u0000", m.get("\u0000"));
172
173
174
175 t = "_value=false";
176 var b = (Boolean)p.parse(t, Object.class);
177 assertEquals(Boolean.FALSE, b);
178 b = p.parse(t, Boolean.class);
179 assertEquals(Boolean.FALSE, b);
180 t = "_value=false";
181 b = p.parse(t, Boolean.class);
182 assertEquals(Boolean.FALSE, b);
183
184
185 t = "?x=false";
186 m = (Map)p.parse(t, Object.class);
187 assertEquals(Boolean.FALSE, m.get("x"));
188 t = "?x=false";
189 m = p.parse(t, HashMap.class, String.class, Boolean.class);
190 assertEquals(Boolean.FALSE, m.get("x"));
191
192
193
194 t = "_value=123";
195 var i = (Integer)p.parse(t, Object.class);
196 assertEquals(123, i.intValue());
197 i = p.parse(t, Integer.class);
198 assertEquals(123, i.intValue());
199 var d = p.parse(t, Double.class);
200 assertEquals(123, d.intValue());
201 var f = p.parse(t, Float.class);
202 assertEquals(123, f.intValue());
203 t = "_value=123";
204 i = p.parse(t, Integer.class);
205 assertEquals(123, i.intValue());
206
207
208 t = "?x=123";
209 m = (Map)p.parse(t, Object.class);
210 assertEquals(123, ((Integer)m.get("x")).intValue());
211 m = p.parse(t, HashMap.class, String.class, Double.class);
212 assertEquals(123, ((Double)m.get("x")).intValue());
213
214
215
216 t = "_value=x;/?:@-_.!*'";
217 assertEquals("x;/?:@-_.!*'", p.parse(t, Object.class));
218
219
220 t = "?x;/?:@-_.!*'=x;/?:@-_.!*'";
221 m = (Map)p.parse(t, Object.class);
222 assertEquals("x;/?:@-_.!*'", m.get("x;/?:@-_.!*'"));
223 m = p.parse(t, HashMap.class, String.class, Object.class);
224 assertEquals("x;/?:@-_.!*'", m.get("x;/?:@-_.!*'"));
225 m = p.parse(t, HashMap.class, String.class, String.class);
226 assertEquals("x;/?:@-_.!*'", m.get("x;/?:@-_.!*'"));
227
228
229
230 assertThrows(ParseException.class, ()->p.parse("_value=x{}|\\^[]`<>#%\"&+", Object.class));
231 t = "_value=x%7B%7D%7C%5C%5E%5B%5D%60%3C%3E%23%25%22%26%2B";
232 assertEquals("x{}|\\^[]`<>#%\"&+", p.parse(t, Object.class));
233 assertEquals("x{}|\\^[]`<>#%\"&+", p.parse(t, String.class));
234
235
236 assertThrows(ParseException.class, ()->p.parse("?x{}|\\^[]`<>#%\"&+=x{}|\\^[]`<>#%\"&+", Object.class));
237 t = "?x%7B%7D%7C%5C%5E%5B%5D%60%3C%3E%23%25%22%26%2B=x%7B%7D%7C%5C%5E%5B%5D%60%3C%3E%23%25%22%26%2B";
238 m = (Map)p.parse(t, Object.class);
239 assertEquals("x{}|\\^[]`<>#%\"&+", m.get("x{}|\\^[]`<>#%\"&+"));
240
241
242
243
244 t = "_value='x$,()'";
245 assertEquals("x$,()", p.parse(t, Object.class));
246 t = "_value='x~~$~~,~~(~~)'";
247 assertEquals("x~$~,~(~)", p.parse(t, Object.class));
248
249
250
251 t = "?'x$,()'='x$,()'";
252 m = (Map)p.parse(t, Object.class);
253 assertEquals("x$,()", m.get("x$,()"));
254 t = "?'x~~$~~,~~(~~)'='x~~$~~,~~(~~)'";
255 m = (Map)p.parse(t, Object.class);
256 assertEquals("x~$~,~(~)", m.get("x~$~,~(~)"));
257
258
259
260
261 t = "_value='x='";
262 assertEquals("x=", p.parse(t, Object.class));
263 t = "_value='x%3D'";
264 assertEquals("x=", p.parse(t, Object.class));
265
266
267 t = "?'x%3D'='x%3D'";
268 m = (Map)p.parse(t, Object.class);
269 assertEquals("x=", m.get("x="));
270 t = "?'x~~%3D'='x~~%3D'";
271 m = (Map)p.parse(t, Object.class);
272 assertEquals("x~=", m.get("x~="));
273
274
275
276 t = "_value='()'";
277 assertEquals("()", p.parse(t, Object.class));
278 assertEquals("()", p.parse(t, String.class));
279 t = "_value='()'";
280 assertEquals("()", p.parse(t, Object.class));
281 assertEquals("()", p.parse(t, String.class));
282
283
284 t = "?'()'='()'";
285 m = (Map)p.parse(t, Object.class);
286 assertEquals("()", m.get("()"));
287 t = "?'()'='()'";
288 m = p.parse(t, HashMap.class, String.class, Object.class);
289 assertEquals("()", m.get("()"));
290
291
292
293 t = "_value=$a";
294 assertEquals("$a", p.parse(t, Object.class));
295 t = "_value=$a";
296 assertEquals("$a", p.parse(t, Object.class));
297
298
299 t = "?$a=$a";
300 m = (Map)p.parse(t, Object.class);
301 assertEquals("$a", m.get("$a"));
302 m = p.parse(t, HashMap.class, String.class, Object.class);
303 assertEquals("$a", m.get("$a"));
304
305
306
307 t = "_value=";
308 assertEquals("", p.parse(t, Object.class));
309
310
311 t = "?=";
312 m = (Map)p.parse(t, Object.class);
313 assertEquals("", m.get(""));
314 m = p.parse(t, HashMap.class, String.class, Object.class);
315 assertEquals("", m.get(""));
316
317
318 t = "?=(=)";
319 m = (Map)p.parse(t, Object.class);
320 assertEquals("", ((Map)m.get("")).get(""));
321 t = "?=(=)";
322 m = p.parse(t, HashMap.class, String.class, HashMap.class);
323 assertEquals("", ((Map)m.get("")).get(""));
324
325
326
327 t = "_value='%0A'";
328 assertEquals("\n", p.parse(t, Object.class));
329
330
331 t = "?'%0A'='%0A'";
332 m = (Map)p.parse(t, Object.class);
333 assertEquals("\n", m.get("\n"));
334
335
336 t = "?'%0A'=('%0A'='%0A')";
337 m = (Map)p.parse(t, Object.class);
338 assertEquals("\n", ((Map)m.get("\n")).get("\n"));
339 }
340
341
342
343
344 @Test void a02_unicodeChars() throws Exception {
345
346
347 var t = "_value=¢";
348 assertEquals("¢", p.parse(t, Object.class));
349 assertEquals("¢", p.parse(t, String.class));
350 t = "_value=%C2%A2";
351 assertEquals("¢", p.parse(t, Object.class));
352 assertEquals("¢", p.parse(t, String.class));
353
354
355 t = "?%C2%A2=%C2%A2";
356 var m = (Map)p.parse(t, Object.class);
357 assertEquals("¢", m.get("¢"));
358
359
360 t = "?%C2%A2=(%C2%A2=%C2%A2)";
361 m = (Map)p.parse(t, Object.class);
362 assertEquals("¢", ((Map)m.get("¢")).get("¢"));
363
364
365
366 t = "_value=€";
367 assertEquals("€", p.parse(t, Object.class));
368 assertEquals("€", p.parse(t, String.class));
369 t = "_value=%E2%82%AC";
370 assertEquals("€", p.parse(t, Object.class));
371 assertEquals("€", p.parse(t, String.class));
372
373
374 t = "?%E2%82%AC=%E2%82%AC";
375 m = (Map)p.parse(t, Object.class);
376 assertEquals("€", m.get("€"));
377
378
379 t = "?%E2%82%AC=(%E2%82%AC=%E2%82%AC)";
380 m = (Map)p.parse(t, Object.class);
381 assertEquals("€", ((Map)m.get("€")).get("€"));
382
383
384
385 t = "_value=𤭢";
386 assertEquals("𤭢", p.parse(t, Object.class));
387 assertEquals("𤭢", p.parse(t, String.class));
388 t = "_value=%F0%A4%AD%A2";
389 assertEquals("𤭢", p.parse(t, Object.class));
390 assertEquals("𤭢", p.parse(t, String.class));
391
392
393 t = "?%F0%A4%AD%A2=%F0%A4%AD%A2";
394 m = (Map)p.parse(t, Object.class);
395 assertEquals("𤭢", m.get("𤭢"));
396
397
398 t = "?%F0%A4%AD%A2=(%F0%A4%AD%A2=%F0%A4%AD%A2)";
399 m = (Map)p.parse(t, Object.class);
400 assertEquals("𤭢", ((Map)m.get("𤭢")).get("𤭢"));
401 }
402
403
404
405
406 @Test void a03_simpleBean() throws Exception {
407 var p2 = UrlEncodingParser.DEFAULT;
408 var s = "?f1=foo&f2=123";
409 var t = p2.parse(s, A.class);
410 assertEquals("foo", t.f1);
411 assertEquals(123, t.f2);
412 }
413
414 public static class A {
415 public String f1;
416 public int f2;
417 }
418
419
420
421
422 @Test void a04_noValues() throws Exception {
423 var p2 = UrlEncodingParser.DEFAULT;
424 var s = "?f1";
425 var m = p2.parse(s, JsonMap.class);
426 assertTrue(m.containsKey("f1"));
427 assertNull(m.get("f1"));
428 s = "?f1=f2&f3";
429 m = p2.parse(s, JsonMap.class);
430 assertEquals("f2", m.get("f1"));
431 assertTrue(m.containsKey("f3"));
432 assertNull(m.get("f3"));
433 }
434
435
436
437
438 @Test void a05_commaDelimitedLists() throws Exception {
439 var p2 = UrlEncodingParser.DEFAULT;
440 var s = "?f1=1,2,3&f2=a,b,c&f3=true,false&f4=&f5";
441 var c = p2.parse(s, C.class);
442 assertBean(c, "f1,f2,f3,f4", "[1,2,3],[a,b,c],[true,false],[]");
443 }
444
445 public static class C {
446 public int[] f1;
447 public String[] f2;
448 public boolean[] f3;
449 public String[] f4;
450 public String[] f5;
451 }
452
453
454
455
456 @Test void a06_commaDelimitedListsWithSpecialChars() throws Exception {
457 var p2 = UrlEncodingParser.DEFAULT;
458
459
460 var s = "?f1=a~b,a~b";
461 var c = p2.parse(s, C1.class);
462 assertBean(c, "f1", "[a~b,a~b]");
463
464 s = "?f1=@(a~b,a~b)";
465 c = p2.parse(s, C1.class);
466 assertBean(c, "f1", "[a~b,a~b]");
467
468 s = "?f1=@('a~b','a~b')";
469 c = p2.parse(s, C1.class);
470 assertBean(c, "f1", "[a~b,a~b]");
471
472 s = "?f1=@('a~b','a~b')";
473 c = p2.parse(s, C1.class);
474 assertBean(c, "f1", "[a~b,a~b]");
475
476 s = "?f1=@('a~b','a~b')";
477 c = p2.parse(s, C1.class);
478 assertBean(c, "f1", "[a~b,a~b]");
479
480 s = "?f1=~~,~~";
481 c = p2.parse(s, C1.class);
482 assertJson("{f1:['~','~']}", c);
483
484 s = "?f1=@(~~,~~)";
485 c = p2.parse(s, C1.class);
486 assertJson("{f1:['~','~']}", c);
487
488 s = "?f1=@(~~~~~~,~~~~~~)";
489 c = p2.parse(s, C1.class);
490 assertJson("{f1:['~~~','~~~']}", c);
491
492 s = "?f1=@('~~~~~~','~~~~~~')";
493 c = p2.parse(s, C1.class);
494 assertJson("{f1:['~~~','~~~']}", c);
495
496
497 s = "?f1=~'~~,~'~~";
498 c = p2.parse(s, C1.class);
499 assertJson("{f1:['\\'~','\\'~']}", c);
500
501 s = "?f1=@(~'~~,~'~~)";
502 c = p2.parse(s, C1.class);
503 assertJson("{f1:['\\'~','\\'~']}", c);
504
505 s = "?f1=@('~'~~','~'~~')";
506 c = p2.parse(s, C1.class);
507 assertJson("{f1:['\\'~','\\'~']}", c);
508
509 s = "?a~b=a~b";
510 var m = p2.parse(s, JsonMap.class);
511 assertEquals("{'a~b':'a~b'}", m.toString());
512
513 s = "?'a~b'='a~b'";
514 m = p2.parse(s, JsonMap.class);
515 assertEquals("{'a~b':'a~b'}", m.toString());
516
517 s = "?~~=~~";
518 m = p2.parse(s, JsonMap.class);
519 assertEquals("{'~':'~'}", m.toString());
520
521 s = "?'~~'='~~'";
522 m = p2.parse(s, JsonMap.class);
523 assertEquals("{'~':'~'}", m.toString());
524
525 s = "?~~~~~~=~~~~~~";
526 m = p2.parse(s, JsonMap.class);
527 assertEquals("{'~~~':'~~~'}", m.toString());
528
529 s = "?'~~~~~~'='~~~~~~'";
530 m = p2.parse(s, JsonMap.class);
531 assertEquals("{'~~~':'~~~'}", m.toString());
532 }
533
534 public static class C1 {
535 public String[] f1;
536 }
537
538
539
540
541 @Test void a07_whitespace() throws Exception {
542 var p2 = UrlEncodingParser.DEFAULT;
543 var s = "?f1=foo\n\t&f2=bar\n\t";
544 var m = p2.parse(s, JsonMap.class);
545 assertEquals("{f1:'foo',f2:'bar'}", m.toString());
546
547 s = "?f1='\n\t'&f2='\n\t'";
548 m = p2.parse(s, JsonMap.class);
549 assertEquals("\n\t", m.getString("f1"));
550 assertEquals("\n\t", m.getString("f2"));
551
552 s = "?f1='\n\t'\n\t&f2='\n\t'\n\t";
553 m = p2.parse(s, JsonMap.class);
554 assertEquals("\n\t", m.getString("f1"));
555 assertEquals("\n\t", m.getString("f2"));
556 assertEquals("{f1:'\\n\\t',f2:'\\n\\t'}", m.toString());
557
558 s = "?f1='\n\t'\n\t&f2='\n\t'\n\t";
559 m = p2.parse(s, JsonMap.class);
560 assertEquals("\n\t", m.getString("f1"));
561 assertEquals("\n\t", m.getString("f2"));
562 assertEquals("{f1:'\\n\\t',f2:'\\n\\t'}", m.toString());
563
564 s = "?f1=(\n\tf1a=a,\n\tf1b=b\n\t)\n\t&f2=(\n\tf2a=a,\n\tf2b=b\n\t)\n\t";
565 m = p2.parse(s, JsonMap.class);
566 assertEquals("{f1:{f1a:'a',f1b:'b'},f2:{f2a:'a',f2b:'b'}}", m.toString());
567 var d = p2.parse(s, D.class);
568 assertBean(d, "f1{f1a,f1b},f2{f2a,f2b}", "{a,b},{a,b}");
569
570 s = "?f1=(\n\tf1a='\n\t',\n\tf1b='\n\t'\n\t)\n\t&f2=(\n\tf2a='\n\t',\n\tf2b='\n\t'\n\t)\n\t";
571 m = p2.parse(s, JsonMap.class);
572 assertEquals("{f1:{f1a:'\\n\\t',f1b:'\\n\\t'},f2:{f2a:'\\n\\t',f2b:'\\n\\t'}}", m.toString());
573 d = p2.parse(s, D.class);
574 assertBean(d, "f1{f1a,f1b},f2{f2a,f2b}", "{\n\t,\n\t},{\n\t,\n\t}");
575
576 s = "?f1=@(\n\tfoo,\n\tbar\n\t)\n\t&f2=@(\n\tfoo,\n\tbar\n\t)\n\t";
577 m = p2.parse(s, JsonMap.class);
578 assertEquals("{f1:['foo','bar'],f2:['foo','bar']}", m.toString());
579
580 s = "f1=a,\n\tb,\n\tc\n\t&f2=1,\n\t2,\n\t3\n\t&f3=true,\n\tfalse\n\t";
581 var e = p2.parse(s, E.class);
582 assertBean(e, "f1,f2,f3", "[a,b,c],[1,2,3],[true,false]");
583
584 s = "f1=a%2C%0D%0Ab%2C%0D%0Ac%0D%0A&f2=1%2C%0D%0A2%2C%0D%0A3%0D%0A&f3=true%2C%0D%0Afalse%0D%0A";
585 e = p2.parse(s, E.class);
586 assertBean(e, "f1,f2,f3", "[a,b,c],[1,2,3],[true,false]");
587 }
588
589 public static class D {
590 public D1 f1;
591 public D2 f2;
592 }
593
594 public static class D1 {
595 public String f1a, f1b;
596 }
597
598 public static class D2 {
599 public String f2a, f2b;
600 }
601
602 public static class E {
603 public String[] f1;
604 public int[] f2;
605 public boolean[] f3;
606 }
607
608
609
610
611 @Test void a08_multiPartParametersOnBeansViaProperty() throws Exception {
612 var p2 = UrlEncodingParser.create().expandedParams().build();
613 var in = """
614 f01=a&f01=b\
615 &f02=c&f02=d\
616 &f03=1&f03=2\
617 &f04=3&f04=4\
618 &f05=@(e,f)&f05=@(g,h)\
619 &f06=@(i,j)&f06=@(k,l)\
620 &f07=(a=a,b=1,c=true)&f07=(a=b,b=2,c=false)\
621 &f08=(a=a,b=1,c=true)&f08=(a=b,b=2,c=false)\
622 &f09=@((a=a,b=1,c=true))&f09=@((a=b,b=2,c=false))\
623 &f10=@((a=a,b=1,c=true))&f10=@((a=b,b=2,c=false))\
624 &f11=a&f11=b\
625 &f12=c&f12=d\
626 &f13=1&f13=2\
627 &f14=3&f14=4\
628 &f15=@(e,f)&f15=@(g,h)\
629 &f16=@(i,j)&f16=@(k,l)\
630 &f17=(a=a,b=1,c=true)&f17=(a=b,b=2,c=false)\
631 &f18=(a=a,b=1,c=true)&f18=(a=b,b=2,c=false)\
632 &f19=@((a=a,b=1,c=true))&f19=@((a=b,b=2,c=false))\
633 &f20=@((a=a,b=1,c=true))&f20=@((a=b,b=2,c=false))""";
634
635 var t = p2.parse(in, DTOs.B.class);
636 assertBean(t,
637 "f01,f02,f03,f04,f05,f06,f07{#{a,b,c}},f08{#{a,b,c}},f09{#{#{a,b,c}}},f10{#{#{a,b,c}}},f11,f12,f13,f14,f15,f16,f17{#{a,b,c}},f18{#{a,b,c}},f19{#{#{a,b,c}}},f20{#{#{a,b,c}}}",
638 "[a,b],[c,d],[1,2],[3,4],[[e,f],[g,h]],[[i,j],[k,l]],{[{a,1,true},{b,2,false}]},{[{a,1,true},{b,2,false}]},{[{[{a,1,true}]},{[{b,2,false}]}]},{[{[{a,1,true}]},{[{b,2,false}]}]},[a,b],[c,d],[1,2],[3,4],[[e,f],[g,h]],[[i,j],[k,l]],{[{a,1,true},{b,2,false}]},{[{a,1,true},{b,2,false}]},{[{[{a,1,true}]},{[{b,2,false}]}]},{[{[{a,1,true}]},{[{b,2,false}]}]}");
639 }
640
641 @Test void a09_multiPartParametersOnBeansViaProperty_usingConfig() throws Exception {
642 var p2 = UrlEncodingParser.create().expandedParams().applyAnnotations(DTOs2.Annotations.class).build();
643 var in = """
644 f01=a&f01=b\
645 &f02=c&f02=d\
646 &f03=1&f03=2\
647 &f04=3&f04=4\
648 &f05=@(e,f)&f05=@(g,h)\
649 &f06=@(i,j)&f06=@(k,l)\
650 &f07=(a=a,b=1,c=true)&f07=(a=b,b=2,c=false)\
651 &f08=(a=a,b=1,c=true)&f08=(a=b,b=2,c=false)\
652 &f09=@((a=a,b=1,c=true))&f09=@((a=b,b=2,c=false))\
653 &f10=@((a=a,b=1,c=true))&f10=@((a=b,b=2,c=false))\
654 &f11=a&f11=b\
655 &f12=c&f12=d\
656 &f13=1&f13=2\
657 &f14=3&f14=4\
658 &f15=@(e,f)&f15=@(g,h)\
659 &f16=@(i,j)&f16=@(k,l)\
660 &f17=(a=a,b=1,c=true)&f17=(a=b,b=2,c=false)\
661 &f18=(a=a,b=1,c=true)&f18=(a=b,b=2,c=false)\
662 &f19=@((a=a,b=1,c=true))&f19=@((a=b,b=2,c=false))\
663 &f20=@((a=a,b=1,c=true))&f20=@((a=b,b=2,c=false))""";
664
665 assertBean(p2.parse(in, DTOs2.B.class),
666 "f01,f02,f03,f04,f05,f06,f07{#{a,b,c}},f08{#{a,b,c}},f09{#{#{a,b,c}}},f10{#{#{a,b,c}}},f11,f12,f13,f14,f15,f16,f17{#{a,b,c}},f18{#{a,b,c}},f19{#{#{a,b,c}}},f20{#{#{a,b,c}}}",
667 "[a,b],[c,d],[1,2],[3,4],[[e,f],[g,h]],[[i,j],[k,l]],{[{a,1,true},{b,2,false}]},{[{a,1,true},{b,2,false}]},{[{[{a,1,true}]},{[{b,2,false}]}]},{[{[{a,1,true}]},{[{b,2,false}]}]},[a,b],[c,d],[1,2],[3,4],[[e,f],[g,h]],[[i,j],[k,l]],{[{a,1,true},{b,2,false}]},{[{a,1,true},{b,2,false}]},{[{[{a,1,true}]},{[{b,2,false}]}]},{[{[{a,1,true}]},{[{b,2,false}]}]}");
668 }
669
670
671
672
673 @Test void a10_multiPartParametersOnBeansViaAnnotationOnClass() throws Exception {
674 var p2 = UrlEncodingParser.DEFAULT;
675 var in = """
676 f01=a&f01=b\
677 &f02=c&f02=d\
678 &f03=1&f03=2\
679 &f04=3&f04=4\
680 &f05=@(e,f)&f05=@(g,h)\
681 &f06=@(i,j)&f06=@(k,l)\
682 &f07=(a=a,b=1,c=true)&f07=(a=b,b=2,c=false)\
683 &f08=(a=a,b=1,c=true)&f08=(a=b,b=2,c=false)\
684 &f09=@((a=a,b=1,c=true))&f09=@((a=b,b=2,c=false))\
685 &f10=@((a=a,b=1,c=true))&f10=@((a=b,b=2,c=false))\
686 &f11=a&f11=b\
687 &f12=c&f12=d\
688 &f13=1&f13=2\
689 &f14=3&f14=4\
690 &f15=@(e,f)&f15=@(g,h)\
691 &f16=@(i,j)&f16=@(k,l)\
692 &f17=(a=a,b=1,c=true)&f17=(a=b,b=2,c=false)\
693 &f18=(a=a,b=1,c=true)&f18=(a=b,b=2,c=false)\
694 &f19=@((a=a,b=1,c=true))&f19=@((a=b,b=2,c=false))\
695 &f20=@((a=a,b=1,c=true))&f20=@((a=b,b=2,c=false))""";
696
697 assertBean(p2.parse(in, DTOs.C.class),
698 "f01,f02,f03,f04,f05,f06,f07{#{a,b,c}},f08{#{a,b,c}},f09{#{#{a,b,c}}},f10{#{#{a,b,c}}},f11,f12,f13,f14,f15,f16,f17{#{a,b,c}},f18{#{a,b,c}},f19{#{#{a,b,c}}},f20{#{#{a,b,c}}}",
699 "[a,b],[c,d],[1,2],[3,4],[[e,f],[g,h]],[[i,j],[k,l]],{[{a,1,true},{b,2,false}]},{[{a,1,true},{b,2,false}]},{[{[{a,1,true}]},{[{b,2,false}]}]},{[{[{a,1,true}]},{[{b,2,false}]}]},[a,b],[c,d],[1,2],[3,4],[[e,f],[g,h]],[[i,j],[k,l]],{[{a,1,true},{b,2,false}]},{[{a,1,true},{b,2,false}]},{[{[{a,1,true}]},{[{b,2,false}]}]},{[{[{a,1,true}]},{[{b,2,false}]}]}");
700 }
701
702 @Test void a11_multiPartParametersOnBeansViaAnnotationOnClass_usingConfig() throws Exception {
703 var p2 = UrlEncodingParser.DEFAULT.copy().applyAnnotations(DTOs2.Annotations.class).build();
704 var in = """
705 f01=a&f01=b\
706 &f02=c&f02=d\
707 &f03=1&f03=2\
708 &f04=3&f04=4\
709 &f05=@(e,f)&f05=@(g,h)\
710 &f06=@(i,j)&f06=@(k,l)\
711 &f07=(a=a,b=1,c=true)&f07=(a=b,b=2,c=false)\
712 &f08=(a=a,b=1,c=true)&f08=(a=b,b=2,c=false)\
713 &f09=@((a=a,b=1,c=true))&f09=@((a=b,b=2,c=false))\
714 &f10=@((a=a,b=1,c=true))&f10=@((a=b,b=2,c=false))\
715 &f11=a&f11=b\
716 &f12=c&f12=d\
717 &f13=1&f13=2\
718 &f14=3&f14=4\
719 &f15=@(e,f)&f15=@(g,h)\
720 &f16=@(i,j)&f16=@(k,l)\
721 &f17=(a=a,b=1,c=true)&f17=(a=b,b=2,c=false)\
722 &f18=(a=a,b=1,c=true)&f18=(a=b,b=2,c=false)\
723 &f19=@((a=a,b=1,c=true))&f19=@((a=b,b=2,c=false))\
724 &f20=@((a=a,b=1,c=true))&f20=@((a=b,b=2,c=false))""";
725
726 assertBean(p2.parse(in, DTOs2.C.class),
727 "f01,f02,f03,f04,f05,f06,f07{#{a,b,c}},f08{#{a,b,c}},f09{#{#{a,b,c}}},f10{#{#{a,b,c}}},f11,f12,f13,f14,f15,f16,f17{#{a,b,c}},f18{#{a,b,c}},f19{#{#{a,b,c}}},f20{#{#{a,b,c}}}",
728 "[a,b],[c,d],[1,2],[3,4],[[e,f],[g,h]],[[i,j],[k,l]],{[{a,1,true},{b,2,false}]},{[{a,1,true},{b,2,false}]},{[{[{a,1,true}]},{[{b,2,false}]}]},{[{[{a,1,true}]},{[{b,2,false}]}]},[a,b],[c,d],[1,2],[3,4],[[e,f],[g,h]],[[i,j],[k,l]],{[{a,1,true},{b,2,false}]},{[{a,1,true},{b,2,false}]},{[{[{a,1,true}]},{[{b,2,false}]}]},{[{[{a,1,true}]},{[{b,2,false}]}]}");
729 }
730 }