I wrote a very small little DSL for spec testing:
(ns funky-spec.core) (def described-entity (ref nil)) (defn it [fun & v] (assert (apply fun (cons (deref described-entity) v)))) (def it-is it) (def it-is-the it) (defmacro describe [value nest] `(dosync (ref-set described-entity ~value) ~nest)) (defmacro when-applied [nest] `(dosync (ref-set described-entity ((deref described-entity))) ~nest)) (defmacro when-applied-to [& args-and-nest] `(dosync (ref-set described-entity (apply (deref described-entity) (take (dec (count (quote ~args-and-nest))) (quote ~args-and-nest)))) (eval (last (quote ~args-and-nest)))))
This turned out to be very nice, for writing some simple, concise specs:
(ns funky-spec.core-test (:require [clojure.test :refer :all] [funky-spec.core :refer :all])) (describe 42 (it = 42)) (describe 99 (it not= 42)) (describe 0 (it-is zero?)) (describe 99 (it-is-the (complement zero?))) (defn answer  42) (describe answer (when-applied (it = 42))) (describe identity (when-applied-to 99 (it = 99))) (describe + (when-applied-to 42 35 (it = 77))) (describe + (when-applied-to 42 35 9 10 (it = 96)))
I'm new to Clojure and macros so any thoughts on this code would be appreciated. I have a few concerns that you could start with:
when-appliedcould (I believe) be an alias for
when-applied-to. I can't get this to work with
def, is there something I am missing?
- Is there a better pattern I could use other than a "global"
described-entity? I tried using
letand shadowing, but couldn't get it to work with macros
when-applied-to, there's a lot of quoting and an
eval, I did this to keep
itfrom pre-maturely executing. Is there a cleaner way to thunk