You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Adds HasMinLength(int minLength) assertion that verifies a string's length is >= the specified minimum
Adds HasMaxLength(int maxLength) assertion that verifies a string's length is <= the specified maximum
Adds HasLengthBetween(int min, int max) assertion that verifies a string's length is within an inclusive range
All three follow the existing assertion patterns (condition classes in StringAssertions.cs, extension methods in AssertionExtensions.cs) and support CallerArgumentExpression for readable error messages.
The implementation follows the established patterns in StringAssertions.cs correctly — constructor, CheckAsync, GetExpectation, and the CallerArgumentExpression extension methods all match the existing convention for parameterized string assertions. The null/exception guard ordering is consistent with the rest of the file.
Two issues found:
1. Missing Public API snapshot updates (CLAUDE.md violation)
Severity: Required
TUnit.PublicAPI contains snapshot tests that verify the entire public surface area of the TUnit.Assertions assembly. The PR adds six new public members, but none of the four .verified.txt files were updated:
The analogous existing type StringLengthAssertion and its HasLength extension method are already captured in those snapshots. Without updating these files, the Public API tests will fail. Per CLAUDE.md Critical Rule 2:
"Changes to source generator output or public APIs require running snapshot tests. Commit .verified.txt files. NEVER commit .received.txt."
Fix: Run the TUnit.PublicAPI test suite and accept the generated .received.txt snapshots:
# From the TUnit.PublicAPI directory
dotnet test# Then accept the output:forfin*.received.txt;do mv "$f""${f%.received.txt}.verified.txt";done
git add *.verified.txt
2. HasLengthBetween silently produces an unsatisfiable assertion when minLength > maxLength
Severity: Design concern
When arguments are accidentally swapped — e.g., HasLengthBetween(10, 3) — the condition value.Length >= 10 && value.Length <= 3 is impossible to satisfy, so the assertion will silently always fail. The failure message will read something like "found length 5", giving the developer no indication that the real problem is the inverted bounds.
This is a genuine usability trap: the arguments have the same type (int, int), swapping them is easy, and the resulting failure message is actively misleading.
Every comparable assertion library (FluentAssertions, Shouldly, NUnit) throws ArgumentOutOfRangeException eagerly at construction time rather than letting the assertion silently become unsatisfiable.
Suggested fix — add a guard in HasLengthBetween (the extension method is the right place since it's the public entry point):
publicstaticStringLengthBetweenAssertionHasLengthBetween(thisIAssertionSource<string>source,intminLength,intmaxLength,[CallerArgumentExpression(nameof(minLength))]string?minExpression=null,[CallerArgumentExpression(nameof(maxLength))]string?maxExpression=null){if(minLength>maxLength)thrownewArgumentOutOfRangeException(nameof(minLength),$"minLength ({minLength}) must be less than or equal to maxLength ({maxLength}).");source.Context.ExpressionBuilder.Append($".HasLengthBetween({minExpression}, {maxExpression})");returnnewStringLengthBetweenAssertion(source.Context,minLength,maxLength);}
Reviewed by Claude — checked for bugs and CLAUDE.md compliance.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
HasMinLength(int minLength)assertion that verifies a string's length is >= the specified minimumHasMaxLength(int maxLength)assertion that verifies a string's length is <= the specified maximumHasLengthBetween(int min, int max)assertion that verifies a string's length is within an inclusive rangeAll three follow the existing assertion patterns (condition classes in
StringAssertions.cs, extension methods inAssertionExtensions.cs) and supportCallerArgumentExpressionfor readable error messages.Closes#4868
Test plan
HasMinLengthpasses for strings at or above the minimum lengthHasMinLengthfails for strings below the minimum lengthHasMaxLengthpasses for strings at or below the maximum lengthHasMaxLengthfails for strings above the maximum lengthHasLengthBetweenpasses for strings within the inclusive rangeHasLengthBetweenfails for strings outside the rangeAssert.That(str).HasMinLength(3).And.HasMaxLength(10))