Skip to content

Commit 91b7236

Browse files
committed
Document string patterns, collection ordering/uniqueness, and object equivalency
1 parent 029c7b5 commit 91b7236

1 file changed

Lines changed: 89 additions & 0 deletions

File tree

README.md

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,12 @@ SharpAssert uses **MSBuild source rewriting** to automatically transform your as
3737
- **🔍 [Detailed Expression Analysis](#complex-expression-analysis)** - See exactly why your assertions failed
3838
- **🎯 [Exception Testing](#exception-testing)** - `Throws<T>` and `ThrowsAsync<T>` with detailed exception diagnostics
3939
- **🔤 [String Diffs](#string-comparisons)** - Character-level inline diffs for strings (powered by DiffPlex)
40+
- **🔠 [String Pattern Matching](#string-pattern-matching)** - Wildcard patterns and occurrence counting
4041
- **📊 [Collection Comparison](#collection-comparisons)** - First mismatch, missing/extra elements detection
42+
- **📋 [Collection Ordering](#collection-ordering)** - Ascending/descending order validation
43+
- **🔢 [Collection Uniqueness](#collection-uniqueness)** - Duplicate detection with key selectors
4144
- **🔎 [Object Deep Diff](#object-deep-comparison)** - Property-level differences for objects/records (powered by Compare-Net-Objects)
45+
- **🔄 [Object Equivalency](#object-equivalency)** - Structural comparison with property exclusion/inclusion
4246
- **🔗 [LINQ Operations](#linq-operations)** - Enhanced diagnostics for Contains/Any/All operations
4347
- **[Async/Await Support](#asyncawait-support)** - Full support for async assertions with value diagnostics
4448
- **💫 Dynamic Types** - Dynamic objects support (Expando)
@@ -120,6 +124,68 @@ Assert(actual.SequenceEqual(expected));
120124
// Actual: 3
121125
```
122126

127+
### String Pattern Matching
128+
129+
Wildcard patterns with `*` (any sequence) and `?` (single character):
130+
131+
```csharp
132+
using SharpAssert.Features.Strings;
133+
134+
Assert("hello world".Matches("hello *")); // * matches any sequence
135+
Assert("test.txt".Matches("*.txt")); // File extension matching
136+
Assert("test".Matches("t?st")); // ? matches single character
137+
Assert("HELLO".MatchesIgnoringCase("hello")); // Case-insensitive
138+
```
139+
140+
Count substring occurrences:
141+
142+
```csharp
143+
Assert("error at line 5, error at line 10".Contains("error", Occur.Exactly(2)));
144+
Assert("warn, warn, warn".Contains("warn", Occur.AtLeast(2)));
145+
Assert("info".Contains("info", Occur.AtMost(1)));
146+
```
147+
148+
Regex pattern occurrence counting:
149+
150+
```csharp
151+
Assert("test123 and test456".MatchesRegex(@"test\d+", Occur.Exactly(2)));
152+
```
153+
154+
### Collection Ordering
155+
156+
Validate collections are sorted:
157+
158+
```csharp
159+
using SharpAssert.Features.Collections;
160+
161+
var ascending = new[] { 1, 2, 3, 4 };
162+
Assert(ascending.IsInAscendingOrder());
163+
164+
var descending = new[] { 4, 3, 2, 1 };
165+
Assert(descending.IsInDescendingOrder());
166+
167+
// With custom comparer
168+
Assert(names.IsInAscendingOrder(StringComparer.OrdinalIgnoreCase));
169+
```
170+
171+
### Collection Uniqueness
172+
173+
Validate collections contain no duplicates:
174+
175+
```csharp
176+
using SharpAssert.Features.Collections;
177+
178+
var unique = new[] { 1, 2, 3, 4 };
179+
Assert(unique.AllUnique());
180+
181+
// Uniqueness by property
182+
var users = new[] { user1, user2, user3 };
183+
Assert(users.AllUnique(u => u.Email));
184+
185+
// Custom equality comparer
186+
Assert(items.AllUnique(StringComparer.OrdinalIgnoreCase));
187+
```
188+
123189
### Object Deep Comparison
124190

125191
Property-level diffs powered by Compare-Net-Objects:
@@ -135,6 +201,29 @@ Assert(actual == expected);
135201
// City: "NYC" → "LA"
136202
```
137203

204+
### Object Equivalency
205+
206+
Structural comparison with fluent configuration:
207+
208+
```csharp
209+
var actual = new Person { Name = "John", Age = 30, Id = 1 };
210+
var expected = new Person { Name = "John", Age = 30, Id = 2 };
211+
212+
// Basic equivalency check
213+
Assert(actual.IsEquivalentTo(expected));
214+
215+
// Exclude specific properties
216+
Assert(actual.IsEquivalentTo(expected, config => config.Excluding(p => p.Id)));
217+
218+
// Include only specific properties
219+
Assert(actual.IsEquivalentTo(expected, config => config.Including(p => p.Name)));
220+
221+
// Ignore collection ordering
222+
var team1 = new Team { Members = new[] { "Alice", "Bob" } };
223+
var team2 = new Team { Members = new[] { "Bob", "Alice" } };
224+
Assert(team1.IsEquivalentTo(team2, config => config.WithoutStrictOrdering()));
225+
```
226+
138227
### LINQ Operations
139228

140229
Enhanced diagnostics for Contains, Any, All:

0 commit comments

Comments
 (0)