diff --git a/CHANGELOG.md b/CHANGELOG.md index d8cecaa..048b197 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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" @@ -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`. diff --git a/README.md b/README.md index 0bcb527..e497d11 100644 --- a/README.md +++ b/README.md @@ -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 @@ -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 diff --git a/deps.edn b/deps.edn index 4198c4b..942862c 100644 --- a/deps.edn +++ b/deps.edn @@ -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 diff --git a/src/clojure/lazytest/context.clj b/src/clojure/lazytest/context.clj index 40711e2..cb655e1 100644 --- a/src/clojure/lazytest/context.clj +++ b/src/clojure/lazytest/context.clj @@ -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))) diff --git a/src/clojure/lazytest/core.clj b/src/clojure/lazytest/core.clj index e5f7a8f..137d535 100644 --- a/src/clojure/lazytest/core.clj +++ b/src/clojure/lazytest/core.clj @@ -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))) @@ -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. @@ -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. @@ -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. diff --git a/src/clojure/lazytest/find.clj b/src/clojure/lazytest/find.clj index 82a1e44..0e0afe2 100644 --- a/src/clojure/lazytest/find.clj +++ b/src/clojure/lazytest/find.clj @@ -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. diff --git a/test/clojure/lazytest/context_namespace_test.clj b/test/clojure/lazytest/context_namespace_test.clj new file mode 100644 index 0000000..4c389c6 --- /dev/null +++ b/test/clojure/lazytest/context_namespace_test.clj @@ -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))) diff --git a/test/clojure/lazytest/context_test.clj b/test/clojure/lazytest/context_test.clj index 4b4d4fd..387450b 100644 --- a/test/clojure/lazytest/context_test.clj +++ b/test/clojure/lazytest/context_test.clj @@ -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! [])]