Skip to content

Commit 6ab1c3e

Browse files
authored
Merge pull request #24 from 21johnh21/HAWL/SWE-43211-add-function-for-deep-equality-checking
SWE-43211 add function for deep equality checking
2 parents 73799c7 + 024b30e commit 6ab1c3e

File tree

5 files changed

+1024
-6
lines changed

5 files changed

+1024
-6
lines changed

AI_AGENT_TESTING_GUIDE.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ The `$t.assert` object provides these methods:
2222

2323
```4d
2424
$t.assert.areEqual($t; expected; actual; "message")
25+
$t.assert.areDeepEqual($t; expected; actual; "message"; maxDepth) // Deep equality for objects/collections (maxDepth optional, default: 10)
2526
$t.assert.isTrue($t; condition; "message")
2627
$t.assert.isFalse($t; condition; "message")
2728
$t.assert.isNull($t; value; "message")

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@ Function test_user_creation($t : cs.Testing)
2525
2626
$t.assert.isNotNull($t; $user.name; "User should have a name")
2727
$t.assert.areEqual($t; "John"; $user.name; "User name should be correct")
28+
29+
// Compare complex objects with deep equality
30+
var $expected : Object
31+
$expected:=New object("name"; "John"; "email"; "john@example.com")
32+
$t.assert.areDeepEqual($t; $expected; $user; "User object should match expected structure")
2833
2934
// #tags: integration, database
3035
Function test_user_persistence($t : cs.Testing)

docs/guide.md

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ The framework includes built-in assertion methods accessible through `$t.assert`
134134

135135
### Basic Assertions
136136
- `$t.assert.areEqual($t; $expected; $actual; $message)` - Values must be equal
137+
- `$t.assert.areDeepEqual($t; $expected; $actual; $message; $maxDepth)` - Deep equality comparison for objects and collections (optional `$maxDepth`, default: 10)
137138
- `$t.assert.isTrue($t; $value; $message)` - Value must be true
138139
- `$t.assert.isFalse($t; $value; $message)` - Value must be false
139140
- `$t.assert.isNull($t; $value; $message)` - Value must be null
@@ -157,6 +158,68 @@ Function test_calculations($t : cs.Testing.Testing)
157158
$t.assert.isNotNull($t; $result; "Function should return a result")
158159
```
159160

161+
### Deep Equality Assertions
162+
163+
The `areDeepEqual` function performs recursive comparison of nested objects and collections, providing detailed difference reporting when values don't match. This is especially useful for testing complex data structures.
164+
165+
**Basic Usage:**
166+
```4d
167+
Function test_object_comparison($t : cs.Testing.Testing)
168+
var $expected; $actual : Object
169+
$expected:={name: "John"; age: 30; address: {city: "New York"; zip: "10001"}}
170+
$actual:={name: "John"; age: 30; address: {city: "New York"; zip: "10001"}}
171+
172+
// Deep comparison of nested structures
173+
$t.assert.areDeepEqual($t; $expected; $actual; "Objects should match")
174+
```
175+
176+
**With Custom Max Depth:**
177+
```4d
178+
Function test_deep_nesting($t : cs.Testing.Testing)
179+
var $expected; $actual : Object
180+
// ... very deeply nested objects ...
181+
182+
// Increase max depth for very deep structures (default is 10)
183+
$t.assert.areDeepEqual($t; $expected; $actual; "Deep objects should match"; 20)
184+
```
185+
186+
**Accessing Differences Programmatically:**
187+
When a deep equality assertion fails, the framework stores detailed difference information in `$t.lastDeepEqualDifferences`:
188+
189+
```4d
190+
Function test_with_difference_analysis($t : cs.Testing.Testing)
191+
var $expected; $actual : Object
192+
$expected:={name: "John"; age: 30}
193+
$actual:={name: "John"; age: 25}
194+
195+
$t.assert.areDeepEqual($t; $expected; $actual; "Objects should match")
196+
197+
// If assertion fails, analyze differences
198+
If ($t.failed)
199+
var $diff : Object
200+
For each ($diff; $t.lastDeepEqualDifferences)
201+
$t.log("Difference at "+$diff.path+": "+$diff.type)
202+
End for each
203+
End if
204+
```
205+
206+
**Features:**
207+
- **Recursive Comparison**: Compares nested objects and collections at all levels
208+
- **Detailed Reporting**: Provides path-based difference reporting (e.g., `user.address.city`)
209+
- **Circular Reference Protection**: Max depth limit prevents infinite loops (default: 10 levels)
210+
- **Type Safety**: Detects type mismatches between expected and actual values
211+
- **Missing/Extra Keys**: Reports missing keys in actual object and extra keys not in expected
212+
- **Collection Support**: Handles collections with different lengths and element differences
213+
- **Programmatic Access**: Differences available via `$t.lastDeepEqualDifferences` collection
214+
215+
**Difference Types:**
216+
- `different_value` - Values differ at a specific path
217+
- `missing_key` - Key exists in expected but not in actual
218+
- `extra_key` - Key exists in actual but not in expected
219+
- `different_type` - Types differ between expected and actual
220+
- `different_length` - Collections have different lengths
221+
- `max_depth_exceeded` - Recursion depth limit reached (increase `$maxDepth` if needed)
222+
160223
## Output Formats
161224

162225
The framework provides terse output by default for cleaner results, with verbose mode available when more detail is needed.

0 commit comments

Comments
 (0)