liveBook · Manning

Assert-expr

As explained in Clojure: The Essential Reference

assert-expr is a clojure.test multimethod that dispatches assertion-expression implementations.

assert-expr is a clojure.test multimethod that dispatches assertion-expression implementations, allowing is to recognize predicates beyond ordinary equality. section 22.9

A custom assertion implementation typically:

  • Defines a defmethod for the predicate symbol, receiving a message and the assertion form. section 22.9
  • Extracts operands and optional arguments from the form, then expands them into executable test code. section 22.9
  • Calls do-report with :type, :message, :expected, and :actual information before returning the Boolean result. section 22.9

A roughly assertion

A roughly method compares two values within a decimal tolerance, defaulting to two places. `(is (roughly 2 (sqrt 4) 14))` passes, while a stricter tolerance can fail and report the expected expression and actual Boolean result. section 22.9

(require '[clojure.test :refer [is deftest] :as t])

(defmethod t/assert-expr 'roughly [msg form] ; #1
  `(let [op1# ~(nth form 1) ; #2
         op2# ~(nth form 2)
         tolerance# (if (= 4 ~(count form)) ~(last form) 2)
         decimals# (/ 1. (Math/pow 10 tolerance#))
         result# (< (Math/abs (- op1# op2#)) decimals#)]
     (t/do-report   ; #3
       {:type (if result# :pass :fail)
        :message ~msg
        :expected (format "%s should be roughly %s with %s tolerance"
                          op1# op2# decimals#)
        :actual result#})
     result#))

(deftest sqrt-test ; #4
  (is (roughly 2 (sqrt 4) 14))
  (is (roughly 2 (sqrt 4) 15)))

(t/test-var #'sqrt-test)

;; FAIL in (sqrt-test) (form-init205.clj:3)
;; expected: "2 should be roughly 2.000000000000002 with 1.0E-15 tolerance"
;;   actual: false

Browse the complete roughly implementation, including form destructuring, tolerance calculation, do-report integration, and test output. section 22.9

How Clojure: The Essential Reference covers it

How deep it goes
Explains dispatch, method inputs, assertion expansion, and reporting, but does not develop the multimethod mechanism generally.
Examples
Uses a roughly predicate to compare square-root results with configurable decimal tolerance.
What it assumes
Assumes familiarity with clojure.test assertions and teaches extension through defmethod and do-report.
What you can do after
Build custom clojure.test assertions that evaluate expressions and produce structured pass or failure reports.
How it connects
Connects assert-expr with is, custom predicates, do-report, and assertion reporting.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Clojure: The Essential Reference. The section links point to the parts of the book it draws on.