Search code examples
clojuremacrosclojure.specgenerative-testing

How to check Clojure, macro specs?


If I try to check a macro spec with clojure.spec.test.alpha, no tests are run, but if I define the same macro as a function with the same spec, a sequence of tests are run against the function. I can always generate parameters to unit test the macro, but is there a way to get that for free with spec? Here is an example:

(ns private.tmp.spec-test
  (:require [clojure.spec.alpha :as spec]
            [clojure.spec.test.alpha :as stest]))


;;; Macro


(defmacro twice' [x]
  `(* 2.0 ~x))

(spec/fdef twice'
           :args (spec/cat :x double?)
           :ret double?
           :fn (fn [{{:keys [x]} :args, x2 :ret}]
                 (or (and
                      (Double/isNaN x)
                      (Double/isNaN x2))
                     (= x2 (+ x x)))))

(println (stest/summarize-results (stest/check `twice')))  ;; {:total 0}


;;; Function


(defn twice [x]
  (* 2.0 x))

(spec/fdef twice
           :args (spec/cat :x double?)
           :ret double?
           :fn (fn [{{:keys [x]} :args, x2 :ret}]
                 (or (and
                      (Double/isNaN x)
                      (Double/isNaN x2))
                     (= x2 (+ x x)))))

(println (stest/summarize-results (stest/check `twice)))  ;; {:total 1, :check-passed 1}

Solution

  • I asked this question on the Clojure, Google Group and the consensus is that checking macros is not supported. The preferred method of testing is by generating params for unit tests by test.check.

    https://groups.google.com/forum/#!topic/clojure/RxnwKcha0cE