@ -1,5 +1,5 @@
@@ -1,5 +1,5 @@
/ *
* Copyright 2012 - 2023 the original author or authors .
* Copyright 2012 - 2025 the original author or authors .
*
* Licensed under the Apache License , Version 2 . 0 ( the "License" ) ;
* you may not use this file except in compliance with the License .
@ -123,6 +123,41 @@ class CollectionBinderTests {
@@ -123,6 +123,41 @@ class CollectionBinderTests {
} ) ;
}
@Test
void bindToCollectionWhenNonKnownIndexedChildNotBoundThrowsException ( ) {
// gh-45994
MockConfigurationPropertySource source = new MockConfigurationPropertySource ( ) ;
source . put ( "foo[0].first" , "Spring" ) ;
source . put ( "foo[0].last" , "Boot" ) ;
source . put ( "foo[1].missing" , "bad" ) ;
this . sources . add ( source ) ;
assertThatExceptionOfType ( BindException . class )
. isThrownBy ( ( ) - > this . binder . bind ( "foo" , Bindable . listOf ( Name . class ) ) )
. satisfies ( ( ex ) - > {
Set < ConfigurationProperty > unbound = ( ( UnboundConfigurationPropertiesException ) ex . getCause ( ) )
. getUnboundProperties ( ) ;
assertThat ( unbound ) . hasSize ( 1 ) ;
ConfigurationProperty property = unbound . iterator ( ) . next ( ) ;
assertThat ( property . getName ( ) ) . hasToString ( "foo[1].missing" ) ;
assertThat ( property . getValue ( ) ) . isEqualTo ( "bad" ) ;
} ) ;
}
@Test
void bindToNestedCollectionWhenNonKnownIndexed ( ) {
// gh-46039
MockConfigurationPropertySource source = new MockConfigurationPropertySource ( ) ;
source . put ( "foo[0].items[0]" , "a" ) ;
source . put ( "foo[0].items[1]" , "b" ) ;
source . put ( "foo[0].string" , "test" ) ;
this . sources . add ( source ) ;
List < ExampleCollectionBean > list = this . binder . bind ( "foo" , Bindable . listOf ( ExampleCollectionBean . class ) ) . get ( ) ;
assertThat ( list ) . hasSize ( 1 ) ;
ExampleCollectionBean bean = list . get ( 0 ) ;
assertThat ( bean . getItems ( ) ) . containsExactly ( "a" , "b" , "d" ) ;
assertThat ( bean . getString ( ) ) . isEqualTo ( "test" ) ;
}
@Test
void bindToNonScalarCollectionWhenNonSequentialShouldThrowException ( ) {
MockConfigurationPropertySource source = new MockConfigurationPropertySource ( ) ;
@ -436,6 +471,8 @@ class CollectionBinderTests {
@@ -436,6 +471,8 @@ class CollectionBinderTests {
private Set < String > itemsSet = new LinkedHashSet < > ( ) ;
private String string ;
List < String > getItems ( ) {
return this . items ;
}
@ -452,6 +489,14 @@ class CollectionBinderTests {
@@ -452,6 +489,14 @@ class CollectionBinderTests {
this . itemsSet = itemsSet ;
}
String getString ( ) {
return this . string ;
}
void setString ( String string ) {
this . string = string ;
}
}
static class ExampleCustomNoDefaultConstructorBean {
@ -562,4 +607,8 @@ class CollectionBinderTests {
@@ -562,4 +607,8 @@ class CollectionBinderTests {
}
record Name ( String first , String last ) {
}
}