@@ -230,6 +230,117 @@ protected override Task<AssertionResult> CheckAsync(EvaluationMetadata<TCollecti
230230 protected override string GetExpectation ( ) => $ "to have count { _expectedCount } ";
231231}
232232
233+ /// <summary>
234+ /// Asserts that a collection has at least the specified minimum number of items (count >= minCount).
235+ /// Delegates to CollectionChecks for the actual logic.
236+ /// </summary>
237+ public class CollectionHasAtLeastAssertion < TCollection , TItem > : Sources . CollectionAssertionBase < TCollection , TItem >
238+ where TCollection : IEnumerable < TItem >
239+ {
240+ private readonly int _minCount ;
241+
242+ public CollectionHasAtLeastAssertion (
243+ AssertionContext < TCollection > context ,
244+ int minCount )
245+ : base ( context )
246+ {
247+ _minCount = minCount ;
248+ }
249+
250+ protected override Task < AssertionResult > CheckAsync ( EvaluationMetadata < TCollection > metadata )
251+ {
252+ if ( metadata . Exception != null )
253+ {
254+ return Task . FromResult ( AssertionResult . Failed ( $ "threw { metadata . Exception . GetType ( ) . Name } ") ) ;
255+ }
256+
257+ if ( metadata . Value == null )
258+ {
259+ return Task . FromResult ( AssertionResult . Failed ( "collection was null" ) ) ;
260+ }
261+
262+ var adapter = new EnumerableAdapter < TItem > ( metadata . Value ) ;
263+ return Task . FromResult ( CollectionChecks . CheckHasAtLeast ( adapter , _minCount ) ) ;
264+ }
265+
266+ protected override string GetExpectation ( ) => $ "to have at least { _minCount } item(s)";
267+ }
268+
269+ /// <summary>
270+ /// Asserts that a collection has at most the specified maximum number of items (count <= maxCount).
271+ /// Delegates to CollectionChecks for the actual logic.
272+ /// </summary>
273+ public class CollectionHasAtMostAssertion < TCollection , TItem > : Sources . CollectionAssertionBase < TCollection , TItem >
274+ where TCollection : IEnumerable < TItem >
275+ {
276+ private readonly int _maxCount ;
277+
278+ public CollectionHasAtMostAssertion (
279+ AssertionContext < TCollection > context ,
280+ int maxCount )
281+ : base ( context )
282+ {
283+ _maxCount = maxCount ;
284+ }
285+
286+ protected override Task < AssertionResult > CheckAsync ( EvaluationMetadata < TCollection > metadata )
287+ {
288+ if ( metadata . Exception != null )
289+ {
290+ return Task . FromResult ( AssertionResult . Failed ( $ "threw { metadata . Exception . GetType ( ) . Name } ") ) ;
291+ }
292+
293+ if ( metadata . Value == null )
294+ {
295+ return Task . FromResult ( AssertionResult . Failed ( "collection was null" ) ) ;
296+ }
297+
298+ var adapter = new EnumerableAdapter < TItem > ( metadata . Value ) ;
299+ return Task . FromResult ( CollectionChecks . CheckHasAtMost ( adapter , _maxCount ) ) ;
300+ }
301+
302+ protected override string GetExpectation ( ) => $ "to have at most { _maxCount } item(s)";
303+ }
304+
305+ /// <summary>
306+ /// Asserts that a collection count is between the specified minimum and maximum (inclusive).
307+ /// Delegates to CollectionChecks for the actual logic.
308+ /// </summary>
309+ public class CollectionHasCountBetweenAssertion < TCollection , TItem > : Sources . CollectionAssertionBase < TCollection , TItem >
310+ where TCollection : IEnumerable < TItem >
311+ {
312+ private readonly int _min ;
313+ private readonly int _max ;
314+
315+ public CollectionHasCountBetweenAssertion (
316+ AssertionContext < TCollection > context ,
317+ int min ,
318+ int max )
319+ : base ( context )
320+ {
321+ _min = min ;
322+ _max = max ;
323+ }
324+
325+ protected override Task < AssertionResult > CheckAsync ( EvaluationMetadata < TCollection > metadata )
326+ {
327+ if ( metadata . Exception != null )
328+ {
329+ return Task . FromResult ( AssertionResult . Failed ( $ "threw { metadata . Exception . GetType ( ) . Name } ") ) ;
330+ }
331+
332+ if ( metadata . Value == null )
333+ {
334+ return Task . FromResult ( AssertionResult . Failed ( "collection was null" ) ) ;
335+ }
336+
337+ var adapter = new EnumerableAdapter < TItem > ( metadata . Value ) ;
338+ return Task . FromResult ( CollectionChecks . CheckHasCountBetween ( adapter , _min , _max ) ) ;
339+ }
340+
341+ protected override string GetExpectation ( ) => $ "to have count between { _min } and { _max } ";
342+ }
343+
233344/// <summary>
234345/// Helper for All().Satisfy() pattern - allows custom assertions on all collection items.
235346/// </summary>
0 commit comments