Add lib tests for expectations.clojure-test

This commit is contained in:
Michiel Borkent 2022-03-12 14:40:52 +01:00
parent 315d58e7a1
commit 6320cddc74
4 changed files with 184 additions and 1 deletions

View file

@ -128,7 +128,8 @@
clojure-msgpack/clojure-msgpack {:mvn/version "1.2.1"}
cli-matic/cli-matic {:git/url "https://github.com/l3nz/cli-matic.git", :git/sha "9cd53ba7336363e3d06650dbad413b6f8b06e471"}
aysylu/loom {:mvn/version "1.0.2"}
com.layerware/hugsql-core {:mvn/version "0.5.1"}}
com.layerware/hugsql-core {:mvn/version "0.5.1"}
com.github.seancorfield/expectations {:mvn/version "2.0.157"}}
:classpath-overrides {org.clojure/clojure nil
org.clojure/spec.alpha nil}}
:clj-nvd

View file

@ -17,8 +17,10 @@ clojure-csv/clojure-csv,https://github.com/davidsantiago/clojure-csv
clojure-msgpack/clojure-msgpack,https://github.com/edma2/clojure-msgpack
clojure-term-colors/clojure-term-colors,https://github.com/trhura/clojure-term-colors
com.exoscale/lingo,https://github.com/exoscale/lingo
com.github.seancorfield/expectations,https://github.com/clojure-expectations/clojure-test
com.github.seancorfield/honeysql,https://github.com/seancorfield/honeysql
com.grammarly/omniconf,https://github.com/grammarly/omniconf
com.layerware/hugsql-core,
com.stuartsierra/component,https://github.com/stuartsierra/component
com.stuartsierra/dependency,https://github.com/stuartsierra/dependency
com.wsscode/cljc-misc,https://github.com/wilkerlucio/cljc-misc

1 maven-name git-url
17 clojure-msgpack/clojure-msgpack https://github.com/edma2/clojure-msgpack
18 clojure-term-colors/clojure-term-colors https://github.com/trhura/clojure-term-colors
19 com.exoscale/lingo https://github.com/exoscale/lingo
20 com.github.seancorfield/expectations https://github.com/clojure-expectations/clojure-test
21 com.github.seancorfield/honeysql https://github.com/seancorfield/honeysql
22 com.grammarly/omniconf https://github.com/grammarly/omniconf
23 com.layerware/hugsql-core
24 com.stuartsierra/component https://github.com/stuartsierra/component
25 com.stuartsierra/dependency https://github.com/stuartsierra/dependency
26 com.wsscode/cljc-misc https://github.com/wilkerlucio/cljc-misc

View file

@ -110,4 +110,5 @@
cli-matic/cli-matic {:git-url "https://github.com/l3nz/cli-matic.git", :test-namespaces (cli-matic.utils-test cli-matic.presets-test cli-matic.help-gen-test cli-matic.utils-convert-config-test cli-matic.utils-candidates-test cli-matic.core-test cli-matic.utils-v2-test), :git-sha "9cd53ba7336363e3d06650dbad413b6f8b06e471"}
aysylu/loom {:git-url "https://github.com/aysylu/loom", :test-namespaces (loom.test.network-simplex loom.test.label loom.test.alg-generic loom.test.compliance-tester loom.test.flow loom.test.alg loom.test.attr loom.test.graph loom.test.derived), :git-sha "d458f0c0dee9021983c64381b90a470f0178cc8e"}
com.layerware/hugsql-core {:test-namespaces (hugsql.babashka-test)}
com.github.seancorfield/expectations {:git-url "https://github.com/clojure-expectations/clojure-test", :test-namespaces (expectations.clojure.test-test), :git-sha "b30fefd97d9eb7d1f47e06956521f354cb926b03"}
}

View file

