-
-
Notifications
You must be signed in to change notification settings - Fork 105
fix: Collection.Count(lambda) returns a collection-type assertion builder for further collection assertion chaining #4043
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…lder for further collection assertion chaining
Pull Request ReviewSummaryThis PR successfully fixes issue #4040 by redesigning the Count() assertion API to return collection-aware types that preserve the collection context for proper chaining. Strengths
Critical IssueSilent Exception Swallowing (Lines 198-206, 303-311 in CollectionCountSource.cs) Bare catch blocks swallow ALL exceptions including critical ones like OutOfMemoryException, StackOverflowException, ThreadAbortException, and OperationCanceledException. Must fix: Use specific exception handling or rethrow critical exceptions. Should Fix
Minor Issues
ConclusionThis is a well-designed fix with clean architecture and comprehensive tests. With the critical exception handling issue fixed, this PR will be ready to merge. Recommendation: Request changes to address bare catch blocks, then approve. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR fixes issue #4040 by refactoring the Count() assertion methods to preserve the collection type, enabling fluent chaining of additional collection assertions. Previously, count assertions returned an int-focused assertion builder that broke the collection context. Now, count assertions return collection-aware builders that allow patterns like .Count().IsEqualTo(5).And.Contains(3).
Key changes:
- Replaced
CollectionCountValueAssertion<TCollection, TItem>(which extendedValueAssertion<int>) withCollectionCountSource<TCollection, TItem>(returns collection-aware assertions) - Introduced
CollectionCountEqualsAssertion<TCollection, TItem>that inherits fromCollectionAssertionBaseto preserve collection type - Removed deprecated
Count(Func<TItem, bool> predicate)method (was marked obsolete) - Added
CollectionCountWithInlineAssertionAssertion<TCollection, TItem>for inline count assertions likeCount(c => c.IsEqualTo(5))
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| TUnit.Assertions/Sources/CollectionAssertionBase.cs | Updated Count() methods to return collection-preserving assertion types; removed obsolete predicate-based Count() method |
| TUnit.Assertions/Conditions/CollectionCountValueAssertion.cs | Deleted - replaced with new architecture that preserves collection type |
| TUnit.Assertions/Conditions/CollectionCountSource.cs | New file implementing collection-preserving count assertions with various comparison operators (IsEqualTo, IsGreaterThan, etc.) |
| TUnit.Assertions.Tests/CollectionAssertionTests.cs | Added comprehensive tests for collection chaining after count assertions; removed obsolete predicate-based count test |
| docs/docs/assertions/collections.md | Added documentation section demonstrating count assertion chaining with examples |
| TUnit.PublicAPI/Tests.Assertions_Library_Has_No_API_Changes.*.verified.txt | Updated API snapshots across all .NET versions (4.7, 8.0, 9.0, 10.0) reflecting the breaking API changes |
| catch | ||
| { | ||
| // Item did not satisfy the assertion, don't count it | ||
| } |
Copilot
AI
Dec 10, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The bare catch block swallows all exceptions without distinguishing between assertion failures and other errors (e.g., NullReferenceException, InvalidOperationException). This makes debugging difficult when unexpected errors occur during item evaluation.
Consider catching specific exception types like AssertionException, or at minimum, add logging or re-throw unexpected exceptions. This pattern is used elsewhere in the codebase (e.g., CollectionAssertions.cs lines 675, 742) where catch blocks catch Exception explicitly and provide error context.
| catch | ||
| { | ||
| // Count assertion failed | ||
| return AssertionResult.Failed($"count was {_actualCount}"); | ||
| } |
Copilot
AI
Dec 10, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The bare catch block swallows all exceptions without distinguishing between assertion failures and other errors. This makes debugging difficult when unexpected errors occur during count assertion evaluation.
Consider catching specific exception types like AssertionException, or at minimum, add logging or re-throw unexpected exceptions to provide better diagnostics when genuine errors occur.
| // Test with lambda-wrapped collection | ||
| await Assert.That(() => items).Count(item => item.IsGreaterThan(2)).IsEqualTo(3); | ||
| } | ||
|
|
Copilot
AI
Dec 10, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new collection chaining functionality introduced in this PR lacks test coverage for failure scenarios. While the happy path tests verify that chaining works when assertions pass, there are no tests verifying:
- Error messages when count assertions fail (e.g., expected 5 but found 3)
- Chained assertions after a failed count assertion
- Null collection handling with chained assertions
- Exception handling during item assertion evaluation in Count(item => ...)
Consider adding negative test cases like:
- Count assertion fails with descriptive error message
- Count with item filter fails and shows correct count
- Chained assertion after count shows proper error context
Fixes #4040