├── .dir-locals.el ├── .gitignore ├── .travis.yml ├── .travis ├── lumo-test └── phantom-test ├── README.org ├── deps.edn ├── dev-resources └── public │ └── js │ └── humanize-test-output-test.js ├── project.clj ├── src └── pjstadig │ ├── humane_test_output.clj │ ├── humane_test_output.cljs │ ├── macro.cljc │ ├── print.clj │ ├── print.cljs │ └── util.cljc └── test ├── fixtures ├── test_output └── test_output_cljs └── pjstadig ├── fixtures └── macro.clj ├── humane_test_output ├── formatting_test.cljc ├── records_test.cljc └── reporting_test.cljc ├── run_all.cljs └── run_self_host.cljs /.dir-locals.el: -------------------------------------------------------------------------------- 1 | ((nil 2 | (fill-column . 80) 3 | (whitespace-line-column . nil)) 4 | (clojure-mode 5 | (clojure-test-ns-segment-position . 1) 6 | (eval ignore-errors 7 | (require 'whitespace) 8 | (whitespace-mode 0) 9 | (whitespace-mode 1)))) 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /checkouts/ 2 | /classes/ 3 | /lib/ 4 | /native/ 5 | /target/ 6 | /.lein-deps-sum 7 | /.lein-failures 8 | /.lein-repl-history 9 | /.nrepl-history 10 | /pom.xml 11 | *jar 12 | *.asc 13 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: clojure 2 | 3 | before_install: 4 | - npm install lumo-cljs@1.8.0 -g 5 | 6 | script: 7 | - lein test :yes-i-know-the-tests-are-supposed-to-fail 2>&1 | diff test/fixtures/test_output - 8 | - ./.travis/phantom-test 9 | - ./.travis/lumo-test 10 | -------------------------------------------------------------------------------- /.travis/lumo-test: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | lumo -c $(lein classpath) -i test/pjstadig/run_self_host.cljs -e '(pjstadig.run-self-host/run)' \ 4 | | sed -e 's/(at evalmachine..*)/(:)/' \ 5 | | tail -n +2 \ 6 | | diff test/fixtures/test_output_cljs - 7 | -------------------------------------------------------------------------------- /.travis/phantom-test: -------------------------------------------------------------------------------- 1 | #/usr/bin/env bash 2 | 3 | lein doo phantom test once 2>&1 \ 4 | | grep --invert-match 'TypeError' \ 5 | | grep --invert-match 'Subprocess' \ 6 | | grep --invert-match ';;' \ 7 | | sed -e 's/(cljs\/test\.js.*)/(:)/' \ 8 | | tail -n +4 \ 9 | | diff test/fixtures/test_output_cljs - 10 | -------------------------------------------------------------------------------- /README.org: -------------------------------------------------------------------------------- 1 | #+STARTUP: hidestars showall 2 | * Humane test output for clojure.test 3 | 4 | [[https://clojars.org/pjstadig/humane-test-output][https://clojars.org/pjstadig/humane-test-output/latest-version.svg]] 5 | 6 | This library does two things: 7 | 1. Test output is pretty printed. 8 | 2. Equality assertions are also diffed. 9 | 10 | Version 0.8.0 and later of humane-test-output requires Clojure 1.8.0 or later. 11 | ** IDEs 12 | This test output formatting works great with Emacs and cider 0.10 or lower, 13 | and when running Leiningen in a console. However, some IDEs are also bashing 14 | in their own versions of test formatting. 15 | 16 | I do not recommend using this with cider 0.11.0 or greater or with Cursive, 17 | or LightTable, or any other IDE. 18 | ** Clojure 19 | To activate it you will need to call ~pjstadig.humane-test-output/activate!~. 20 | The preferred way to do this with Leiningen is to use an injection in 21 | the :user profile in your ~/.lein/profiles.clj: 22 | 23 | #+BEGIN_EXAMPLE 24 | {:user {:dependencies [[pjstadig/humane-test-output "0.11.0"]] 25 | :injections [(require 'pjstadig.humane-test-output) 26 | (pjstadig.humane-test-output/activate!)]}} 27 | #+END_EXAMPLE 28 | 29 | If you are on a mixed team and some members need to disable humane test 30 | output, they can define the ~INHUMANE_TEST_OUTPUT~ environment variable, 31 | though again it's better for each user to enable it in their own 32 | ~/.lein/profiles.clj. 33 | 34 | Once humane-test-output is activated, instead of this: 35 | #+BEGIN_EXAMPLE 36 | FAIL in (a-test) (humane_test_output_test.clj:7) 37 | FIXME, I fail. 38 | expected: (= {:foo :bar, :baz :quux, :something "a long string?", :another-key "and another value"} {:fo :bar, :baz :quux, :something "a long string?", :another-key "and another value"}) 39 | actual: (not (= {:another-key "and another value", :foo :bar, :something "a long string?", :baz :quux} {:another-key "and another value", :something "a long string?", :fo :bar, :baz :quux})) 40 | 41 | FAIL in (a-test) (humane_test_output_test.clj:11) 42 | FIXME, I fail. 43 | expected: (= {:foo :bar, :baz :quux} {:foo :bar, :baz :quux} {:fo :bar, :baz :quux}) 44 | actual: (not (= {:foo :bar, :baz :quux} {:foo :bar, :baz :quux} {:fo :bar, :baz :quux})) 45 | FAIL in (a-test) (humane_test_output_test.clj:14) 46 | 47 | FIXME, I fail. 48 | expected: (list? foo) 49 | actual: (not (list? {:another-key "and another value", :foo :bar, :something "a long string?", :baz :quux})) 50 | #+END_EXAMPLE 51 | 52 | You get this: 53 | #+BEGIN_EXAMPLE 54 | FAIL in (a-test) (humane_test_output_test.clj:7) 55 | FIXME, I fail. 56 | expected: {:another-key "and another value", 57 | :foo :bar, 58 | :something "a long string?", 59 | :baz :quux} 60 | actual: {:fo :bar} 61 | diff: - {:baz :quux, 62 | :something "a long string?", 63 | :foo :bar, 64 | :another-key "and another value"} 65 | + {:fo :bar} 66 | 67 | FAIL in (a-test) (humane_test_output_test.clj:10) 68 | FIXME, I fail. 69 | expected: {:foo :bar, :baz :quux} 70 | actual: {:fo :bar, :baz :quux} 71 | diff: - {:foo :bar} 72 | + {:fo :bar} 73 | 74 | FAIL in (a-test) (humane_test_output_test.clj:13) 75 | FIXME, I fail. 76 | expected: (list? foo) 77 | actual: (not 78 | (list? 79 | {:another-key "and another value", 80 | :foo :bar, 81 | :something "a long string?", 82 | :baz :quux})) 83 | #+END_EXAMPLE 84 | 85 | *BONUS FEATURE* 86 | 87 | A test containing ~(is (= oops-i-only-gave-one-argument))~ will throw an 88 | exception. 89 | ** ClojureScript 90 | It is not necessary to activate humane-test-output with ClojureScript, but 91 | the behavior should be much the same as with Clojure. 92 | ** License 93 | #+BEGIN_EXAMPLE 94 | Copyright © Paul Stadig and Outpace Systems, Inc. All rights reserved. 95 | 96 | Some small bits of code were taken from clojure.test and modified, and are 97 | Copyright © Rich Hickey. All rights reserved. 98 | 99 | Distributed under the Eclipse Public License, the same as Clojure. 100 | #+END_EXAMPLE 101 | ** Acknowledgements 102 | I am grateful for design and implementation assistance from Bryce Covert. 103 | 104 | Thanks to Miloslav Nenadál for the ClojureScript implementation. 105 | -------------------------------------------------------------------------------- /deps.edn: -------------------------------------------------------------------------------- 1 | {:aliases {:test {:extra-paths ["test"]}}} 2 | -------------------------------------------------------------------------------- /dev-resources/public/js/humanize-test-output-test.js: -------------------------------------------------------------------------------- 1 | var CLOSURE_UNCOMPILED_DEFINES = {"cljs.core._STAR_target_STAR_":"browser"}; 2 | var CLOSURE_NO_DEPS = true; 3 | if(typeof goog == "undefined") document.write(''); 4 | document.write(''); 5 | document.write(''); 6 | document.write(''); 7 | document.write(''); 8 | document.write(''); 9 | -------------------------------------------------------------------------------- /project.clj: -------------------------------------------------------------------------------- 1 | (defproject pjstadig/humane-test-output "0.12.0-SNAPSHOT" 2 | :description "Humane test output for clojure.test" 3 | :url "http://github.com/pjstadig/humane-test-output/" 4 | :license {:name "Eclipse Public License" 5 | :url "http://www.eclipse.org/legal/epl-v10.html"} 6 | :deploy-repositories [["releases" :clojars]] 7 | :test-selectors 8 | {:default (complement :intentionally-failing) 9 | :yes-i-know-the-tests-are-supposed-to-fail :intentionally-failing} 10 | :profiles {:dev {:dependencies [[org.clojure/clojure "1.8.0"] 11 | [org.clojure/clojurescript "1.10.516"] 12 | [org.seleniumhq.selenium/selenium-java "2.52.0"] 13 | [com.codeborne/phantomjsdriver "1.2.1"]] 14 | :plugins [[lein-cljsbuild "1.1.7"] 15 | [lein-doo "0.1.10"]] 16 | :cljsbuild {:builds [{:id "test" 17 | :source-paths ["src" "test"] 18 | :compiler {:main pjstadig.run-all 19 | :target :browser 20 | :optimizations :none 21 | :output-to "target/js/compiled/humanize-test-output-test.js" 22 | :output-dir "target" 23 | :source-map-timestamp true 24 | :warnings {:private-var-access false}}}]}} 25 | :test {:injections [(require 'pjstadig.humane-test-output) 26 | (pjstadig.humane-test-output/activate!)]}}) 27 | -------------------------------------------------------------------------------- /src/pjstadig/humane_test_output.clj: -------------------------------------------------------------------------------- 1 | (ns pjstadig.humane-test-output 2 | (:use [clojure.test] 3 | [pjstadig.util]) 4 | (:require [clojure.data :as data] 5 | [clojure.pprint :as pp])) 6 | 7 | (defn =-body 8 | [msg a more] 9 | (if (seq more) 10 | `(let [a# (do ~a) 11 | more# (seq (list ~@more)) 12 | result# (apply = a# more#)] 13 | (if result# 14 | (do-report {:type :pass, :message ~msg, 15 | :expected a#, :actual more#}) 16 | (do-report {:type :fail, :message ~msg, 17 | :expected a#, :actual more#, 18 | :diffs (map vector 19 | more# 20 | (map #(take 2 (data/diff a# %)) 21 | more#))})) 22 | result#) 23 | `(throw (Exception. "= expects more than one argument")))) 24 | 25 | (defonce activation-body 26 | (delay 27 | (when (not (System/getenv "INHUMANE_TEST_OUTPUT")) 28 | (defmethod assert-expr '= [msg [_ a & more]] 29 | (=-body msg a more)) 30 | (defmethod assert-expr 'clojure.core/= [msg [_ a & more]] 31 | (=-body msg a more)) 32 | 33 | (define-fail-report) 34 | ;; this code is just yanked from clojure.pprint 35 | (defmethod pp/simple-dispatch clojure.lang.IRecord [arec] 36 | (pprint-record arec)) 37 | (prefer-method pp/simple-dispatch 38 | clojure.lang.IRecord 39 | clojure.lang.IPersistentMap)))) 40 | 41 | (defn activate! [] 42 | @activation-body) 43 | -------------------------------------------------------------------------------- /src/pjstadig/humane_test_output.cljs: -------------------------------------------------------------------------------- 1 | (ns pjstadig.humane-test-output 2 | (:require [cljs.test :refer-macros [run-all-tests run-tests]] 3 | [cljs.pprint :as pp] 4 | [pjstadig.util :as util])) 5 | 6 | (def pprint-map (get-method pp/simple-dispatch :map)) 7 | 8 | (defmethod pp/simple-dispatch :map [amap] 9 | (if (record? amap) 10 | (util/pprint-record amap) 11 | (pprint-map amap))) 12 | 13 | (util/define-fail-report) 14 | -------------------------------------------------------------------------------- /src/pjstadig/macro.cljc: -------------------------------------------------------------------------------- 1 | (ns pjstadig.macro 2 | (:require [clojure.data :as data])) 3 | 4 | (defn diff [& args] 5 | (apply data/diff args)) 6 | -------------------------------------------------------------------------------- /src/pjstadig/print.clj: -------------------------------------------------------------------------------- 1 | (ns pjstadig.print 2 | (:require [clojure.pprint :as pp])) 3 | 4 | (def rprint print) 5 | 6 | (defn clear []) 7 | 8 | (defn with-pretty-writer [f] 9 | (binding [*out* (pp/get-pretty-writer *out*)] 10 | (f))) 11 | -------------------------------------------------------------------------------- /src/pjstadig/print.cljs: -------------------------------------------------------------------------------- 1 | (ns pjstadig.print 2 | (:require [cljs.pprint :as pp :include-macros true] 3 | [pjstadig.macro :as m]) 4 | (:import [goog.string StringBuffer])) 5 | 6 | ;; fix #37 - https://github.com/pjstadig/humane-test-output/issues/37 7 | (defonce ^:private sb (StringBuffer.)) 8 | 9 | (defn rprint [s] 10 | (cljs.core/-write *out* s)) 11 | 12 | (defn clear [] 13 | (*print-fn* (.toString sb)) 14 | (.clear sb)) 15 | 16 | (defn with-pretty-writer [f] 17 | (binding [*out* (pp/get-pretty-writer (StringBufferWriter. sb))] 18 | (f))) 19 | 20 | (defn convert-event [{:keys [actual expected] :as event}] 21 | (let [diffs (when (and (seq? actual) 22 | (seq actual) 23 | (= 'not (first actual)) 24 | (seq? (second actual)) 25 | (seq (second actual)) 26 | (#{'clojure.core/= '= 'cljs.core/=} (first (second actual))) 27 | (< 2 (count (second actual)))) 28 | (let [a (nth (second actual) 1) 29 | more (drop 2 (second actual))] 30 | (map vector 31 | more 32 | (map #(take 2 (m/diff a %)) more)))) 33 | expected (if (seq diffs) 34 | (nth (second actual) 1) 35 | expected)] 36 | (assoc event 37 | :diffs diffs 38 | :expected expected))) 39 | -------------------------------------------------------------------------------- /src/pjstadig/util.cljc: -------------------------------------------------------------------------------- 1 | (ns pjstadig.util 2 | #?(:clj (:use [clojure.test])) 3 | (:require 4 | #?@(:clj [[clojure.pprint :as pp] 5 | [pjstadig.print :as p]] 6 | :cljs [[cljs.pprint :as pp :include-macros true] 7 | [pjstadig.print :as p] 8 | [cljs.test :refer [inc-report-counter! testing-vars-str testing-contexts-str get-current-env]]])) 9 | #?(:cljs (:import [goog.string StringBuffer]))) 10 | 11 | (defn- print-seq [aseq] 12 | (pp/pprint-logical-block 13 | (pp/write-out (ffirst aseq)) 14 | (p/rprint " ") 15 | (pp/pprint-newline :linear) 16 | ;; [pjs] this is kind of ugly, but it is a private var :( 17 | ;; always print both parts of the [k v] pair 18 | #?(:clj (.set #'pp/*current-length* 0) 19 | :cljs (set! pp/*current-length* 0)) 20 | (pp/write-out (fnext (first aseq))))) 21 | 22 | 23 | (defn pprint-record [arec] 24 | (pp/pprint-logical-block 25 | #?@(:clj [:prefix (str "#" (.getName (class arec)) "{") :suffix "}"] 26 | :cljs [:prefix (re-find #".*?\{" (with-out-str (print arec))) :suffix "}"]) 27 | (pp/print-length-loop 28 | [aseq (seq arec)] 29 | (when aseq 30 | (print-seq aseq) 31 | (when (next aseq) 32 | (print ", ") 33 | (pp/pprint-newline :linear) 34 | (recur (next aseq))))))) 35 | 36 | (defn- report- 37 | [{:keys [type expected actual diffs message] :as event}] 38 | #?(:clj (inc-report-counter :fail) 39 | :cljs (inc-report-counter! :fail)) 40 | (println "\nFAIL in" (testing-vars-str event)) 41 | (when #?(:clj (seq *testing-contexts*) 42 | :cljs (:testing-contexts (get-current-env))) 43 | (println (testing-contexts-str))) 44 | (when message (println message)) 45 | (p/with-pretty-writer (fn [] 46 | (let [print-expected (fn [actual] 47 | (p/rprint "expected: ") 48 | (pp/pprint expected *out*) 49 | (p/rprint " actual: ") 50 | (pp/pprint actual *out*) 51 | (p/clear))] 52 | (if (seq diffs) 53 | (doseq [[actual [a b]] diffs] 54 | (print-expected actual) 55 | (when (and (some? expected) (some? actual)) 56 | (do 57 | (p/rprint " diff:") 58 | (if a 59 | (do (p/rprint " - ") 60 | (pp/pprint a *out*) 61 | (p/rprint " + ")) 62 | (p/rprint " + ")) 63 | (when b 64 | (pp/pprint b *out*)) 65 | (p/clear)))) 66 | (print-expected actual)))))) 67 | 68 | (defn define-fail-report [] 69 | #?(:clj (defmethod report :fail [& args] 70 | (with-test-out 71 | (report- (first args)))) 72 | :cljs (defmethod cljs.test/report [:cljs.test/default :fail] 73 | [event] 74 | (report- (p/convert-event event))))) 75 | -------------------------------------------------------------------------------- /test/fixtures/test_output: -------------------------------------------------------------------------------- 1 | 2 | lein test pjstadig.humane-test-output.formatting-test 3 | 4 | lein test :only pjstadig.humane-test-output.formatting-test/non-seq-actual 5 | 6 | FAIL in (non-seq-actual) (:) 7 | expected: 4 8 | actual: 5 9 | 10 | lein test :only pjstadig.humane-test-output.formatting-test/t-formatting 11 | 12 | FAIL in (t-formatting) (formatting_test.cljc:18) 13 | THESE TESTS ARE INTENDED TO FAIL 14 | expected: {:foo :bar, 15 | :baz :quux, 16 | :something "a long string?", 17 | :another-key "and another value"} 18 | actual: {:fo :bar} 19 | diff: - {:foo :bar, 20 | :baz :quux, 21 | :something "a long string?", 22 | :another-key "and another value"} 23 | + {:fo :bar} 24 | 25 | lein test :only pjstadig.humane-test-output.formatting-test/t-formatting 26 | 27 | FAIL in (t-formatting) (formatting_test.cljc:21) 28 | THESE TESTS ARE INTENDED TO FAIL 29 | expected: {:foo :bar, 30 | :baz :quux, 31 | :something "a long string?", 32 | :another-key "and another value"} 33 | actual: {:foo :bar} 34 | diff: - {:baz :quux, 35 | :something "a long string?", 36 | :another-key "and another value"} 37 | 38 | lein test :only pjstadig.humane-test-output.formatting-test/t-formatting 39 | 40 | FAIL in (t-formatting) (formatting_test.cljc:24) 41 | THESE TESTS ARE INTENDED TO FAIL 42 | expected: {:foo :bar} 43 | actual: {:foo :bar, 44 | :baz :quux, 45 | :something "a long string?", 46 | :another-key "and another value"} 47 | diff: + {:baz :quux, 48 | :something "a long string?", 49 | :another-key "and another value"} 50 | 51 | lein test :only pjstadig.humane-test-output.formatting-test/t-formatting 52 | 53 | FAIL in (t-formatting) (formatting_test.cljc:27) 54 | THESE TESTS ARE INTENDED TO FAIL 55 | expected: {:foo :bar, :baz :quux} 56 | actual: {:foo :bar, :baz :quux} 57 | diff: + expected: {:foo :bar, :baz :quux} 58 | actual: {:fo :bar, :baz :quux} 59 | diff: - {:foo :bar} 60 | + {:fo :bar} 61 | expected: {:foo :bar, :baz :quux} 62 | actual: {:fo :bar, :baz :quux} 63 | diff: - {:foo :bar} 64 | + {:fo :bar} 65 | 66 | lein test :only pjstadig.humane-test-output.formatting-test/t-formatting 67 | 68 | FAIL in (t-formatting) (formatting_test.cljc:31) 69 | THESE TESTS ARE INTENDED TO FAIL 70 | expected: (list? foo) 71 | actual: (not 72 | (list? 73 | {:foo :bar, 74 | :baz :quux, 75 | :something "a long string?", 76 | :another-key "and another value"})) 77 | 78 | lein test :only pjstadig.humane-test-output.formatting-test/t-formatting 79 | 80 | FAIL in (t-formatting) (formatting_test.cljc:32) 81 | THESE TESTS ARE INTENDED TO FAIL 82 | expected: {:foo :bar} 83 | actual: nil 84 | 85 | lein test :only pjstadig.humane-test-output.formatting-test/t-macro-wrapping 86 | 87 | FAIL in (t-macro-wrapping) (formatting_test.cljc:35) 88 | THIS ONE SHOULD ALSO FAIL 89 | expected: 1 90 | actual: 2 91 | diff: - 1 92 | + 2 93 | 94 | lein test pjstadig.humane-test-output.records-test 95 | 96 | lein test :only pjstadig.humane-test-output.records-test/t-records 97 | 98 | FAIL in (t-records) (records_test.cljc:10) 99 | THESE TESTS ARE INTENDED TO FAIL these should not print as plain maps 100 | expected: #pjstadig.humane_test_output.records_test.ARecord{:foo :foo} 101 | actual: #pjstadig.humane_test_output.records_test.ARecord{:foo :bar} 102 | diff: - {:foo :foo} 103 | + {:foo :bar} 104 | 105 | lein test :only pjstadig.humane-test-output.records-test/t-records 106 | 107 | FAIL in (t-records) (records_test.cljc:12) 108 | THESE TESTS ARE INTENDED TO FAIL there should be a diff here 109 | expected: #pjstadig.humane_test_output.records_test.ARecord{:foo :foo} 110 | actual: {:foo :foo} 111 | 112 | lein test :only pjstadig.humane-test-output.records-test/t-records 113 | 114 | FAIL in (t-records) (records_test.cljc:14) 115 | THESE TESTS ARE INTENDED TO FAIL and here 116 | expected: #pjstadig.humane_test_output.records_test.ARecord{:foo :foo} 117 | actual: #pjstadig.humane_test_output.records_test.BRecord{:foo :foo} 118 | 119 | Ran 4 tests containing 11 assertions. 120 | 11 failures, 0 errors. 121 | Tests failed. 122 | -------------------------------------------------------------------------------- /test/fixtures/test_output_cljs: -------------------------------------------------------------------------------- 1 | Testing pjstadig.humane-test-output.formatting-test 2 | 3 | FAIL in (t-formatting) (:) 4 | THESE TESTS ARE INTENDED TO FAIL 5 | expected: {:foo :bar, 6 | :baz :quux, 7 | :something "a long string?", 8 | :another-key "and another value"} 9 | actual: {:fo :bar} 10 | 11 | diff: - {:foo :bar, 12 | :baz :quux, 13 | :something "a long string?", 14 | :another-key "and another value"} 15 | + {:fo :bar} 16 | 17 | 18 | FAIL in (t-formatting) (:) 19 | THESE TESTS ARE INTENDED TO FAIL 20 | expected: {:foo :bar, 21 | :baz :quux, 22 | :something "a long string?", 23 | :another-key "and another value"} 24 | actual: {:foo :bar} 25 | 26 | diff: - {:baz :quux, 27 | :something "a long string?", 28 | :another-key "and another value"} 29 | 30 | 31 | FAIL in (t-formatting) (:) 32 | THESE TESTS ARE INTENDED TO FAIL 33 | expected: {:foo :bar} 34 | actual: {:foo :bar, 35 | :baz :quux, 36 | :something "a long string?", 37 | :another-key "and another value"} 38 | 39 | diff: + {:baz :quux, 40 | :something "a long string?", 41 | :another-key "and another value"} 42 | 43 | 44 | FAIL in (t-formatting) (:) 45 | THESE TESTS ARE INTENDED TO FAIL 46 | expected: {:foo :bar, :baz :quux} 47 | actual: {:foo :bar, :baz :quux} 48 | 49 | 50 | diff: + expected: {:foo :bar, :baz :quux} 51 | actual: {:fo :bar, :baz :quux} 52 | 53 | diff: - {:foo :bar} 54 | + {:fo :bar} 55 | 56 | expected: {:foo :bar, :baz :quux} 57 | actual: {:fo :bar, :baz :quux} 58 | 59 | diff: - {:foo :bar} 60 | + {:fo :bar} 61 | 62 | 63 | FAIL in (t-formatting) (:) 64 | THESE TESTS ARE INTENDED TO FAIL 65 | expected: (list? foo) 66 | actual: (not 67 | (list? 68 | {:foo :bar, 69 | :baz :quux, 70 | :something "a long string?", 71 | :another-key "and another value"})) 72 | 73 | 74 | FAIL in (t-formatting) (:) 75 | THESE TESTS ARE INTENDED TO FAIL 76 | expected: {:foo :bar} 77 | actual: nil 78 | 79 | 80 | FAIL in (t-macro-wrapping) (:) 81 | 82 | THIS ONE SHOULD ALSO FAIL 83 | expected: 1 84 | actual: 2 85 | 86 | diff: - 1 87 | + 2 88 | 89 | 90 | Testing pjstadig.humane-test-output.records-test 91 | 92 | FAIL in (t-records) (:) 93 | THESE TESTS ARE INTENDED TO FAIL these should not print as plain maps 94 | expected: #pjstadig.humane-test-output.records-test.ARecord{:foo :foo} 95 | actual: #pjstadig.humane-test-output.records-test.ARecord{:foo :bar} 96 | 97 | diff: - {:foo :foo} 98 | + {:foo :bar} 99 | 100 | 101 | FAIL in (t-records) (:) 102 | THESE TESTS ARE INTENDED TO FAIL there should be a diff here 103 | expected: #pjstadig.humane-test-output.records-test.ARecord{:foo :foo} 104 | actual: {:foo :foo} 105 | 106 | 107 | 108 | FAIL in (t-records) (:) 109 | THESE TESTS ARE INTENDED TO FAIL and here 110 | expected: #pjstadig.humane-test-output.records-test.ARecord{:foo :foo} 111 | actual: #pjstadig.humane-test-output.records-test.BRecord{:foo :foo} 112 | 113 | 114 | 115 | Testing pjstadig.humane-test-output.reporting-test 116 | 117 | FAIL in (cljs-smoke-test) (:) 118 | 119 | this is a smoke test 120 | expected: {:map "srt"} 121 | actual: {:map 1} 122 | 123 | diff: - {:map "srt"} 124 | + {:map 1} 125 | 126 | 127 | Ran 5 tests containing 14 assertions. 128 | 11 failures, 0 errors. 129 | -------------------------------------------------------------------------------- /test/pjstadig/fixtures/macro.clj: -------------------------------------------------------------------------------- 1 | (ns pjstadig.fixtures.macro) 2 | 3 | (defmacro deftest+ 4 | [test-name expected actual] 5 | `(~'deftest ~test-name 6 | (~'is (= ~expected ~actual) "THIS ONE SHOULD ALSO FAIL"))) 7 | 8 | -------------------------------------------------------------------------------- /test/pjstadig/humane_test_output/formatting_test.cljc: -------------------------------------------------------------------------------- 1 | (ns pjstadig.humane-test-output.formatting-test 2 | #?(:clj (:use [clojure.test] 3 | [pjstadig.fixtures.macro]) 4 | :cljs (:require-macros [cljs.test :refer [deftest testing is]] 5 | [pjstadig.fixtures.macro :refer [deftest+]]))) 6 | 7 | (deftest t-nothing-to-see-here 8 | (is true "everything should be A-OK") 9 | (is (= :clojure.spec.alpha/invalid 10 | :clojure.spec.alpha/invalid) 11 | "everything should be A-OK") 12 | (is (= :clojure.spec/invalid 13 | :clojure.spec/invalid) 14 | "everything should be A-OK")) 15 | 16 | (deftest ^:intentionally-failing t-formatting 17 | (testing "THESE TESTS ARE INTENDED TO FAIL" 18 | (is (= {:foo :bar :baz :quux :something "a long string?" 19 | :another-key "and another value"} 20 | {:fo :bar})) 21 | (is (= {:foo :bar :baz :quux :something "a long string?" 22 | :another-key "and another value"} 23 | {:foo :bar})) 24 | (is (= {:foo :bar} 25 | {:foo :bar :baz :quux :something "a long string?" 26 | :another-key "and another value"})) 27 | (is (= {:foo :bar :baz :quux} {:foo :bar :baz :quux} {:fo :bar :baz :quux} 28 | {:fo :bar :baz :quux})) 29 | (let [foo {:foo :bar :baz :quux :something "a long string?" 30 | :another-key "and another value"}] 31 | (is (list? foo))) 32 | (is (= {:foo :bar} 33 | nil)))) 34 | 35 | (deftest+ ^:intentionally-failing t-macro-wrapping 1 2) 36 | 37 | #?(:clj (deftest ^:intentionally-failing non-seq-actual 38 | (clojure.test/report {:type :fail :expected 4 :actual 5} ))) 39 | -------------------------------------------------------------------------------- /test/pjstadig/humane_test_output/records_test.cljc: -------------------------------------------------------------------------------- 1 | (ns pjstadig.humane-test-output.records-test 2 | (:require [clojure.test #?(:clj :refer :cljs :refer-macros) [deftest testing is]])) 3 | 4 | (defrecord ARecord [foo]) 5 | (defrecord BRecord [foo]) 6 | 7 | (deftest ^:intentionally-failing t-records 8 | (testing "THESE TESTS ARE INTENDED TO FAIL" 9 | (testing "these should not print as plain maps" 10 | (is (= (->ARecord :foo) (->ARecord :bar)))) 11 | (testing "there should be a diff here" 12 | (is (= (->ARecord :foo) {:foo :foo}))) 13 | (testing "and here" 14 | (is (= (->ARecord :foo) (->BRecord :foo)))))) 15 | -------------------------------------------------------------------------------- /test/pjstadig/humane_test_output/reporting_test.cljc: -------------------------------------------------------------------------------- 1 | (ns pjstadig.humane-test-output.reporting-test 2 | (:require [cljs.test #?(:clj :refer :cljs :refer-macros) [deftest]] 3 | #?@(:cljs [[pjstadig.util] 4 | [pjstadig.print :as p]]))) 5 | 6 | #?(:cljs 7 | (def report #'pjstadig.util/report-)) 8 | 9 | #?(:cljs 10 | (deftest cljs-smoke-test 11 | (report (p/convert-event {:type :fail 12 | :expected '(= {:map "srt"} {:map 1}) 13 | :actual '(not (= {:map "srt"} {:map 1})) 14 | :message "this is a smoke test"})))) 15 | -------------------------------------------------------------------------------- /test/pjstadig/run_all.cljs: -------------------------------------------------------------------------------- 1 | (ns pjstadig.run-all 2 | (:require [doo.runner :as doo :include-macros true] 3 | [pjstadig.humane-test-output] 4 | [pjstadig.humane-test-output.formatting-test] 5 | [pjstadig.humane-test-output.records-test] 6 | [pjstadig.humane-test-output.reporting-test])) 7 | 8 | (enable-console-print!) 9 | 10 | (doo/doo-all-tests #"pjstadig.*-test") 11 | -------------------------------------------------------------------------------- /test/pjstadig/run_self_host.cljs: -------------------------------------------------------------------------------- 1 | (ns pjstadig.run-self-host 2 | (:require [cljs.test :refer-macros [run-all-tests]] 3 | [pjstadig.humane-test-output] 4 | [pjstadig.humane-test-output.formatting-test] 5 | [pjstadig.humane-test-output.records-test] 6 | [pjstadig.humane-test-output.reporting-test])) 7 | 8 | (enable-console-print!) 9 | 10 | (defn ^:export run [] 11 | (run-all-tests #"pjstadig.*-test")) 12 | --------------------------------------------------------------------------------