The Power Assertions feature in the Groovy language is a strong tool, it makes writing tests and finding bugs easier. This is an implementation for the Clojure programming language with support for macros and lazy sequences.
It prints subexpressions on assert failure.
And each evaluations of subexpressions are shown.
This library provides five small macros for easier debugging.
examine macro can be used to trace parts of an evaluated expression. Debug information is printed to the standard output and the value of the expression is returned.assert macro is similar to clojure.core/assert. It wraps the examined information in the thrown AssertionError instance.verify macro is just like assert, but it throws an ExceptionInfo instead.is and are macros are drop-in replacements for clojure.test/is and clojure.test/are used in unit tests.First, add the dependency to your project.clj.
[io.github.erdos/erdos.assert "0.2.3"]
Second, require the namespace:
(require '[erdos.assert :as ea])
In the REPL, examining simple expressions will print to *out*.
erdos.assert=> (examine (* (+ 19 17) (- 19 17)))
(* (+ 19 17) (- 19 17))
¦ ¦ ¦
72 36 2
You can also write assertions that will wrap examined data as a string in the AssertionError instance.
erdos.assert=> (assert (= 1 (* 3 (/ 1 3)) "") ; does not print anything
erdos.assert=> (assert (= (* 1.0 1) (* 3 (/ 1 3))) "")
; AssertionError
; (= (* 1.0 1) (* 3 (/ 1 3)))
; ¦ ¦ ¦ ¦
; ¦ 1.0 1N 1/3
; false
Shown output is arranged to make place for more complex output.
erdos.assert=> (examine (+ (* 12 (- 32 12) 12.2) (- 3 (/ 1 2 3 4) 2.2) (* (- 1 2) 3)))
(+ (* 12 (- 32 12) 12.2) (- 3 (/ 1 2 3 4) 2.2) (* (- 1 2) 3))
¦ ¦ ¦ ¦ ¦ ¦ ¦
¦ ¦ 20 ¦ 1/24 -3 -1
¦ 2928.0 0.7583333333333329
2925.758333333333
Some expressions are evaluated repeatedly, hence all values are shown.
erdos.assert=> (examine (dotimes [i 5] (print (* i i))))
(dotimes [i 5] (print (* i i)))
¦ ¦
¦ 16, 9, 4, 1, 0
nil, nil, nil, nil, nil
Only the already realized part is printed for lazy sequences.
erdos.assert=> (examine (reduce + (map * (range) (range 0 10 2))))
(reduce + (map * (range) (range 0 10 2)))
¦ ¦ ¦ ¦
60 (…) (0 …) (0 2 4 6 8)
In such cases you might want to run doall on intermediate lazy sequences.
erdos.assert=> (examine (reduce + (doall (map * (range) (range 0 10 2)))))
(reduce + (doall (map * (range) (range 0 10 2))))
¦ ¦ ¦ ¦ ¦
60 ¦ (…) (0 …) (0 2 4 6 8)
(0 2 8 18 32)
Add the ^:show metadata to function arguments to show the values on every function invocation:
erdos.assert=> (examine (mapv (fn [^:show a] (mod a 3)) (range 10)))
(mapv (fn [a] (mod a 3)) (range 10))
¦ ¦ ¦ ¦
¦ ¦ ¦ (0 1 2 3 4 5 6 7 8 9)
¦ ¦ 0, 1, 2, 0, 1, 2, 0, 1, 2, 0
¦ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
[0 1 2 0 1 2 0 1 2 0]
Copyright © 2017-2021 Janos Erdos
Distributed under the Eclipse Public License version 1.0.
Can you improve this documentation? These fine people already did:
Janos Erdos & erdos janosEdit on GitHub
cljdoc 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 |