diff --git a/eftest/project.clj b/eftest/project.clj index 7222d23..63c2204 100644 --- a/eftest/project.clj +++ b/eftest/project.clj @@ -7,7 +7,8 @@ [org.clojure/tools.namespace "1.3.0"] [progrock "0.1.2"] [io.aviso/pretty "1.3"] - [mvxcvi/puget "1.3.4"]] + [mvxcvi/puget "1.3.4"] + [juji/editscript "0.6.2"]] :plugins [[lein-eftest "0.6.0"]] :aliases {"test-all" ["with-profile" "default:+1.8:+1.9:+1.10:+1.11" "eftest"]} diff --git a/eftest/src/eftest/report/pretty.clj b/eftest/src/eftest/report/pretty.clj index 3f02273..a361e49 100644 --- a/eftest/src/eftest/report/pretty.clj +++ b/eftest/src/eftest/report/pretty.clj @@ -52,6 +52,11 @@ (puget/pretty-printer {:print-color true :print-meta false})) +(defn- pretty-printer-unsorted-key [] + (puget/pretty-printer {:print-color true + :print-meta false + :sort-keys false})) + (defn- pprint-document [doc] (fipp/pprint-document doc {:width 80})) @@ -72,6 +77,15 @@ (if a " + " "+ ") (puget/format-doc p b)])])])))) +(defn- editscript-equals-fail-report [{:keys [expected actual diffs]}] + (let [p (pretty-printer-unsorted-key)] + (pprint-document + [:group + [:span "expected: " (puget/format-doc p expected) :break] + [:span " actual: " (puget/format-doc p actual) :break] + [:span " diff: " (puget/format-doc p diffs)] + ]))) + (defn- predicate-fail-report [{:keys [expected actual]}] (let [p (pretty-printer)] (pprint-document @@ -124,6 +138,17 @@ (predicate-fail-report m)) (print-output (capture/read-test-buffer)))) +(defmethod report :fail-with-diffs [{:keys [message expected] :as m}] + (test/with-test-out + (test/inc-report-counter :fail) + (print *divider*) + (println (str (:fail *fonts*) "FAIL" (:reset *fonts*) " in") (testing-scope-str m)) + (when (seq test/*testing-contexts*) (println (test/testing-contexts-str))) + (when message (println message)) + (when (= (first expected) 'e=) + (editscript-equals-fail-report m)) + (print-output (capture/read-test-buffer)))) + (defmethod report :error [{:keys [message expected actual] :as m}] (test/with-test-out (test/inc-report-counter :error) diff --git a/eftest/src/eftest/report/progress.clj b/eftest/src/eftest/report/progress.clj index d1981d4..49122b0 100644 --- a/eftest/src/eftest/report/progress.clj +++ b/eftest/src/eftest/report/progress.clj @@ -48,6 +48,13 @@ (newline) (print-progress (swap! report/*context* update-in [:state] set-state :fail)))) +(defmethod report :fail-with-diffs [m] + (test/with-test-out + (print clear-line) + (binding [pretty/*divider* "\r"] (pretty/report m)) + (newline) + (print-progress (swap! report/*context* update-in [:state] set-state :fail)))) + (defmethod report :error [m] (test/with-test-out (print clear-line) diff --git a/eftest/src/eftest/runner.clj b/eftest/src/eftest/runner.clj index d67c32b..f2637b5 100644 --- a/eftest/src/eftest/runner.clj +++ b/eftest/src/eftest/runner.clj @@ -3,6 +3,7 @@ (:require [clojure.java.io :as io] [clojure.test :as test] [clojure.tools.namespace.find :as find] + [editscript.core :as editscript] [eftest.report :as report] [eftest.report.progress :as progress] [eftest.output-capture :as capture]) @@ -178,6 +179,40 @@ (defmethod find-tests java.lang.String [dir] (find-tests-in-dir (io/file dir))) +(defn e= [exp act] + (let [d (editscript/diff exp act {:algo :quick})] + (= 0 (editscript/edit-distance d)))) + +(defn- make-diff [exp act [path & _]] + {:path path + :exp (get-in exp path) + :act (get-in act path)}) + +(defn make-diffs [exp act] + (let [d (editscript/diff exp act) + es (editscript/get-edits d)] + (map #(make-diff exp act %) es))) + +(defmethod clojure.test/assert-expr 'e= [msg form] + (let [args (rest form) + pred (first form)] + `(let [values# (list ~@args) + result# (apply ~pred values#)] + (if result# + (clojure.test/do-report { + :type :pass + :message ~msg + :expected '~form + :actual (cons ~pred values#)}) + (let [diffs# (apply make-diffs values#)] + (clojure.test/do-report { + :type :fail-with-diffs + :message ~msg + :expected '~form + :actual (list '~'not (cons '~pred values#)) + :diffs diffs#}))) + result#))) + (defn run-tests "Run the supplied test vars. Accepts the following options: diff --git a/eftest/test/eftest/runner_test.clj b/eftest/test/eftest/runner_test.clj index 69df98d..194c1ff 100644 --- a/eftest/test/eftest/runner_test.clj +++ b/eftest/test/eftest/runner_test.clj @@ -1,6 +1,6 @@ (ns eftest.runner-test (:require [clojure.test :refer :all] - [eftest.runner :as sut])) + [eftest.runner :as sut :refer [e=]])) (in-ns 'eftest.test-ns.single-failing-test) (clojure.core/refer-clojure) @@ -8,6 +8,21 @@ (clojure.test/deftest single-failing-test (clojure.test/is (= 1 2))) +(in-ns 'eftest.test-ns.editscript-failing-test) +(clojure.core/refer-clojure) +(clojure.core/require 'clojure.test) +(clojure.core/require '[eftest.runner :refer [e=]]) +(clojure.test/deftest editscript-failing-test + (clojure.test/is (e= 1 2))) + +(in-ns 'eftest.test-ns.editscript-failing-complex-test) +(clojure.core/refer-clojure) +(clojure.core/require 'clojure.test) +(clojure.core/require '[eftest.runner :refer [e=]]) +(clojure.test/deftest editscript-failing-complex-test + (clojure.test/is (e= {:a 1 :b [1 2 3] :c {:a 1}} + {:a 2 :b [2 3 4] :c {:a 2}}))) + (in-ns 'eftest.test-ns.another-failing-test) (clojure.core/refer-clojure) (clojure.core/require 'clojure.test) @@ -48,6 +63,18 @@ (is (re-find #"FAIL in eftest.test-ns.single-failing-test/single-failing-test" out)) (is (not (re-find #"IllegalArgumentException" out))))) +(deftest test-editscript-failing + (let [out (:output (test-run-tests 'eftest.test-ns.editscript-failing-test))] + (is (re-find #"FAIL in eftest.test-ns.editscript-failing-test/editscript-failing-test" out)) + (is (re-find #"diff" out)) + (is (not (re-find #"IllegalArgumentException" out))))) + +(deftest test-editscript-failing-complex + (let [out (:output (test-run-tests 'eftest.test-ns.editscript-failing-complex-test))] + (is (re-find #"FAIL in eftest.test-ns.editscript-failing-complex-test/editscript-failing-complex-test" out)) + (is (re-find #"diff" out)) + (is (not (re-find #"IllegalArgumentException" out))))) + (deftest test-fail-fast (let [result (:return (test-run-tests