Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Install all components #164

Merged
merged 1 commit into from
Mar 4, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 27 additions & 31 deletions spec/speclj/core_spec.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,7 @@
(it "only executes once"
(should= 2 @gadget)
(should= 0 @widget)
(should= 2 @bauble))
)
(should= 2 @bauble)))

(def #^{:dynamic true} *gewgaw* 0)
(describe "around forms"
Expand All @@ -106,17 +105,14 @@

(context "with before and after"
(before (should= 42 *gewgaw*))
(it "executes around all of them" :filler)
)
)
(it "executes around all of them" :filler)))


(describe "around-all form"
(describe "with nothing else"
(let [widget (atom 5)
call-count (atom 0)]

[
(around-all [context]
(swap! call-count inc)
(binding [*gewgaw* (swap! widget inc)]
Expand Down Expand Up @@ -146,11 +142,10 @@
(should= 1 @widget))

(it "and still only execute once"
(should= 3 @call-count)))]))
(should= 3 @call-count)))))

(describe "with before-alls"
(let [widget (atom 6)]
[
(around-all [context]
(swap! widget #(- % 2))
(context))
Expand All @@ -159,24 +154,21 @@
(swap! widget #(/ % 2)))

(it "executes after before-alls regardless of definition order"
(should= 1 @widget))]))
(should= 1 @widget))))

(describe "with withs"
(let [widget (atom 6)]
[
(describe "with after-alls"
[(after-all
(swap! widget #(/ % 2)))
(describe "with after-alls"
(after-all
(swap! widget #(/ % 2)))

(around-all [context]
(context))
(swap! widget #(- % 2))
])
(around-all [context]
(context))
(swap! widget #(- % 2)))

(describe "previous after-all and around-all forms"
(it "executes before after-alls regardless of definition order"
(should= 2 @widget)))
])
(describe "previous after-all and around-all forms"
(it "executes before after-alls regardless of definition order"
(should= 2 @widget))))

(describe "with with-alls"
(with-all with-all-val 1)
Expand All @@ -187,8 +179,7 @@
(should= 1 @with-all-val))

(it "enters after binding with-alls and exits before unbinding"
:filler)))
)
:filler))))

(def frippery (atom []))
(def gimcrack (atom "gimcrack"))
Expand Down Expand Up @@ -257,10 +248,7 @@

(it ": the with value has changed"
(should= @@bibelot @@gimcrack)
(should (not (identical? @bibelot @gimcrack))))
)
)
)
(should (not (identical? @bibelot @gimcrack)))))))

(describe "Nested contexts"
(it "execute all the components in the right order"
Expand Down Expand Up @@ -291,8 +279,7 @@

(context "child2"
(tags :four :five)
(it "tag :one :three :four" :filler))
)
(it "tag :one :three :four" :filler)))

(describe "with"
(def lazy-calls (atom 0))
Expand Down Expand Up @@ -343,8 +330,17 @@
(should= 1 @non-lazy-with-all-calls))

(it "has not been reset and deref'ed"
(should= 1 @non-lazy-with-all-calls))
)
(should= 1 @non-lazy-with-all-calls)))

(describe "Nesting components inside let"
(let [a (atom 0)]
(it "first one runs"
(swap! a inc))
(it "second one runs"
(swap! a inc))
(it "third one runs"
(swap! a inc)
(should= 3 @a))))

;(run-specs :tags ["two"])
(run-specs)
73 changes: 55 additions & 18 deletions src/speclj/core.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,52 @@
(defmacro ^:no-doc -new-pending [message]
`(speclj.platform.SpecPending. ~message))

(defn install-component [x]
(when (bound? #'speclj.config/*parent-description*)
(speclj.components/install x speclj.config/*parent-description*))
x)

(def install-new-description
(comp install-component speclj.components/new-description))

(def install-new-characteristic
(comp install-component speclj.components/new-characteristic))

(def install-new-tag
(comp install-component speclj.components/new-tag))

(def install-new-with
(comp install-component speclj.components/new-with))

(def install-new-with-all
(comp install-component speclj.components/new-with-all))

(def install-new-before
(comp install-component speclj.components/new-before))

(def install-new-before-all
(comp install-component speclj.components/new-before-all))

(def install-new-after
(comp install-component speclj.components/new-after))

(def install-new-after-all
(comp install-component speclj.components/new-after-all))

(def install-new-around
(comp install-component speclj.components/new-around))

(def install-new-around-all
(comp install-component speclj.components/new-around-all))

(defmacro it
"body => any forms but aught to contain at least one assertion (should)

Declares a new characteristic (example in rspec)."
[name & body]
(if (seq body)
`(speclj.components/new-characteristic ~name (fn [] ~@body))
`(speclj.components/new-characteristic ~name (fn [] (pending)))))
`(install-new-characteristic ~name (fn [] ~@body))
`(install-new-characteristic ~name (fn [] (pending)))))

(defmacro xit
"Syntactic shortcut to make the characteristic pending."
Expand All @@ -56,13 +94,12 @@
(defmacro describe
"body => & spec-components

Declares a new spec. The body can contain any forms that evaluate to spec compoenents (it, before, after, with ...)."
Declares a new spec. The body can contain any forms that evaluate to spec components (it, before, after, with ...)."
[name & components]
`(let [description# (speclj.components/new-description ~name ~(clojure.core/name (.name *ns*)))]
`(let [description# (install-new-description ~name ~(clojure.core/name (.name *ns*)))]
(binding [speclj.config/*parent-description* description#]
; MDM - use a vector below - cljs generates a warning because def/declares don't eval immediatly
(doseq [component# (vector ~@components)]
(speclj.components/install component# description#)))
; MDM - use a vector below - cljs generates a warning because def/declares don't eval immediately
(vector ~@components))
(when-not (if-cljs
speclj.config/*parent-description*
(bound? #'speclj.config/*parent-description*))
Expand All @@ -79,13 +116,13 @@
"Declares a function that is invoked before each characteristic in the containing describe scope is evaluated. The body
may consist of any forms, presumably ones that perform side effects."
[& body]
`(speclj.components/new-before (fn [] ~@body)))
`(install-new-before (fn [] ~@body)))

(defmacro after
"Declares a function that is invoked after each characteristic in the containing describe scope is evaluated. The body
may consist of any forms, presumably ones that perform side effects."
[& body]
`(speclj.components/new-after (fn [] ~@body)))
`(install-new-after (fn [] ~@body)))

(defmacro around
"Declares a function that will be invoked around each characteristic of the containing describe scope.
Expand All @@ -98,24 +135,24 @@
(around [it] (try (it) (finally :clean-up)))
"
[binding & body]
`(speclj.components/new-around (fn ~binding ~@body)))
`(install-new-around (fn ~binding ~@body)))

(defmacro before-all
"Declares a function that is invoked once before any characteristic in the containing describe scope is evaluated. The
body may consist of any forms, presumably ones that perform side effects."
[& body]
`(speclj.components/new-before-all (fn [] ~@body)))
`(install-new-before-all (fn [] ~@body)))

(defmacro after-all
"Declares a function that is invoked once after all the characteristics in the containing describe scope have been
evaluated. The body may consist of any forms, presumably ones that perform side effects."
[& body]
`(speclj.components/new-after-all (fn [] ~@body)))
`(install-new-after-all (fn [] ~@body)))

(defmacro around-all
"Declares a function that is invoked once around all characteristics of the containing describe scope."
[context & body]
`(speclj.components/new-around-all (fn ~context ~@body)))
`(install-new-around-all (fn ~context ~@body)))

(def cljs-munge
#?(:clj
Expand Down Expand Up @@ -144,7 +181,7 @@
(with meaning 42)
(it \"knows the meaning of life\" (should= @meaning (the-meaning-of :life)))"
[name & body]
(-make-with name body `speclj.components/new-with false))
(-make-with name body `install-new-with false))

(defmacro with!
"Declares a reference-able symbol that will be evaluated immediately and reset once per characteristic of the containing
Expand All @@ -154,7 +191,7 @@
(with! my-with! (swap! my-num inc))
(it \"increments my-num before being accessed\" (should= 1 @my-num) (should= 2 @my-with!))"
[name & body]
(-make-with name body `speclj.components/new-with true))
(-make-with name body `install-new-with true))

(defmacro with-all
"Declares a reference-able symbol that will be lazily evaluated once per context. The body may contain any forms,
Expand All @@ -163,7 +200,7 @@
(with-all meaning 42)
(it \"knows the meaning of life\" (should= @meaning (the-meaning-of :life)))"
[name & body]
(-make-with name body `speclj.components/new-with-all false))
(-make-with name body `install-new-with-all false))

(defmacro with-all!
"Declares a reference-able symbol that will be immediately evaluated once per context. The body may contain any forms,
Expand All @@ -178,7 +215,7 @@
(should= 1 @my-num)
(should= 2 @my-with!))"
[name & body]
(-make-with name body `speclj.components/new-with-all true))
(-make-with name body `install-new-with-all true))

(defmacro ^:no-doc -to-s [thing]
`(if (nil? ~thing) "nil" (pr-str ~thing)))
Expand Down Expand Up @@ -455,7 +492,7 @@ There are three options for passing different kinds of predicates:
(tags :one :two)"
[& values]
(let [tag-kws (mapv keyword values)]
`(mapv speclj.components/new-tag ~tag-kws)))
`(mapv install-new-tag ~tag-kws)))

(defmacro with-stubs
"Add this to describe/context blocks that use stubs. It will setup a clean recording environment."
Expand Down