Skip to content

Commit

Permalink
fix match-with for cljs (#203)
Browse files Browse the repository at this point in the history
* fix match-with for cljs
  • Loading branch information
philomates authored Jul 18, 2023
1 parent f6c6ed6 commit ccd2099
Show file tree
Hide file tree
Showing 8 changed files with 126 additions and 13 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ change log follows the conventions of
## 3.8.6 / unreleased
- fix issue when using non-composite matchers (`m/regex`, `m/pred`, etc)
inside `match-with`.
- fix issue where `match-with` misbehaves in ClojureScript

## 3.8.5 / 2023-03-24
- fix clj-kondo lint warnings for `match?` in Clojurescript
Expand Down
4 changes: 4 additions & 0 deletions bb.edn
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
{:doc "Starts a nREPL"
:task (apply clojure "-Adev -Sdeps '{:deps {cider/cider-nrepl {:mvn/version \"0.29.0\"}}}' -m nrepl.cmdline --middleware \"[cider.nrepl/cider-middleware]\"" *command-line-args*)}

dev:cljs
{:doc "Starts a ClojureScript nREPL"
:task (apply clojure "-M:cljs-test node-repl" *command-line-args*)}

test:clj
{:doc "run Clojure clojure.test tests"
:task (apply clojure "-A:dev:clj-test:test-runner" *command-line-args*)}
Expand Down
2 changes: 1 addition & 1 deletion src/cljc/matcher_combinators/matchers.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@
[& matchers]
(core/->AllOf matchers))

#?(:cljs (defn- cljs-uri [expected]
#?(:cljs (defn cljs-uri [expected]
(core/->CljsUriEquals expected)))

(defn matcher-for
Expand Down
51 changes: 49 additions & 2 deletions src/cljc/matcher_combinators/parser.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -13,56 +13,95 @@
function
(-match [this actual]
(core/match (matchers/pred this) actual))
(-matcher-for
([this] (matchers/pred this))
([this _t->m] (matchers/pred this)))

;; equals base types
nil
(-match [this actual]
(core/match (matchers/equals this) actual))
(-matcher-for
([_this] matchers/equals)
([this t->m] (matchers/lookup-matcher this t->m)))

number
(-match [this actual]
(core/match (matchers/equals this) actual))
(-matcher-for
([_this] matchers/equals)
([this t->m] (matchers/lookup-matcher this t->m)))

string
(-match [this actual]
(core/match (matchers/equals this) actual))
(-matcher-for
([_this] matchers/equals)
([this t->m] (matchers/lookup-matcher this t->m)))

boolean
(-match [this actual]
(core/match (matchers/equals this) actual))
(-matcher-for
([_this] matchers/equals)
([this t->m] (matchers/lookup-matcher this t->m)))

Keyword
(-match [this actual]
(core/match (matchers/equals this) actual))
(-matcher-for
([_this] matchers/equals)
([this t->m] (matchers/lookup-matcher this t->m)))

Symbol
(-match [this actual]
(core/match (matchers/equals this) actual))
(-matcher-for
([_this] matchers/equals)
([this t->m] (matchers/lookup-matcher this t->m)))

UUID
(-match [this actual]
(core/match (matchers/equals this) actual))
(-matcher-for
([_this] matchers/equals)
([this t->m] (matchers/lookup-matcher this t->m)))

goog.Uri
(-match [this actual]
(core/match (matchers/cljs-uri this) actual))
(-matcher-for
([_this] matchers/cljs-uri)
([this t->m] (matchers/lookup-matcher this t->m)))

js/Date
(-match [this actual]
(core/match (matchers/equals this) actual))
(-matcher-for
([_this] matchers/equals)
([this t->m] (matchers/lookup-matcher this t->m)))

Var
(-match [this actual]
(core/match (matchers/equals this) actual))
(-matcher-for
([_this] matchers/equals)
([this t->m] (matchers/lookup-matcher this t->m)))

;; equals nested types
Cons
(-match [this actual]
(core/match (matchers/equals this) actual))
(-matcher-for
([_this] matchers/equals)
([this t->m] (matchers/lookup-matcher this t->m)))

Repeat
(-match [this actual]
(core/match (matchers/equals this) actual))
(-matcher-for
([_this] matchers/equals)
([this t->m] (matchers/lookup-matcher this t->m)))

default
(-match [this actual]
Expand All @@ -73,10 +112,18 @@
(or (satisfies? ISet this)
(satisfies? ISequential this))
(core/match (matchers/equals this) actual)))
(-matcher-for
([this] (if (satisfies? IMap this)
matchers/embeds
matchers/equals))
([this t->m] (matchers/lookup-matcher this t->m)))

js/RegExp
(-match [this actual]
(core/match (matchers/regex this) actual))))
(core/match (matchers/regex this) actual))
(-matcher-for
([_this] matchers/equals)
([this t->m] (matchers/lookup-matcher this t->m)))))

