Pure snapshot capture, comparison, and serialization for validation testing.
This namespace provides data-only operations for snapshot testing:
All functions are pure with no I/O. File operations belong in test helpers.
Example usage:
;; Capture a validation result (def snap (capture {:status :failure :errors [...]} {:schema-version "1.0" :seed 42 :meta {:test "user-email"}}))
;; Serialize deterministically (stable-serialize snap) ;; => "{:meta {:schema-version "1.0" :seed 42 ...} :result {...}}"_in
;; Compute file path (path-for {:ns 'boundary.user.validation-test :test 'email-required :case 'missing}) ;; => "test/snapshots/validation/boundary/user/validation_test/email_required__missing.edn"
;; Compare snapshots (compare-snapshots expected actual) ;; => {:equal? true :diff [nil nil nil]}
Snapshot format: {:meta {:schema-version "1.0" :seed 42 :test-ns 'boundary.user.validation-test :test-name 'email-required :case-name 'missing :captured-at "2025-01-04"} :result <validation-result>}
Pure snapshot capture, comparison, and serialization for validation testing.
This namespace provides data-only operations for snapshot testing:
- capture: Create snapshot maps with metadata
- stable-serialize: Deterministic EDN serialization
- path-for: Compute snapshot file paths from test metadata
- compare-snapshots: Deep comparison with detailed diffs
All functions are pure with no I/O. File operations belong in test helpers.
Example usage:
;; Capture a validation result
(def snap (capture {:status :failure :errors [...]}
{:schema-version "1.0" :seed 42 :meta {:test "user-email"}}))
;; Serialize deterministically
(stable-serialize snap)
;; => "{:meta {:schema-version \"1.0\" :seed 42 ...} :result {...}}"_in
;; Compute file path
(path-for {:ns 'boundary.user.validation-test :test 'email-required :case 'missing})
;; => "test/snapshots/validation/boundary/user/validation_test/email_required__missing.edn"
;; Compare snapshots
(compare-snapshots expected actual)
;; => {:equal? true :diff [nil nil nil]}
Snapshot format:
{:meta {:schema-version "1.0"
:seed 42
:test-ns 'boundary.user.validation-test
:test-name 'email-required
:case-name 'missing
:captured-at "2025-01-04"}
:result <validation-result>}(capture result opts)Capture a validation result as a snapshot map with metadata.
Args: result - The validation result to capture (typically a map with :status, :errors, etc.) opts - Map of metadata options: :schema-version - Version string for snapshot format (default "1.0") :seed - Random seed used for generation (for reproducibility) :meta - Additional metadata (test name, case name, etc.)
Returns: Snapshot map with :meta and :result keys.
Example: (capture {:status :failure :errors [{:code :user.email/required}]} {:schema-version "1.0" :seed 42 :meta {:test "email-validation"}}) ;; => {:meta {:schema-version "1.0" :seed 42 :test "email-validation"} ;; :result {:status :failure :errors [{:code :user.email/required}]}}
Capture a validation result as a snapshot map with metadata.
Args:
result - The validation result to capture (typically a map with :status, :errors, etc.)
opts - Map of metadata options:
:schema-version - Version string for snapshot format (default "1.0")
:seed - Random seed used for generation (for reproducibility)
:meta - Additional metadata (test name, case name, etc.)
Returns:
Snapshot map with :meta and :result keys.
Example:
(capture {:status :failure :errors [{:code :user.email/required}]}
{:schema-version "1.0" :seed 42 :meta {:test "email-validation"}})
;; => {:meta {:schema-version "1.0" :seed 42 :test "email-validation"}
;; :result {:status :failure :errors [{:code :user.email/required}]}}Alias for compare-snapshots. See compare-snapshots for full documentation.
Alias for compare-snapshots. See compare-snapshots for full documentation.
(compare-snapshots expected actual)Deep comparison of two snapshots with detailed diff.
Uses clojure.data/diff to identify differences between expected and actual snapshots.
Args: expected - Expected snapshot map actual - Actual snapshot map
Returns: Map with: :equal? - Boolean indicating if snapshots are equal :diff - Vector [only-in-expected only-in-actual shared] from clojure.data/diff
Example: (compare-snapshots {:meta {:seed 42} :result {:status :success}} {:meta {:seed 42} :result {:status :failure}}) ;; => {:equal? false ;; :diff [{:result {:status :success}} ;; {:result {:status :failure}} ;; {:meta {:seed 42}}]}
Deep comparison of two snapshots with detailed diff.
Uses clojure.data/diff to identify differences between expected and actual snapshots.
Args:
expected - Expected snapshot map
actual - Actual snapshot map
Returns:
Map with:
:equal? - Boolean indicating if snapshots are equal
:diff - Vector [only-in-expected only-in-actual shared] from clojure.data/diff
Example:
(compare-snapshots {:meta {:seed 42} :result {:status :success}}
{:meta {:seed 42} :result {:status :failure}})
;; => {:equal? false
;; :diff [{:result {:status :success}}
;; {:result {:status :failure}}
;; {:meta {:seed 42}}]}(format-diff {:keys [equal? diff]})Format a diff result into human-readable string.
Args: diff - Diff result from compare-snapshots
Returns: Formatted string showing differences.
Example: (format-diff (compare-snapshots expected actual)) ;; => "Differences found: Only in expected: {...} Only in actual: {...}"
Format a diff result into human-readable string.
Args:
diff - Diff result from compare-snapshots
Returns:
Formatted string showing differences.
Example:
(format-diff (compare-snapshots expected actual))
;; => "Differences found:
Only in expected: {...}
Only in actual: {...}"(parse-snapshot edn-string)Parse EDN string back to snapshot map.
Args: edn-string - EDN string (from stable-serialize)
Returns: Snapshot map.
Example: (parse-snapshot (stable-serialize snapshot)) ;; => original snapshot
Parse EDN string back to snapshot map. Args: edn-string - EDN string (from stable-serialize) Returns: Snapshot map. Example: (parse-snapshot (stable-serialize snapshot)) ;; => original snapshot
(path-for opts)Compute snapshot file path from test metadata.
Args: opts - Map with: :ns - Test namespace symbol :test - Test name symbol or string :case - Test case name symbol or string (optional) :base - Base directory (default "test/snapshots/validation")
Returns: Relative path string to snapshot file.
Examples: (path-for {:ns 'boundary.user.validation-test :test 'email-required :case 'missing}) ;; => "test/snapshots/validation/boundary/user/validation_test/email_required__missing.edn"
(path-for {:ns 'boundary.user.validation-test :test 'email-format}) ;; => "test/snapshots/validation/boundary/user/validation_test/email_format.edn"
Compute snapshot file path from test metadata.
Args:
opts - Map with:
:ns - Test namespace symbol
:test - Test name symbol or string
:case - Test case name symbol or string (optional)
:base - Base directory (default "test/snapshots/validation")
Returns:
Relative path string to snapshot file.
Examples:
(path-for {:ns 'boundary.user.validation-test
:test 'email-required
:case 'missing})
;; => "test/snapshots/validation/boundary/user/validation_test/email_required__missing.edn"
(path-for {:ns 'boundary.user.validation-test
:test 'email-format})
;; => "test/snapshots/validation/boundary/user/validation_test/email_format.edn"(stable-serialize snapshot)Serialize a snapshot to deterministic EDN string.
Ensures consistent output regardless of map insertion order:
Args: snapshot - Snapshot map (from capture)
Returns: EDN string with deterministic formatting.
Example: (stable-serialize {:meta {:seed 42 :test "example"} :result {:status :success}}) ;; Always produces same string for same data
Serialize a snapshot to deterministic EDN string.
Ensures consistent output regardless of map insertion order:
- Sorts all map keys recursively
- Uses sorted-map and sorted-set
- Pretty-prints with consistent formatting
Args:
snapshot - Snapshot map (from capture)
Returns:
EDN string with deterministic formatting.
Example:
(stable-serialize {:meta {:seed 42 :test "example"} :result {:status :success}})
;; Always produces same string for same datacljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |