Skip to content

Commit

Permalink
Add namespace-level context hook support
Browse files Browse the repository at this point in the history
  • Loading branch information
NoahTheDuke committed Sep 23, 2024
1 parent 89dfb6c commit cc8ea6b
Show file tree
Hide file tree
Showing 8 changed files with 51 additions and 23 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
(= [:before :after] @state))))
```

- Add the macro `around`, which works like a clojure.test fixture:
- Add the macro `around`, which works like a `clojure.test` fixture:

```clojure
(describe "it works"
Expand All @@ -29,6 +29,8 @@

- Add macros `before-each` and `after-each`, which are run before/after each nested test case.

- Add function `set-ns-context!` which sets the current namespace's context to be the given vector. Works like `clojure.test/use-fixture`.

### Changes

- Changed primary branch from `master` to `main`.
Expand Down
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ To partition your test suite based on metadata, you can use `-i`/`--include` to

## Setup and Teardown

To handle set up and tear down of stateful architecture, Lazytest provides the hooks `(before)`, `(before-each)`, `(after-each)`, `(after)`, and `(around)`. You can add them to a `:context` vector in suite or test-case metadata:
To handle set up and tear down of stateful architecture, Lazytest provides the hooks `before`, `before-each`, `after-each`, `after`, and `around`, along with the helper `set-ns-context!`. You can add them to a `:context` vector in suite or test-case metadata:

```clojure
(defdescribe before-and-after-test
Expand Down Expand Up @@ -229,7 +229,9 @@ To handle set up and tear down of stateful architecture, Lazytest provides the h

`(around)` hooks are combined with the same logic as `clojure.test`'s `join-fixtures`.

Context functions of the same kind are run in the order they're defined. When executing a given suite or test-case, all `(before)` hooks are run once, then each `before-each` hook is run, then the `(around)` hooks are called on the nested tests (if they exist), then each `(after-each)` hook is run, then all `(after)` hooks are run once.
Context functions of the same kind are run in the order they're defined. When executing a given suite or test-case, all `before` hooks are run once, then each `before-each` hook is run, then the `around` hooks are called on the nested tests (if they exist), then each `after-each` hook is run, then all `after` hooks are run once.

To set context functions for an entire namespace, use `set-ns-context!`. There is currently no way to define run-wide context functions.

## Output

Expand Down
1 change: 0 additions & 1 deletion deps.edn
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
org.clojure/tools.cli {:mvn/version "1.1.230"}
org.clojure/tools.namespace {:mvn/version "1.5.0"}
io.github.tonsky/clj-reload {:mvn/version "0.7.0"}
dev.weavejester/medley {:mvn/version "1.8.1"}
metosin/malli {:mvn/version "0.16.3"}}
:deps/prep-lib {:ensure "target/classes"
:alias :prep
Expand Down
18 changes: 9 additions & 9 deletions src/clojure/lazytest/context.clj
Original file line number Diff line number Diff line change
Expand Up @@ -15,39 +15,39 @@

(defn run-befores
[obj]
(doseq [before-fn (-> obj :context :before)
(doseq [before-fn (-> obj :lazytest/context :before)
:when (fn? before-fn)]
(before-fn)))

(defn run-before-eachs
[obj]
(doseq [before-each-fn (-> obj :context :before-each)
(doseq [before-each-fn (-> obj :lazytest/context :before-each)
:when (fn? before-each-fn)]
(before-each-fn)))

(defn run-after-eachs
[obj]
(doseq [after-each-fn (-> obj :context :after-each)
(doseq [after-each-fn (-> obj :lazytest/context :after-each)
:when (fn? after-each-fn)]
(after-each-fn)))

(defn run-afters
[obj]
(doseq [after-fn (-> obj :context :after)
(doseq [after-fn (-> obj :lazytest/context :after)
:when (fn? after-fn)]
(after-fn)))

(defn combine-arounds
[obj]
(when-let [arounds (-> obj :context :around seq)]
(when-let [arounds (-> obj :lazytest/context :around seq)]
(c.t/join-fixtures arounds)))

(defn propagate-eachs
[parent-meta child]
(let [child-meta (meta child)
updated-meta (-> child-meta
(assoc-in [:context :before-each] (into (vec (-> parent-meta :context :before-each))
(-> child-meta :context :before-each)))
(assoc-in [:context :after-each] (into (vec (-> child-meta :context :after-each))
(-> parent-meta :context :after-each))))]
(assoc-in [:lazytest/context :before-each] (into (vec (-> parent-meta :lazytest/context :before-each))
(-> child-meta :lazytest/context :before-each)))
(assoc-in [:lazytest/context :after-each] (into (vec (-> child-meta :lazytest/context :after-each))
(-> parent-meta :lazytest/context :after-each))))]
(with-meta child updated-meta)))
21 changes: 16 additions & 5 deletions src/clojure/lazytest/core.clj
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
(ns lazytest.core
(:require
[lazytest.context :refer [merge-context]]
[lazytest.context :as ctx]
[lazytest.malli]
[lazytest.suite :refer [suite]]
[lazytest.test-case :refer [test-case]]
[medley.core :refer [update-existing]])
[lazytest.test-case :refer [test-case]])
(:import
(lazytest ExpectationFailed)))

Expand Down Expand Up @@ -127,6 +126,18 @@
(simple-symbol? (first param))) "Must be a vector of one symbol")
`{:around (fn around# ~param (let [ret# (do ~@body)] ret#))})

(defn set-ns-context!
[context]
(alter-meta! *ns* assoc :lazytest/context (ctx/merge-context context)))

(defn ^:no-doc cleanup-context
"Convert :context to :lazytest/context"
[metadata]
(cond-> metadata
(:context metadata)
(-> (assoc :lazytest/context (ctx/merge-context (:context metadata)))
(dissoc :context))))

(defmacro describe
"Defines a suite of tests.
Expand All @@ -151,7 +162,7 @@
metadata (merged-metadata children &form doc attr-map)]
`(suite (with-meta
(flatten [~@children])
(update-existing ~metadata :context merge-context)))))
(cleanup-context ~metadata)))))

(defmacro defdescribe
"`describe` helper that assigns a `describe` call to a Var of the given name.
Expand Down Expand Up @@ -213,7 +224,7 @@
metadata (merged-metadata body &form doc attr-map)]
`(test-case (with-meta
(fn it# [] (let [ret# (do ~@body)] ret#))
(update-existing ~metadata :context merge-context)))))
(cleanup-context ~metadata)))))

(defmacro expect-it
"Defines a single test case that wraps the given expr in an `expect` call.
Expand Down
2 changes: 1 addition & 1 deletion src/clojure/lazytest/find.clj
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
(when-let [s (test-seq-for-ns n)]
(vary-meta
(suite (test-seq s))
assoc :type :lazytest/ns-suite :ns-name (ns-name n))))))
merge (meta n) {:type :lazytest/ns-suite :ns-name (ns-name n)})))))

(defn find-suite
"Returns test suite containing suites for the given namespaces.
Expand Down
14 changes: 14 additions & 0 deletions test/clojure/lazytest/context_namespace_test.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
(ns lazytest.context-namespace-test
(:require
[lazytest.core :refer [around before-each defdescribe expect-it
set-ns-context!]]))

(def state (volatile! nil))

(set-ns-context!
[(around [f] (vreset! state []) (f) (vreset! state []))
(before-each (vswap! state conj :before-each))])

(defdescribe context-namespace-test
(expect-it "works"
(= [:before-each] @state)))
8 changes: 4 additions & 4 deletions test/clojure/lazytest/context_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -111,10 +111,10 @@

(defdescribe propagate-eachs-test
(expect-it "combines correctly"
(= {:context {:before-each [1 2 3 4 5 6]
:after-each []}}
(meta (propagate-eachs {:context {:before-each [1 2 3]}}
(with-meta [] {:context {:before-each [4 5 6]}}))))))
(= {:lazytest/context {:before-each [1 2 3 4 5 6]
:after-each []}}
(meta (propagate-eachs {:lazytest/context {:before-each [1 2 3]}}
(with-meta [] {:lazytest/context {:before-each [4 5 6]}}))))))

(defdescribe complex-context-test
(given [state (volatile! [])]
Expand Down

0 comments on commit cc8ea6b

Please sign in to comment.