4040import org .example .domain .NestedDataUnwrappedAction ;
4141import org .example .domain .User ;
4242import org .example .domain .UserField ;
43+ import org .example .domain .UserType ;
4344import org .primeframework .mvc .PrimeBaseTest ;
4445import org .primeframework .mvc .parameter .convert .ConverterStateException ;
4546import org .slf4j .Logger ;
@@ -366,7 +367,7 @@ public void maximumParameterCollectionIndex_noLimit() {
366367 }
367368
368369 @ Test
369- public void commaDelimitedStringToArray () {
370+ public void collectionSizeLimit_commaDelimitedString () {
370371 ActionField action = new ActionField ();
371372 action .user = new UserField ();
372373
@@ -390,6 +391,161 @@ public void commaDelimitedStringToArray() {
390391 assertEquals (action .ids [4 ], 5 );
391392 }
392393
394+ @ Test
395+ public void collectionSizeLimit_arrayTypes () {
396+ ActionField action = new ActionField ();
397+ action .user = new UserField ();
398+
399+ // Enum[] — comma-delimited exceeds limit
400+ try {
401+ evaluator .setValue ("userTypes" , action , new String []{"COOL,MELLOW,COOL,MELLOW,COOL,MELLOW,COOL,MELLOW,COOL,MELLOW,COOL" }, null );
402+ fail ("Expected an [InvalidCollectionSizeException] exception." );
403+ } catch (InvalidCollectionSizeException e ) {
404+ assertEquals (e .resultCode , "input" );
405+ }
406+
407+ // Enum[] — within limit produces typed values
408+ evaluator .setValue ("userTypes" , action , new String []{"COOL,MELLOW,COOL" }, null );
409+ assertEquals (action .userTypes .length , 3 );
410+ assertEquals (action .userTypes [0 ], UserType .COOL );
411+ assertEquals (action .userTypes [1 ], UserType .MELLOW );
412+ assertEquals (action .userTypes [2 ], UserType .COOL );
413+
414+ // Locale[] — repeated params exceed limit
415+ try {
416+ evaluator .setValue ("localeArray" , action , new String []{"en" , "fr" , "de" , "es" , "it" , "pt" , "ja" , "ko" , "zh" , "ru" , "ar" }, null );
417+ fail ("Expected an [InvalidCollectionSizeException] exception." );
418+ } catch (InvalidCollectionSizeException e ) {
419+ assertEquals (e .resultCode , "input" );
420+ }
421+
422+ // Locale[] — within limit produces typed values
423+ evaluator .setValue ("localeArray" , action , new String []{"en" , "fr" , "de" }, null );
424+ assertEquals (action .localeArray .length , 3 );
425+ assertEquals (action .localeArray [0 ], Locale .ENGLISH );
426+ assertEquals (action .localeArray [1 ], Locale .FRENCH );
427+ assertEquals (action .localeArray [2 ], Locale .GERMAN );
428+
429+ // UUID[] — repeated params exceed limit
430+ try {
431+ evaluator .setValue ("uuids" , action , new String []{
432+ "00000000-0000-0000-0000-000000000001" , "00000000-0000-0000-0000-000000000002" ,
433+ "00000000-0000-0000-0000-000000000003" , "00000000-0000-0000-0000-000000000004" ,
434+ "00000000-0000-0000-0000-000000000005" , "00000000-0000-0000-0000-000000000006" ,
435+ "00000000-0000-0000-0000-000000000007" , "00000000-0000-0000-0000-000000000008" ,
436+ "00000000-0000-0000-0000-000000000009" , "00000000-0000-0000-0000-000000000010" ,
437+ "00000000-0000-0000-0000-000000000011" }, null );
438+ fail ("Expected an [InvalidCollectionSizeException] exception." );
439+ } catch (InvalidCollectionSizeException e ) {
440+ assertEquals (e .resultCode , "input" );
441+ }
442+
443+ // UUID[] — within limit produces typed values
444+ evaluator .setValue ("uuids" , action , new String []{"00000000-0000-0000-0000-000000000001" , "00000000-0000-0000-0000-000000000002" }, null );
445+ assertEquals (action .uuids .length , 2 );
446+ assertEquals (action .uuids [0 ], java .util .UUID .fromString ("00000000-0000-0000-0000-000000000001" ));
447+ assertEquals (action .uuids [1 ], java .util .UUID .fromString ("00000000-0000-0000-0000-000000000002" ));
448+
449+ // ZoneId[] — repeated params exceed limit
450+ try {
451+ evaluator .setValue ("zoneIds" , action , new String []{
452+ "US/Eastern" , "US/Central" , "US/Mountain" , "US/Pacific" , "Europe/London" ,
453+ "Europe/Paris" , "Europe/Berlin" , "Asia/Tokyo" , "Asia/Shanghai" , "Australia/Sydney" ,
454+ "Africa/Cairo" }, null );
455+ fail ("Expected an [InvalidCollectionSizeException] exception." );
456+ } catch (InvalidCollectionSizeException e ) {
457+ assertEquals (e .resultCode , "input" );
458+ }
459+
460+ // ZoneId[] — within limit produces typed values
461+ evaluator .setValue ("zoneIds" , action , new String []{"US/Eastern" , "US/Pacific" }, null );
462+ assertEquals (action .zoneIds .length , 2 );
463+ assertEquals (action .zoneIds [0 ], java .time .ZoneId .of ("US/Eastern" ));
464+ assertEquals (action .zoneIds [1 ], java .time .ZoneId .of ("US/Pacific" ));
465+
466+ // File[] — repeated params exceed limit
467+ try {
468+ evaluator .setValue ("files" , action , new String []{
469+ "/a" , "/b" , "/c" , "/d" , "/e" , "/f" , "/g" , "/h" , "/i" , "/j" , "/k" }, null );
470+ fail ("Expected an [InvalidCollectionSizeException] exception." );
471+ } catch (InvalidCollectionSizeException e ) {
472+ assertEquals (e .resultCode , "input" );
473+ }
474+
475+ // File[] — within limit produces typed values
476+ evaluator .setValue ("files" , action , new String []{"/tmp/a" , "/tmp/b" }, null );
477+ assertEquals (action .files .length , 2 );
478+ assertEquals (action .files [0 ], new java .io .File ("/tmp/a" ));
479+ assertEquals (action .files [1 ], new java .io .File ("/tmp/b" ));
480+
481+ // LocalDate[] — repeated params exceed limit
482+ try {
483+ evaluator .setValue ("localDates" , action , new String []{
484+ "2026-01-01" , "2026-01-02" , "2026-01-03" , "2026-01-04" , "2026-01-05" ,
485+ "2026-01-06" , "2026-01-07" , "2026-01-08" , "2026-01-09" , "2026-01-10" ,
486+ "2026-01-11" }, null );
487+ fail ("Expected an [InvalidCollectionSizeException] exception." );
488+ } catch (InvalidCollectionSizeException e ) {
489+ assertEquals (e .resultCode , "input" );
490+ }
491+
492+ // LocalDate[] — within limit produces typed values
493+ evaluator .setValue ("localDates" , action , new String []{"2026-01-01" , "2026-06-15" }, Collections .emptyMap ());
494+ assertEquals (action .localDates .length , 2 );
495+ assertEquals (action .localDates [0 ], java .time .LocalDate .of (2026 , 1 , 1 ));
496+ assertEquals (action .localDates [1 ], java .time .LocalDate .of (2026 , 6 , 15 ));
497+ }
498+
499+ @ Test
500+ public void collectionSizeLimit_listTypes () {
501+ ActionField action = new ActionField ();
502+
503+ // List<String> — repeated params exceed limit
504+ try {
505+ evaluator .setValue ("names" , action , new String []{"a" , "b" , "c" , "d" , "e" , "f" , "g" , "h" , "i" , "j" , "k" }, null );
506+ fail ("Expected an [InvalidCollectionSizeException] exception." );
507+ } catch (InvalidCollectionSizeException e ) {
508+ assertEquals (e .resultCode , "input" );
509+ }
510+
511+ // List<String> — within limit produces typed values
512+ evaluator .setValue ("names" , action , new String []{"Alice" , "Bob" , "Charlie" }, null );
513+ assertEquals (action .names .size (), 3 );
514+ assertEquals (action .names .get (0 ), "Alice" );
515+ assertEquals (action .names .get (2 ), "Charlie" );
516+
517+ // List<Locale> — repeated params exceed limit
518+ try {
519+ evaluator .setValue ("locales" , action , new String []{"en" , "fr" , "de" , "es" , "it" , "pt" , "ja" , "ko" , "zh" , "ru" , "ar" }, null );
520+ fail ("Expected an [InvalidCollectionSizeException] exception." );
521+ } catch (InvalidCollectionSizeException e ) {
522+ assertEquals (e .resultCode , "input" );
523+ }
524+
525+ // List<Locale> — within limit produces typed values
526+ evaluator .setValue ("locales" , action , new String []{"en" , "fr" }, null );
527+ assertEquals (action .locales .size (), 2 );
528+ assertEquals (action .locales .get (0 ), Locale .ENGLISH );
529+ assertEquals (action .locales .get (1 ), Locale .FRENCH );
530+
531+ // List<ZoneId> — repeated params exceed limit
532+ try {
533+ evaluator .setValue ("timeZones" , action , new String []{
534+ "US/Eastern" , "US/Central" , "US/Mountain" , "US/Pacific" , "Europe/London" ,
535+ "Europe/Paris" , "Europe/Berlin" , "Asia/Tokyo" , "Asia/Shanghai" , "Australia/Sydney" ,
536+ "Africa/Cairo" }, null );
537+ fail ("Expected an [InvalidCollectionSizeException] exception." );
538+ } catch (InvalidCollectionSizeException e ) {
539+ assertEquals (e .resultCode , "input" );
540+ }
541+
542+ // List<ZoneId> — within limit produces typed values
543+ evaluator .setValue ("timeZones" , action , new String []{"US/Eastern" , "Europe/London" }, null );
544+ assertEquals (action .timeZones .size (), 2 );
545+ assertEquals (action .timeZones .get (0 ), java .time .ZoneId .of ("US/Eastern" ));
546+ assertEquals (action .timeZones .get (1 ), java .time .ZoneId .of ("Europe/London" ));
547+ }
548+
393549 @ Test
394550 public void genericInheritanceImplements () {
395551 GenericBean bean = new GenericBean ();
0 commit comments