Konrad Mrożek
2023-09-06 8b8f7606f8f7189315e5582a4bd6cd1118f78583
commit | author | age
b9eb2d 1 (ns test-runner)
919581 2
b9eb2d 3 (def class-cache-dir ".cache/classes")
KM 4 (.mkdirs (java.io.File. class-cache-dir))
919581 5
b9eb2d 6 (defmacro with-class-cache [& body]
KM 7   `(binding [*compile-path*  class-cache-dir
8              *compile-files* true]
9      ~@body))
10
11 (with-class-cache
8b8f76 12   (require '[clojure.test :as t]
KM 13            '[lambdaisland.deep-diff2 :as ddiff]))
919581 14
8b8f76 15 (def no-colors-printer (ddiff/printer {:print-color false}))
55439f 16 (defmulti vim-report :type)
919581 17
55439f 18 (defmethod vim-report :begin-test-ns [m]
KM 19   (println "\nTesting" (ns-name (:ns m))))
20
2f0051 21 (defmethod vim-report :begin-test-var [m]
KM 22   (println "\nExecuting" (:name (meta (:var m)))))
23
55439f 24 (defmethod vim-report :fail
919581 25   [m]
2f8117 26   (t/inc-report-counter :fail)
KM 27   (when-let [source-file (some-> t/*testing-vars*
28                                  first
29                                  meta
30                                  :file)]
31     (println (str "FAIL:" source-file ":" (:line m) ":" (t/testing-vars-str m) ":" (t/testing-contexts-str) ":" (:message m "FAIL")))
32     (println (str "FAIL-CONTINUE:EXPECTED:" (pr-str (:expected m))))
33     (println (str "FAIL-CONTINUE:ACTUAL:" (pr-str (:actual m))))))
04e874 34
8b8f76 35 (defmethod t/assert-expr '= [msg form]
KM 36   (let [args (rest form)
37         pred (first form)]
38     `(let [values# (list ~@args)
39            result# (apply ~pred values#)]
40        (if result#
41          (t/do-report {:type :pass, :message ~msg,
42                        :expected '~form, :actual (cons '~pred values#)})
43          (do
44            (t/do-report {:type :fail, :message ~msg,
45                          :expected '~form, :actual (list '~'not (cons '~pred values#))})
46            (-> (apply ddiff/diff values#)
47                (ddiff/pretty-print no-colors-printer))))
48        result#)))
49
22b826 50 (defn- find-line-number [source-file m]
KM 51   (if (instance? Throwable (:actual m))
52     (let [fname (-> source-file (java.io.File.) (.getName))]
53       (->> m
54            :actual
55            Throwable->map
56            :trace
57            (some (fn [[_ _ e-file e-line]]
58                    (when (= e-file fname)
59                      e-line)))))
60     (:line m)))
61
55439f 62 (defmethod vim-report :error
04e874 63   [m]
2f8117 64   (t/inc-report-counter :error)
04e874 65   (when-let [source-file (some-> t/*testing-vars*
KM 66                                  first
67                                  meta
68                                  :file)]
22b826 69     (let [line (find-line-number source-file m)]
KM 70       (println (str "ERROR:" source-file ":" line ":" (t/testing-vars-str m) ":" (t/testing-contexts-str) ":" (:message m "FAIL")))
71       (println (str "ERROR-CONTINUE:EXPECTED:" (pr-str (:expected m))))
72       (println (str "ERROR-CONTINUE:ACTUAL:"
73                     (if (instance? Throwable (:actual m))
74                       (ex-message (:actual m))
75                       (pr-str (:actual m))))))))
04e874 76
55439f 77 (defmethod vim-report :default
04e874 78   [_])
919581 79
9ae31a 80 (defn- clj-file? [f]
KM 81   (re-matches #"^.*\.cljs?$" (.getName f)))
82
3dde4c 83 (defn find-closest-test [test-file test-line]
KM 84   (->> (all-ns)
85        (mapcat ns-publics)
86        (map second)
87        (filter (comp :test meta))
88        (filter (comp #{test-file} :file meta))
89        (map #(vector % (- test-line (-> % meta :line))))
90        (filterv (comp pos? second))
91        (sort-by second)
92        first
93        first))
94
95 (defn -main [& {:strs [-test-file -test-line] :or {-test-file "test"}}]
b9eb2d 96   (with-class-cache
919581 97     (compile 'test-runner)
9ae31a 98     (println "Detecting test files in" -test-file)
KM 99     (let [test-files (->> -test-file
f5c518 100                           (java.io.File.)
KM 101                           (file-seq)
102                           (filter (memfn isFile))
9ae31a 103                           (filter clj-file?)
f5c518 104                           (map (memfn getAbsolutePath))
KM 105                           (set))]
106       (println "Loading test files...")
107       (run! load-file test-files)
55439f 108       (when (find-ns 'malli.core)
KM 109         (println "Malli detected. Instrument functions...")
110         (require 'malli.dev)
88cddc 111         (require 'malli.dev.pretty)
KM 112         ((find-var 'malli.dev/start!) {:report ((find-var 'malli.dev.pretty/thrower))}))
f5c518 113       (let [test-namespaces (->> (all-ns)
KM 114                                  (mapcat ns-publics)
115                                  (map (comp meta second))
116                                  (filter :test)
117                                  (filter (comp test-files :file))
118                                  (map :ns)
119                                  (set))]
3dde4c 120         (with-redefs [t/report vim-report]
KM 121           (System/exit
122            (if (pos? (if (and -test-file -test-line)
2f8117 123
d93754 124                        (if-let [test-var (find-closest-test (.. (java.io.File. -test-file) getAbsolutePath)
KM 125                                                             (parse-long -test-line))]
126                          (->> (t/run-test-var test-var)
127                               ((juxt :fail :error))
128                               (apply +))
129                          (do
130                            (println "No test found")
131                            0))
3dde4c 132                        (reduce (fn [total-fails n]
KM 133                                  (let [results (t/run-tests n)]
134                                    (+ total-fails
135                                       (:fail results 0)
136                                       (:error results 0))))
137                                0
138                                test-namespaces)))
139              1
140              0)))))))