@@ -48,6 +48,11 @@ public class ComplexType
4848
4949 public NestedType ObjectProperty { get; set; } = new NestedType();
5050
51+ [SkipValidation]
52+ public List<NestedType> SkippedListOfNestedTypes { get; set; } = [];
53+
54+ public List<NestedType> ListOfNestedTypes { get; set; } = [];
55+
5156 [SkipValidation]
5257 public NonSkippedBaseType SkippedBaseTypeProperty { get; set; } = new NonSkippedBaseType();
5358
@@ -100,13 +105,32 @@ await VerifyValidatableType(compilation, "ComplexType", async (validationOptions
100105 {
101106 Assert . True ( validationOptions . TryGetValidatableTypeInfo ( type , out var validatableTypeInfo ) ) ;
102107
103- await InvalidNestedIntegerWithRangeProducesError ( validatableTypeInfo ) ;
104- await InvalidSkippedNestedIntegerWithRangeDoesNotProduceProduceError ( validatableTypeInfo ) ;
105- await InvalidSkippedIntegerWithRangeDoesNotProduceError ( validatableTypeInfo ) ;
106- await InvalidSubTypeNestedIntegersWithRangeProduceErrors ( validatableTypeInfo ) ;
107- await InvalidAlwaysSkippedTypeDoesNotProduceError ( validatableTypeInfo ) ;
108+ await InvalidSkippedInteger_DoesNotProduceError ( validatableTypeInfo ) ;
109+ await InvalidNestedInteger_ProducesError ( validatableTypeInfo ) ;
110+ await InvalidSkippedNestedInteger_DoesNotProduceError ( validatableTypeInfo ) ;
111+ await InvalidList_ProducesError ( validatableTypeInfo ) ;
112+ await InvalidSkippedList_DoesNotProduceError ( validatableTypeInfo ) ;
113+ await InvalidSubTypeNestedIntegers_ProduceErrors ( validatableTypeInfo ) ;
114+ await InvalidAlwaysSkippedType_DoesNotProduceError ( validatableTypeInfo ) ;
108115
109- async Task InvalidNestedIntegerWithRangeProducesError ( IValidatableInfo validatableInfo )
116+ async Task InvalidSkippedInteger_DoesNotProduceError ( IValidatableInfo validatableInfo )
117+ {
118+ var instance = Activator . CreateInstance ( type ) ;
119+ var intProperty = type . GetProperty ( "IntegerWithRange" ) ;
120+ intProperty ? . SetValue ( instance , 5 ) ; // Set invalid value
121+
122+ var context = new ValidateContext
123+ {
124+ ValidationOptions = validationOptions ,
125+ ValidationContext = new ValidationContext ( instance )
126+ } ;
127+
128+ await validatableTypeInfo . ValidateAsync ( instance , context , CancellationToken . None ) ;
129+
130+ Assert . Null ( context . ValidationErrors ) ;
131+ }
132+
133+ async Task InvalidNestedInteger_ProducesError ( IValidatableInfo validatableInfo )
110134 {
111135 var instance = Activator . CreateInstance ( type ) ;
112136 var objectPropertyInstance = type . GetProperty ( "ObjectProperty" ) . GetValue ( instance ) ;
@@ -128,7 +152,7 @@ async Task InvalidNestedIntegerWithRangeProducesError(IValidatableInfo validatab
128152 } ) ;
129153 }
130154
131- async Task InvalidSkippedNestedIntegerWithRangeDoesNotProduceProduceError ( IValidatableInfo validatableInfo )
155+ async Task InvalidSkippedNestedInteger_DoesNotProduceError ( IValidatableInfo validatableInfo )
132156 {
133157 var instance = Activator . CreateInstance ( type ) ;
134158 var objectPropertyInstance = type . GetProperty ( "SkippedObjectProperty" ) . GetValue ( instance ) ;
@@ -146,24 +170,59 @@ async Task InvalidSkippedNestedIntegerWithRangeDoesNotProduceProduceError(IValid
146170 Assert . Null ( context . ValidationErrors ) ;
147171 }
148172
149- async Task InvalidSkippedIntegerWithRangeDoesNotProduceError ( IValidatableInfo validatableInfo )
173+ async Task InvalidList_ProducesError ( IValidatableInfo validatableInfo )
150174 {
151- var instance = Activator . CreateInstance ( type ) ;
152- var intProperty = type . GetProperty ( "IntegerWithRange" ) ;
153- intProperty ? . SetValue ( instance , 5 ) ; // Set invalid value
175+ var rootInstance = Activator . CreateInstance ( type ) ;
176+ var listInstance = Activator . CreateInstance ( typeof ( List < > ) . MakeGenericType ( type . Assembly . GetType ( "NestedType" ) ! ) ) ;
177+
178+ // Create invalid item
179+ var nestedTypeInstance = Activator . CreateInstance ( type . Assembly . GetType ( "NestedType" ) ! ) ;
180+ nestedTypeInstance . GetType ( ) . GetProperty ( "IntegerWithRange" ) ? . SetValue ( nestedTypeInstance , 5 ) ;
181+
182+ // Add to list
183+ listInstance . GetType ( ) . GetMethod ( "Add" ) ? . Invoke ( listInstance , [ nestedTypeInstance ] ) ;
154184
185+ type . GetProperty ( "ListOfNestedTypes" ) ? . SetValue ( rootInstance , listInstance ) ;
155186 var context = new ValidateContext
156187 {
157188 ValidationOptions = validationOptions ,
158- ValidationContext = new ValidationContext ( instance )
189+ ValidationContext = new ValidationContext ( rootInstance )
159190 } ;
160191
161- await validatableTypeInfo . ValidateAsync ( instance , context , CancellationToken . None ) ;
192+ await validatableTypeInfo . ValidateAsync ( rootInstance , context , CancellationToken . None ) ;
193+
194+ Assert . Collection ( context . ValidationErrors , kvp =>
195+ {
196+ Assert . Equal ( "ListOfNestedTypes[0].IntegerWithRange" , kvp . Key ) ;
197+ Assert . Equal ( "The field IntegerWithRange must be between 10 and 100." , kvp . Value . Single ( ) ) ;
198+ } ) ;
199+ }
200+
201+ async Task InvalidSkippedList_DoesNotProduceError ( IValidatableInfo validatableInfo )
202+ {
203+ var rootInstance = Activator . CreateInstance ( type ) ;
204+ var listInstance = Activator . CreateInstance ( typeof ( List < > ) . MakeGenericType ( type . Assembly . GetType ( "NestedType" ) ! ) ) ;
205+
206+ // Create invalid item
207+ var nestedTypeInstance = Activator . CreateInstance ( type . Assembly . GetType ( "NestedType" ) ! ) ;
208+ nestedTypeInstance . GetType ( ) . GetProperty ( "IntegerWithRange" ) ? . SetValue ( nestedTypeInstance , 5 ) ;
209+
210+ // Add to list
211+ listInstance . GetType ( ) . GetMethod ( "Add" ) ? . Invoke ( listInstance , [ nestedTypeInstance ] ) ;
212+
213+ type . GetProperty ( "SkippedListOfNestedTypes" ) ? . SetValue ( rootInstance , listInstance ) ;
214+ var context = new ValidateContext
215+ {
216+ ValidationOptions = validationOptions ,
217+ ValidationContext = new ValidationContext ( rootInstance )
218+ } ;
219+
220+ await validatableTypeInfo . ValidateAsync ( rootInstance , context , CancellationToken . None ) ;
162221
163222 Assert . Null ( context . ValidationErrors ) ;
164223 }
165224
166- async Task InvalidSubTypeNestedIntegersWithRangeProduceErrors ( IValidatableInfo validatableInfo )
225+ async Task InvalidSubTypeNestedIntegers_ProduceErrors ( IValidatableInfo validatableInfo )
167226 {
168227 var instance = Activator . CreateInstance ( type ) ;
169228 var objectPropertyInstance = type . GetProperty ( "NonSkippedSubTypeProperty" ) . GetValue ( instance ) ;
@@ -194,7 +253,7 @@ async Task InvalidSubTypeNestedIntegersWithRangeProduceErrors(IValidatableInfo v
194253 } ) ;
195254 }
196255
197- async Task InvalidAlwaysSkippedTypeDoesNotProduceError ( IValidatableInfo validatableInfo )
256+ async Task InvalidAlwaysSkippedType_DoesNotProduceError ( IValidatableInfo validatableInfo )
198257 {
199258 var instance = Activator . CreateInstance ( type ) ;
200259 var objectPropertyInstance = type . GetProperty ( "AlwaysSkippedProperty" ) . GetValue ( instance ) ;
0 commit comments