From 4928715cafe3c8e50b7c9891f488a6f2af3f2362 Mon Sep 17 00:00:00 2001 From: Callum Herries Date: Fri, 10 Nov 2023 16:06:36 +0200 Subject: [PATCH] Replace reader macros with functions --- .../hawk/assert_exprs/approximately_equal.clj | 51 ++++----- .../assert_exprs/approximately_equal_test.clj | 102 +++++++++--------- 2 files changed, 77 insertions(+), 76 deletions(-) diff --git a/src/mb/hawk/assert_exprs/approximately_equal.clj b/src/mb/hawk/assert_exprs/approximately_equal.clj index 1e341e8..7e967de 100644 --- a/src/mb/hawk/assert_exprs/approximately_equal.clj +++ b/src/mb/hawk/assert_exprs/approximately_equal.clj @@ -107,10 +107,11 @@ (deftype Exactly [expected]) -(defn read-exactly - "Data reader for `#hawk/exactly`." - [expected-form] - `(->Exactly ~expected-form)) +(defn exactly + "Used inside a =? expression. Results have to be exactly equal as if by =. Use this to get around the normal way =? + would compare things. This works inside collections as well." + [expected] + (->Exactly expected)) (defmethod print-method Exactly [this writer] @@ -118,26 +119,26 @@ (defmethod print-dup Exactly [^Exactly this ^java.io.Writer writer] - (.write writer (format "#hawk/exactly %s" (pr-str (.expected this))))) + (.write writer (format "(exactly %s)" (pr-str (.expected this))))) (defmethod pprint/simple-dispatch Exactly [^Exactly this] (pprint/pprint-logical-block - :prefix "#hawk/exactly " :suffix nil + :prefix "(exactly " :suffix ")" (pprint/write-out (.expected this)))) (methodical/defmethod =?-diff [Exactly :default] [^Exactly this actual] (let [expected (.expected this)] (when-not (= expected actual) - (list 'not (list '= (symbol "#hawk/exactly") expected actual))))) + (list 'not (list '= (list 'exactly expected) actual))))) (deftype Schema [schema]) -(defn read-schema - "Data reader for `#hawk/schema`." - [schema-form] - `(->Schema ~schema-form)) +(defn schema + "Used inside a =? expression. Compares things to a schema.core schema." + [schema] + (->Schema schema)) (defmethod print-method Schema [this writer] @@ -145,12 +146,12 @@ (defmethod print-dup Schema [^Schema this ^java.io.Writer writer] - (.write writer (format "#hawk/schema %s" (pr-str (.schema this))))) + (.write writer (format "(schema %s)" (pr-str (.schema this))))) (defmethod pprint/simple-dispatch Schema [^Schema this] (pprint/pprint-logical-block - :prefix "#hawk/schema " :suffix nil + :prefix "(malli " :suffix ")" (pprint/write-out (.schema this)))) (methodical/defmethod =?-diff [Schema :default] @@ -159,14 +160,14 @@ (deftype Malli [schema]) -(defn read-malli - "Data reader for `#hawk/malli`." - [schema-form] - `(->Malli ~schema-form)) +(defn malli + "Used inside a =? expression. Compares things to a malli schema." + [schema] + (->Malli schema)) (defmethod print-dup Malli [^Malli this ^java.io.Writer writer] - (.write writer (format "#hawk/malli %s" (pr-str (.schema this))))) + (.write writer (format "(malli %s)" (pr-str (.schema this))))) (defmethod print-method Malli [this writer] @@ -175,7 +176,7 @@ (defmethod pprint/simple-dispatch Malli [^Malli this] (pprint/pprint-logical-block - :prefix "#hawk/malli " :suffix nil + :prefix "(malli " :suffix ")" (pprint/write-out (.schema this)))) (methodical/defmethod =?-diff [Malli :default] @@ -184,11 +185,11 @@ (deftype Approx [expected epsilon]) -(defn read-approx - "Data reader for `#hawk/approx`." +(defn approx + "Used inside a =? expression. Compares whether two numbers are approximately equal." [form] (let [form (eval form) - _ (assert (sequential? form) "Expected #hawk/approx [expected epsilon]") + _ (assert (sequential? form) "Expected (approx [expected epsilon])") [expected epsilon] form] (assert (number? expected)) (assert (number? epsilon)) @@ -200,12 +201,12 @@ (defmethod print-dup Approx [^Approx this ^java.io.Writer writer] - (.write writer (format "#hawk/approx %s" (pr-str [(.expected this) (.epsilon this)])))) + (.write writer (format "(approx %s)" (pr-str [(.expected this) (.epsilon this)])))) (defmethod pprint/simple-dispatch Approx [^Approx this] (pprint/pprint-logical-block - :prefix "#hawk/approx " :suffix nil + :prefix "(approx " :suffix ")" (pprint/write-out [(.expected this) (.epsilon this)]))) (methodical/defmethod =?-diff [Approx Number] @@ -213,4 +214,4 @@ (let [expected (.expected this) epsilon (.epsilon this)] (when-not (algo.generic.math/approx= expected actual epsilon) - (list 'not (list 'approx= expected actual (symbol "#_epsilon") epsilon))))) + (list 'not (list 'approx expected actual (symbol "#_epsilon") epsilon))))) diff --git a/test/mb/hawk/assert_exprs/approximately_equal_test.clj b/test/mb/hawk/assert_exprs/approximately_equal_test.clj index c71ff54..731d136 100644 --- a/test/mb/hawk/assert_exprs/approximately_equal_test.clj +++ b/test/mb/hawk/assert_exprs/approximately_equal_test.clj @@ -3,7 +3,7 @@ [clojure.test :refer :all] [malli.core :as m] [mb.hawk.assert-exprs :as test-runner.assert-exprs] - [mb.hawk.assert-exprs.approximately-equal :as approximately-equal] + [mb.hawk.assert-exprs.approximately-equal :as =?] [schema.core :as s])) (comment test-runner.assert-exprs/keep-me) @@ -43,21 +43,21 @@ [:a 100])) (testing "Should enforce that sequences are of the same length" (is (= [nil nil (list 'not= nil? nil)] - (approximately-equal/=?-diff [int? string? nil?] - [1 "two"]))) + (=?/=?-diff [int? string? nil?] + [1 "two"]))) (is (= [nil nil (list 'not= nil? nil) (list 'not= nil "cans")] - (approximately-equal/=?-diff [int? string? nil?] - [1 "two" nil "cans"]))) + (=?/=?-diff [int? string? nil?] + [1 "two" nil "cans"]))) (testing "Differentiate between [1 2 nil] and [1 2]" ;; these are the same answers [[clojure.data/diff]] would give in these situations. The output is a little more ;; obvious in failing tests because you can see the difference between expected and actual in addition to this ;; diff. (is (= [nil nil nil] - (approximately-equal/=?-diff [1 2 nil] - [1 2]))) + (=?/=?-diff [1 2 nil] + [1 2]))) (is (= [nil nil nil] - (approximately-equal/=?-diff [1 2] - [1 2 nil])))))) + (=?/=?-diff [1 2] + [1 2 nil])))))) (deftest ^:parallel custom-approximately-equal-methods (is (=? {[String java.time.LocalDate] @@ -76,99 +76,99 @@ {:a "abc", :b 100}))) (deftest ^:parallel exactly-test - (testing "#hawk/exactly" + (testing "=?/exactly" (is (=? {:a 1} {:a 1, :b 2})) (testing "Fail when things are not exactly the same, as if by `=`" ;; these serialize the results to strings because it makes it easier to see what the output will look like when ;; printed out which is what we actually care about. - (is (= "(not (= #hawk/exactly {:a 1} {:a 1, :b 2}))" - (pr-str (approximately-equal/=?-diff #hawk/exactly {:a 1} {:a 1, :b 2})))) + (is (= "(not (= (exactly {:a 1}) {:a 1, :b 2}))" + (pr-str (=?/=?-diff (=?/exactly {:a 1}) {:a 1, :b 2})))) (testing "Inside a map" - (is (= "{:b (not (= #hawk/exactly {:a 1} {:a 1, :b 2}))}" - (pr-str (approximately-equal/=?-diff {:a 1, :b #hawk/exactly {:a 1}} - {:a 1, :b {:a 1, :b 2}})))))) + (is (= "{:b (not (= (exactly {:a 1}) {:a 1, :b 2}))}" + (pr-str (=?/=?-diff {:a 1, :b (=?/exactly {:a 1})} + {:a 1, :b {:a 1, :b 2}})))))) (testing "Should pass when things are exactly the same as if by `=`" - (is (nil? (approximately-equal/=?-diff #hawk/exactly 2 2))) - (is (=? #hawk/exactly 2 + (is (nil? (=?/=?-diff (=?/exactly 2) 2))) + (is (=? (=?/exactly 2) 2)) (testing "should evaluate args" - (is (=? #hawk/exactly (+ 1 1) + (is (=? (=?/exactly (+ 1 1)) 2))) (testing "Inside a map" - (is (=? {:a 1, :b #hawk/exactly 2} + (is (=? {:a 1, :b (=?/exactly 2)} {:a 1, :b 2})))))) (deftest ^:parallel schema-test - (testing "#hawk/schema" - (is (=? #hawk/schema {:a s/Int} + (testing "=?/schema" + (is (=? (=?/schema {:a s/Int}) {:a 1})) (testing "Nested inside a collection" - (is (=? {:a 1, :b #hawk/schema {s/Keyword s/Int}} + (is (=? {:a 1, :b (=?/schema {s/Keyword s/Int})} {:a 1, :b {}})) - (is (=? {:a 1, :b #hawk/schema {s/Keyword s/Int}} + (is (=? {:a 1, :b (=?/schema {s/Keyword s/Int})} {:a 1, :b {:c 2}})) - (is (=? {:a 1, :b #hawk/schema {s/Keyword s/Int}} + (is (=? {:a 1, :b (=?/schema {s/Keyword s/Int})} {:a 1, :b {:c 2, :d 3}}))) (testing "failures" ;; serialize these to strings and read them back out because Schema actually returns weird classes like ;; ValidationError or whatever that aren't equal to their printed output (is (= '{:a (not (integer? 1.0))} - (read-string (pr-str (approximately-equal/=?-diff #hawk/schema {:a s/Int} {:a 1.0}))))) + (read-string (pr-str (=?/=?-diff (=?/schema {:a s/Int}) {:a 1.0}))))) (testing "Inside a collection" (is (= '{:b {:c (not (integer? 2.0))}} - (read-string (pr-str (approximately-equal/=?-diff {:a 1, :b #hawk/schema {:c s/Int}} - {:a 1, :b {:c 2.0}}))))))))) + (read-string (pr-str (=?/=?-diff {:a 1, :b (=?/schema {:c s/Int})} + {:a 1, :b {:c 2.0}}))))))))) (deftest ^:parallel malli-test - (testing "#hawk/malli" - (is (=? #hawk/malli [:map [:a :int]] + (testing "=?/malli" + (is (=? (=?/malli [:map [:a :int]]) {:a 1})) (testing "Nested inside a collection" - (is (=? {:a 1, :b #hawk/malli [:map-of :keyword :int]} + (is (=? {:a 1, :b (=?/malli [:map-of :keyword :int])} {:a 1, :b {}})) - (is (=? {:a 1, :b #hawk/malli [:map-of :keyword :int]} + (is (=? {:a 1, :b (=?/malli [:map-of :keyword :int])} {:a 1, :b {:c 2}})) - (is (=? {:a 1, :b #hawk/malli [:map-of :keyword :int]} + (is (=? {:a 1, :b (=?/malli [:map-of :keyword :int])} {:a 1, :b {:c 2, :d 3}}))) (testing "failures" (is (= '{:a ["should be an integer"]} - (read-string (pr-str (approximately-equal/=?-diff #hawk/malli [:map [:a :int]] {:a 1.0}))))) + (read-string (pr-str (=?/=?-diff (=?/malli [:map [:a :int]]) {:a 1.0}))))) (testing "Inside a collection" (is (= '{:b {:c ["should be an integer"]}} - (read-string (pr-str (approximately-equal/=?-diff {:a 1, :b #hawk/malli [:map [:c :int]]} - {:a 1, :b {:c 2.0}}))))))) + (read-string (pr-str (=?/=?-diff {:a 1, :b (=?/malli [:map [:c :int]])} + {:a 1, :b {:c 2.0}}))))))) (testing "Doesn't double evaluate functions (#12)" - (let [schema #hawk/malli [:map [:k map?]]] + (let [schema (=?/malli [:map [:k map?]])] (is (identical? map? (-> (.schema schema) last last)) "Got a double compiled function in schema") (is (m/validate (.schema schema) {:k {}})))))) (deftest ^:parallel approx-test - (testing "#hawk/approx" - (is (=? #hawk/approx [1.5 0.1] + (testing "=?/approx" + (is (=? (=?/approx [1.5 0.1]) 1.51)) (testing "Nested inside a collection" - (is (=? {:a 1, :b #hawk/approx [1.5 0.1]} + (is (=? {:a 1, :b (=?/approx [1.5 0.1])} {:a 1, :b 1.51}))) ;; failures below render stuff to strings so we can see it the way it will look in test failures with its nice ;; comment and whatnot (testing "failures" - (is (= "(not (approx= 1.5 1.6 #_epsilon 0.1))" - (pr-str (approximately-equal/=?-diff #hawk/approx [1.5 0.1] 1.6)))) + (is (= "(not (approx 1.5 1.6 #_epsilon 0.1))" + (pr-str (=?/=?-diff (=?/approx [1.5 0.1]) 1.6)))) (testing "Inside a collection" - (is (= "{:b (not (approx= 1.5 1.6 #_epsilon 0.1))}" - (pr-str (approximately-equal/=?-diff {:a 1, :b #hawk/approx [1.5 0.1]} - {:a 1, :b 1.6})))))) + (is (= "{:b (not (approx 1.5 1.6 #_epsilon 0.1))}" + (pr-str (=?/=?-diff {:a 1, :b (=?/approx [1.5 0.1])} + {:a 1, :b 1.6})))))) (testing "Eval the args" - (is (=? #hawk/approx [(+ 1.0 0.5) (- 1.0 0.9)] + (is (=? (=?/approx [(+ 1.0 0.5) (- 1.0 0.9)]) 1.51))) (testing "A large epsilon" - (is (=? #hawk/approx [1 10.0] + (is (=? (=?/approx [1 10.0]) 9.0)) - (is (= "(not (approx= 1 20.0 #_epsilon 10.0))" - (pr-str (approximately-equal/=?-diff #hawk/approx [1 10.0] 20.0))))) - (testing "nil should not match the #hawk/approx method -- fall back to the :default" - (is (= "(not= #hawk/approx [1 0.1] nil)" - (pr-str (approximately-equal/=?-diff #hawk/approx [1 0.1] nil))))))) + (is (= "(not (approx 1 20.0 #_epsilon 10.0))" + (pr-str (=?/=?-diff (=?/approx [1 10.0]) 20.0))))) + (testing "nil should not match the =?/approx method -- fall back to the :default" + (is (= "(not= (approx [1 0.1]) nil)" + (pr-str (=?/=?-diff (=?/approx [1 0.1]) nil)))))))