Skip to content
This repository has been archived by the owner on Oct 28, 2024. It is now read-only.

Commit

Permalink
Do not run fixtures in namespaces when using test-ns-hook
Browse files Browse the repository at this point in the history
This is in accordance with clojure.test's definition of fixtures and
test-ns-hook:
   Note: Fixtures and test-ns-hook are mutually incompatible.  If you
   are using test-ns-hook, fixture functions will *never* be run.

Global fixtures still run.
  • Loading branch information
Mourjo Sen committed May 4, 2020
1 parent 2d35e34 commit 4fc6d36
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 45 deletions.
89 changes: 59 additions & 30 deletions src/circleci/test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,27 @@
:var v
:elapsed elapsed})))))))))


(defn- test-var-with-ns-hook*
[config v]
(assert (var? v) (format "v must be a var. got %s" (class v)))
(let [global-fixture-fn (make-global-fixture config)]
(when (:test (meta v))
(binding [test/*testing-vars* (conj test/*testing-vars* v)]
(let [start-time (System/nanoTime)]
(try
(global-fixture-fn (fn [] (test* v)))
(catch Exception e
(test/do-report {:type :error,
:message "Uncaught exception, not in assertion."
:expected nil, :actual e}))
(finally
(let [stop-time (System/nanoTime)
elapsed (-> stop-time (- start-time) nanos->seconds)]
(test/do-report {:type :end-test-var,
:var v
:elapsed elapsed})))))))))

(defn test-var
"The entry-point into circleci.test for running a single test.
Expand All @@ -129,7 +150,7 @@


(defn- test-all-vars [config ns selector]
(doseq [v (get-all-vars config ns selector)]
(doseq [v (sort-by str (get-all-vars config ns selector))]
(test-var v config)))


Expand All @@ -139,15 +160,21 @@
(alter-meta! v #(-> % (assoc to-key x) (dissoc from-key)))))


(defmacro with-unmarking
[ns var-selector & body]
`(let [vars# (vals (ns-interns ~ns))]
(defmacro select-test-ns-hook
"When test-ns-hook is used, select vars based on the selector but
don't run once and each fixtures."
[ns-hook var-selector config]
`(let [ns# (-> ~ns-hook meta :ns)
vars# (vals (ns-interns ns#))]
(try
(doseq [a-var# vars#]
(when (and (:test (meta a-var#))
(not (~var-selector a-var#)))
(copy-meta a-var# :test ::skipped-test)))
~@body

(binding [test/test-var (partial test-var-with-ns-hook* ~config)]
((var-get ~ns-hook)))

(finally
(doseq [a-var# vars#]
(copy-meta a-var# ::skipped-test :test))))))
Expand All @@ -170,32 +197,33 @@
test/report report/report
report/*reporters* (get-reporters config)]
(let [ns-obj (the-ns ns)
run-once-fixture? (seq (get-all-vars config ns selector))
ns-hook (find-var (symbol (str (ns-name ns-obj))
"test-ns-hook"))
run-once-fixture? (when-not ns-hook
(seq (get-all-vars config ns selector)))
global-fixture-fn (make-global-fixture config)
once-fixture-fn (if run-once-fixture?
(make-once-fixture ns-obj)
(fn [f] (f)))]
(try
(global-fixture-fn
(fn []
(once-fixture-fn
(fn []
(test/do-report {:type :begin-test-ns, :ns ns-obj})
;; If the namespace has a test-ns-hook function, call that:
(if-let [v (find-var (symbol (str (ns-name ns-obj))
"test-ns-hook"))]
(with-unmarking ns
(fn [a-var] (-> a-var meta selector))
(binding [test/test-var (partial test-var* config)]
((var-get v))))

;; Otherwise, just test every var in the namespace.
(test-all-vars config ns-obj selector))))))
(fn []
(once-fixture-fn
(fn []
(test/do-report {:type :begin-test-ns, :ns ns-obj})
;; If the namespace has a test-ns-hook function, call that:
(if ns-hook
(select-test-ns-hook ns-hook
(fn [a-var] (-> a-var meta selector))
config)

;; Otherwise, just test every var in the namespace.
(test-all-vars config ns-obj selector))))))
(catch Exception e
(binding [test/*testing-vars*
(conj test/*testing-vars* (with-meta 'test
{:name "Exception thrown from test fixture"
:ns ns-obj}))]
{:name "Exception thrown from test fixture"
:ns ns-obj}))]
(test/do-report {:type :error,
:message "Exception thrown from test fixture."
:expected nil, :actual e})))
Expand All @@ -208,18 +236,19 @@
(for [n (sort-by str (distinct nses))]
(test-ns n selector config)))



(defn test-selected-var
[v selector config]
(binding [test/*report-counters* (ref test/*initial-report-counters*)
test/report report/report
report/*reporters* (get-reporters config)]
(let [n (-> v meta :ns)]
(if-let [tnv (find-var (symbol (str (ns-name n))
"test-ns-hook"))]
(with-unmarking n
(fn [a-var] (and (= a-var v) (-> a-var meta selector)))
(binding [test/test-var (partial test-var* config)]
((var-get tnv))))
(if-let [ns-hook (find-var (symbol (str (ns-name n))
"test-ns-hook"))]
(select-test-ns-hook ns-hook
(fn [a-var] (and (= a-var v) (-> a-var meta selector)))
config)

(when (-> v meta selector)
(binding [test/test-var (partial test-var* config)]
Expand All @@ -230,10 +259,10 @@
(defn test-vars-in-ns-groups
[vars selector config]
(let [ns-groups (group-by (comp :ns meta) (distinct vars))
reports (for [ns (keys ns-groups)]
reports (for [ns (sort-by str (keys ns-groups))]
(try
(test/do-report {:type :begin-test-ns, :ns ns})
(for [v (get ns-groups ns)]
(for [v (sort-by str (get ns-groups ns))]
(test-selected-var v selector config))
(finally (test/do-report {:type :end-test-ns, :ns ns}))))]
(apply concat reports)))
Expand Down
24 changes: 9 additions & 15 deletions test/circleci/sample_test_ns1.clj
Original file line number Diff line number Diff line change
Expand Up @@ -5,32 +5,26 @@
(def ^:dynamic veach 0)
(def ^:dynamic vcommon 0)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; This namespace's tests will fail with the Leiningen test runner ;;
;; because when there is a test-ns-hook, fixtures are NOT run by ;;
;; Leiningen or Clojure.test ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(deftest test-1
(println "Running: circleci.sample-test-ns1/test-1")
(is (= 1 1))
(is (= 1 veach))
(is (= 1 vonce))
(is (= 2 vcommon)))
(is (zero? veach))
(is (zero? vonce))
(is (zero? vcommon)))

(deftest test-2
(println "Running: circleci.sample-test-ns1/test-2")
(is (= 10 10))
(is (= 1 veach))
(is (= 1 vonce))
(is (= 2 vcommon)))
(is (zero? veach))
(is (zero? vonce))
(is (zero? vcommon)))

(deftest test-3
(println "Running: circleci.sample-test-ns1/test-3")
(is (= 109 109))
(is (= 1 veach))
(is (= 1 vonce))
(is (= 2 vcommon)))
(is (zero? veach))
(is (zero? vonce))
(is (zero? vcommon)))


(defn test-ns-hook
Expand Down

0 comments on commit 4fc6d36

Please sign in to comment.