@ -0,0 +1,179 @@
;; copyright (c) 2019-2020 sean corfield, all rights reserved
(ns expectations.clojure.test-test
"Test the testing framework -- this is sometimes harder than you might think!
Tests marked `^:negative` will not pass with Humane Test Output enabled
because it manipulates the report data which my `is-not` macros rely on."
(:require [clojure.string :as str]
[clojure.test :refer [deftest is do-report testing]]
[expectations.clojure.test :as sut
;; refer these purely to help clj-kondo:
:refer [from-each in more more-of]]))
(defmacro is-not'
"Construct a negative test for an expectation with a symbolic failure."
[expectation failure & [msg]]
`(let [results# (atom nil)]
(with-redefs [do-report (sut/all-report results#)]
~expectation)
(is (some (fn [fail#]
(= '~failure (:actual fail#)))
(:fail @results#)))
(when ~msg
(is (some (fn [fail#]
(re-find ~msg (:message fail#)))
(:fail @results#))))))
(defmacro is-not
"Construct a negative test for an expectation with a value-based failure."
[expectation failure & [msg]]
`(let [results# (atom nil)]
(with-redefs [do-report (sut/all-report results#)]
~expectation)
(is (some (fn [fail#]
(= ~failure (:actual fail#)))
(:fail @results#)))
(when ~msg
(is (some (fn [fail#]
(re-find ~msg (:message fail#)))
(:fail @results#))))))
(defmacro passes
"Construct a positive test for an expectation with a predicate-based success.
This is needed for cases where a successful test wraps a failing behavior,
such as `thrown?`, i.e., `(expect ExceptionType actual)`"
[expectation success]
`(let [results# (atom nil)]
(with-redefs [do-report (sut/all-report results#)]
~expectation)
(is (some (fn [pass#]
(~success (:actual pass#)))
(:pass @results#)))))
(deftest predicate-test
(is (sut/expect even? (+ 1 1)))
(is (sut/expect empty? (list)))
(is-not' (sut/expect even? (+ 1 1 1)) (not (even? 3)))
(is-not' (sut/expect empty? [1]) (not (empty? [1]))))
(deftest equality-test
(is (sut/expect 1 (* 1 1)))
(is (sut/expect "foo" (str "f" "oo"))))
(deftest ^:negative not-equality-test
(is-not' (sut/expect 2 (* 1 1)) (not (=? 2 1)))
(is-not' (sut/expect "fool" (str "f" "oo")) (not (=? "fool" "foo"))))
(deftest ^:negative message-test
(is-not' (sut/expect even? (+ 1 1 1) "It's uneven!")
(not (even? 3))
#"uneven")
(is-not' (sut/expect empty? [1] "It's partly full!")
(not (empty? [1]))
#"full")
(is-not' (sut/expect 2 (* 1 1) "One times one isn't two?")
(not (=? 2 1))
#"isn't two")
(is-not' (sut/expect "fool" (str "f" "oo") "No fooling around!")
(not (=? "fool" "foo"))
#"fooling"))
(deftest regex-test
(is (sut/expect #"foo" "It's foobar!"))
;; TODO: fails because regexes never compare equal to themselves!
#_(is-not' (sut/expect #"fool" "It's foobar!") (not (re-find #"fool" "It's foobar!"))))
(deftest exception-test
(passes (sut/expect ArithmeticException (/ 12 0))
(fn [ex]
(let [t (Throwable->map ex)]
(and (= "Divide by zero" (-> t :cause))
(or (= 'java.lang.ArithmeticException (-> t :via first :type))
(= java.lang.ArithmeticException (-> t :via first :type))))))))
(deftest class-test
(is (sut/expect String (name :foo)))
(is-not (sut/expect String :foo) clojure.lang.Keyword))
(try
(eval '(do
(require '[clojure.spec.alpha :as s])
(s/def :small/value (s/and pos-int? #(< % 100)))
(deftest spec-test
(is (sut/expect :small/value (* 13 4)))
(is-not' (sut/expect :small/value (* 13 40)) (not (=? :small/value 520))))))
(catch Throwable _
(println "\nOmitting Spec tests for Clojure" (clojure-version))))
(deftest collection-test
(is (sut/expect {:foo 1} (in {:foo 1 :cat 4})))
;; TODO: need better tests here
(is (nil? (sut/expect :foo (in #{:foo :bar}))))
(is (nil? (sut/expect :foo (in [:bar :foo])))))
(deftest ^:negative not-collection-test
(is-not' (sut/expect {:foo 1} (in {:foo 2 :cat 4})) (not (=? {:foo 1} {:foo 2}))))
;; TODO: need better tests here
(deftest grouping-more-more-of-from-each
(sut/expecting "numeric behavior"
(sut/expect (more-of {:keys [a b]}
even? a
odd? b)
{:a (* 2 13) :b (* 3 13)})
(sut/expect pos? (* -3 -5)))
(sut/expecting "string behavior"
(sut/expect (more #"foo" "foobar" #(str/starts-with? % "f"))
(str "f" "oobar"))
(sut/expect #"foo"
(from-each [s ["l" "d" "bar"]]
(str "foo" s)))))
(defn- dummy1 [x] (throw (ex-info "called dummy1" {:x x})))
(defn- dummy2 [x] (throw (ex-info "called dummy2" {:x x})))
(deftest side-effect-testing
(testing "No side effects"
(is (= [] (sut/side-effects [dummy1 [dummy2 42]] (+ 1 1)))))
(testing "Basic side effects"
(is (= [[2]]
(sut/side-effects [dummy1 [dummy2 42]] (dummy1 (+ 1 1)))))
(is (= [[2]]
(sut/side-effects [dummy1 [dummy2 42]] (dummy2 (+ 1 1))))))
(testing "Mocked return values"
(is (= [[2] [42]]
(sut/side-effects [dummy1 [dummy2 42]] (dummy1 (dummy2 (+ 1 1))))))
(is (= [[2] [nil]]
(sut/side-effects [dummy1 [dummy2 42]] (dummy2 (dummy1 (+ 1 1))))))))
(def d-t-counter (atom 0))
(sut/with-test
(defn definition-test
"Make sure expectations work with clojure.test/with-test."
[a b c]
(swap! d-t-counter inc)
(* a b c))
(println "\nRunning inline tests")
(reset! d-t-counter 0)
(is (= 0 @d-t-counter))
(sut/expect 1 (definition-test 1 1 1))
(sut/expect 6 (definition-test 1 2 3))
(is (= 2 @d-t-counter)))
;; these would be failing tests in 1.x but not in 2.x:
(sut/defexpect deftest-equivalence-0)
(sut/defexpect deftest-equivalence-1 nil)
(def ^:private control (atom 0))
;; this will succeed on its own
(sut/defexpect control-test-1 zero? @control)
;; then retest with a different control value
(deftest control-test-2
(try
(reset! control 1)
(is-not' (control-test-1) (not (zero? 1)))
(finally
(reset! control 0))))