|
| 1 | +(ns pez.baldr |
| 2 | + (:require #?(:cljs [cljs.test :as t] |
| 3 | + :clj [clojure.test :as t]) |
| 4 | + [clojure.string :as string])) |
| 5 | + |
| 6 | +(defn- default [text] |
| 7 | + (str "\033[39m" text "\033[22m")) |
| 8 | + |
| 9 | +(defn- gray [text] |
| 10 | + (str "\033[90m" text "\033[39m")) |
| 11 | + |
| 12 | +(defn- green [text] |
| 13 | + (str "\033[1;32m" text "\033[22m")) |
| 14 | + |
| 15 | +(defn- red [text] |
| 16 | + (str "\033[31m" text "\033[39m")) |
| 17 | + |
| 18 | +(def ^:private initial-state {:seen-contexts nil |
| 19 | + :failure-prints []}) |
| 20 | + |
| 21 | +(defonce ^:private !state (atom initial-state)) |
| 22 | + |
| 23 | +(defn- indent [level] |
| 24 | + (apply str (repeat (* 2 level) " "))) |
| 25 | + |
| 26 | +(defn- get-report [m contexts seen-contexts {:keys [color bullet bullet-color context-color]}] |
| 27 | + (let [common-contexts (take-while true? (map = (reverse seen-contexts) (reverse contexts))) |
| 28 | + common-prefix-length (count common-contexts) |
| 29 | + new-contexts (reverse (take (- (count contexts) common-prefix-length) contexts)) |
| 30 | + context-color (or context-color default) |
| 31 | + message (or (:message m) (pr-str (:expected m)))] |
| 32 | + (cond-> [] |
| 33 | + (seq new-contexts) (into (map-indexed (fn [idx ctx] |
| 34 | + (str (indent (+ 2 common-prefix-length idx)) |
| 35 | + (context-color ctx))) |
| 36 | + new-contexts)) |
| 37 | + :always (conj (str (indent (+ 2 (count contexts))) |
| 38 | + (str (bullet-color bullet) " " (color message))))))) |
| 39 | + |
| 40 | +(defn- report! [m config] |
| 41 | + (let [contexts #?(:cljs (:testing-contexts (t/get-current-env)) |
| 42 | + :clj t/*testing-contexts*) |
| 43 | + printouts (get-report m contexts (:seen-contexts @!state) config)] |
| 44 | + (swap! !state assoc :seen-contexts contexts) |
| 45 | + (doseq [printout printouts] |
| 46 | + (println printout)))) |
| 47 | + |
| 48 | +(defn- dispatch-value [type] |
| 49 | + [::t/default type]) |
| 50 | + |
| 51 | +(defmethod t/report (dispatch-value :begin-test-var) [_m] |
| 52 | + (swap! !state merge (select-keys initial-state [:seen-contexts]))) |
| 53 | + |
| 54 | +(def ^:private original-summary (get-method t/report (dispatch-value :summary))) |
| 55 | +(defmethod t/report (dispatch-value :summary) [m] |
| 56 | + (when (seq (:failure-prints @!state)) |
| 57 | + (println)) |
| 58 | + (doseq [[i failure-print] (map-indexed vector (:failure-prints @!state))] |
| 59 | + (println (red (str (inc i) ") " (string/trim failure-print))))) |
| 60 | + (reset! !state initial-state) |
| 61 | + (original-summary m)) |
| 62 | + |
| 63 | +(def ^:private original-pass (get-method t/report (dispatch-value :pass))) |
| 64 | +(defmethod t/report (dispatch-value :pass) [m] |
| 65 | + (report! m {:color gray |
| 66 | + :bullet "✓" |
| 67 | + :bullet-color green}) |
| 68 | + (original-pass m)) |
| 69 | + |
| 70 | +(def ^:private original-fail (get-method t/report (dispatch-value :fail))) |
| 71 | +(defmethod t/report (dispatch-value :fail) [m] |
| 72 | + (let [failure-printout (with-out-str (original-fail m))] |
| 73 | + (swap! !state update :failure-prints conj failure-printout)) |
| 74 | + (report! m {:color red |
| 75 | + :bullet (str (count (:failure-prints @!state)) ")") |
| 76 | + :bullet-color red})) |
| 77 | + |
| 78 | +(def ^:private original-error (get-method t/report (dispatch-value :error))) |
| 79 | +(defmethod t/report (dispatch-value :error) [m] |
| 80 | + (let [error-printout (with-out-str (original-error m))] |
| 81 | + (swap! !state update :failure-prints conj error-printout)) |
| 82 | + (report! m {:color red |
| 83 | + :bullet (str (count (:failure-prints @!state)) ")") |
| 84 | + :bullet-color red})) |
| 85 | + |
| 86 | +(defmethod t/report (dispatch-value :begin-test-var) [m] |
| 87 | + (println (str (indent 1) (default (:var m))))) |
0 commit comments