#?(:clj (do
(defmacro mimic-matcher [matcher t]
Expand Down Expand Up @@ -105,6 +152,6 @@
core/Matcher
(-matcher-for
([this] (matchers/pred this))
([this t->m] (matchers/pred this)))
([this t->m] (matchers/lookup-matcher this t->m)))
(-match [this actual]
(core/match (matchers/pred this) actual)))))
9 changes: 5 additions & 4 deletions test/clj/matcher_combinators/matchers_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
[matcher-combinators.matchers :as m]
[matcher-combinators.result :as result]
[matcher-combinators.test :refer [match?]]
[matcher-combinators.test-helpers :as test-helpers :refer [abs-value-matcher]])
[matcher-combinators.test-helpers :as test-helpers :refer [no-match? abs-value-matcher]])
(:import [matcher_combinators.model Mismatch Missing InvalidMatcherContext InvalidMatcherType]))

(defn any? [_x] true)
Expand Down Expand Up @@ -245,9 +245,6 @@
(is (= m/regex
(m/matcher-for #"abc")))))

(defn no-match? [expected actual]
(not (c/indicates-match? (c/match expected actual))))

(deftest match-with-matcher
(testing "processes overrides in order"
(let [matcher (m/match-with [pos? abs-value-matcher
Expand Down Expand Up @@ -297,6 +294,10 @@
#{1})
#{1 2}))

(is (match?
(m/match-with [set? m/embeds]
#{(m/pred odd?)})
#{1 2}))
(is (match?
(m/match-with [set? m/embeds]
#{odd?})
Expand Down
2 changes: 1 addition & 1 deletion test/clj/matcher_combinators/standalone_test.clj
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
(ns matcher-combinators.standalone-test
(:require [clojure.test :refer [deftest is testing use-fixtures]]
(:require [clojure.test :refer [deftest is testing]]
[matcher-combinators.matchers :as m]
[matcher-combinators.standalone :as standalone]))

Expand Down
3 changes: 3 additions & 0 deletions test/cljc/matcher_combinators/test_helpers.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,6 @@
(fn [actual] (= (Math/abs expected)
(Math/abs actual)))
(str "equal to abs value of " expected)))

(defn no-match? [expected actual]
(not (core/indicates-match? (core/match expected actual))))
67 changes: 62 additions & 5 deletions test/cljs/matcher_combinators/cljs_example_test.cljs
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
(ns matcher-combinators.cljs-example-test
(:require [clojure.test :refer [deftest testing is are]]
(:require [clojure.test :refer [deftest testing is]]
[clojure.test.check.generators :as gen]
[clojure.test.check.properties :as prop]
[clojure.test.check.clojure-test :refer [defspec]]
[matcher-combinators.standalone :as standalone]
[matcher-combinators.parser]
[matcher-combinators.matchers :as m]
[matcher-combinators.core :as c]
[matcher-combinators.test]
[matcher-combinators.test-helpers :as helpers])
[matcher-combinators.test :refer [match? thrown-match?]]
[matcher-combinators.test-helpers :refer [abs-value-matcher no-match?]])
(:import [goog.Uri]))

(def gen-any-equatable
Expand Down Expand Up @@ -45,7 +44,12 @@
[2 3 1])))
(testing "`(sort 2)` throws and causes a mismatch"
(is (not (standalone/match? (m/via sort 2)
2)))))
2))))
(testing "via + match-with allows pre-processing `actual` before applying matching"
(is (match? (m/match-with
[vector? (fn [expected] (m/via sort expected))]
{:payloads [1 2 3]})
{:payloads (shuffle [3 2 1])}))))

(deftest exception-matching
(is (thrown-match? ExceptionInfo
Expand All @@ -55,6 +59,12 @@
(deftest passing-match
(is (match? {:a 2} {:a 2 :b 1})))

(deftest pred-match
(is (match? #{odd?}
#{1}))
(is (match? #{(m/pred odd?)}
#{1})))

(comment
(deftest match?-no-actual-arg
(testing "fails with nice message when you don't provide an `actual` arg to `match?`"
Expand All @@ -68,3 +78,50 @@
(testing "fails with nice message when you don't provide an `actual` arg to `thrown-match?`"
(is (thrown-match? ExceptionInfo {:a 1})
:in-wrong-place))))

(deftest match-with-test
(testing "Example numeric test-case"
(is (match? (m/match-with [number? (m/within-delta 0.05)] 1) 0.99)))

(testing "maps"
(testing "passing case with equals override"
(is (match? (m/match-with [map? m/equals]
{:a :b})
{:a :b})))
(testing "failing case with equals override"
(is (no-match? (m/match-with [map? m/equals]
{:a :b})
{:a :b :d :e})))
(testing "passing case multiple scopes"
(is (match?
{:o (m/match-with [map? m/equals]
{:a
(m/match-with [map? m/embeds]
{:b :c})})}
{:o {:a {:b :c :d :e}}
:p :q})))
(testing "using `absent` matcher"
(is (match? (m/match-with [map? m/equals]
{:a m/absent
:b :c})
{:b :c}))
(is (match? (m/match-with [map? m/embeds]
{:a m/absent})
{:b :c}))))

(testing "sets"
(is (match?
(m/match-with [set? m/embeds]
#{1})
#{1 2}))

(is (match?
(m/match-with [set? m/embeds]
#{(m/pred odd?)})
#{1 2})))

(let [matcher (m/match-with [pos? abs-value-matcher
integer? m/equals]
5)]
(is (match? matcher 5))
(is (match? matcher -5))))

0 comments on commit ccd2099

Please sign in to comment.