Skip to content

v1.2.0

Choose a tag to compare

@yevhen yevhen released this 15 Dec 07:45
· 35 commits to main since this release

What's New

Custom Expectations

Create reusable, composable expectations by inheriting from Expectation:

sealed class IsEvenExpectation(int value) : Expectation
{
    public override EvaluationResult Evaluate(ExpectationContext context) =>
        value % 2 == 0
            ? ExpectationResults.Pass(context.Expression)
            : ExpectationResults.Fail(context.Expression, $"Expected even, got {value}");
}

// Use with static factories or extension methods
Assert(IsEven(4));
Assert(4.IsEven() & !5.IsEven());

String Pattern Matching

Wildcard patterns with * (any sequence) and ? (single character):

using SharpAssert.Features.Strings;

Assert("hello world".Matches("hello *"));
Assert("test.txt".Matches("*.txt"));
Assert("HELLO".MatchesIgnoringCase("hello"));

Occurrence counting for substrings and regex:

Assert("error, error".Contains("error", Occur.Exactly(2)));
Assert("warn, warn".Contains("warn", Occur.AtLeast(1)));
Assert("test123 test456".MatchesRegex(@"test\d+", Occur.Exactly(2)));

Collection Ordering

Validate collections are sorted:

using SharpAssert.Features.Collections;

Assert(numbers.IsInAscendingOrder());
Assert(scores.IsInDescendingOrder());
Assert(names.IsInAscendingOrder(StringComparer.OrdinalIgnoreCase));

Collection Uniqueness

Validate collections contain no duplicates:

Assert(items.AllUnique());
Assert(users.AllUnique(u => u.Email));  // By key

Object Equivalency

Structural comparison with fluent configuration:

Assert(actual.IsEquivalentTo(expected));
Assert(actual.IsEquivalentTo(expected, c => c.Excluding(p => p.Id)));
Assert(actual.IsEquivalentTo(expected, c => c.Including(p => p.Name)));
Assert(team1.IsEquivalentTo(team2, c => c.WithoutStrictOrdering()));

Improvements

  • Programmatic access to results - SharpAssertionException.Result property provides structured access to assertion evaluation results
  • Hardened expression evaluation - Better fallbacks and sentinels for edge cases in expression compilation
  • Improved expression display - Fixed display for complex nested binary operations and nullable unwrapping

Internal

  • Feature-based code organization
  • Decoupled evaluation from formatting
  • Structured comparison results with rendering pushed into record types
  • Simplified rendering without visitors

Full Changelog: v1.1.0...v1.2.0