diff --git a/Makefile b/Makefile index 0668f9c..cc825ad 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,6 @@ .PHONY: test - +repl: + clojure -Sdeps '{:deps {nrepl/nrepl {:mvn/version "0.8.3"} cider/cider-nrepl {:mvn/version "0.25.7"} refactor-nrepl/refactor-nrepl {:mvn/version "2.5.1"}}}' -m nrepl.cmdline --middleware "[cider.nrepl/cider-middleware refactor-nrepl.middleware/wrap-refactor]" --interactive test: clj -A:test:runner diff --git a/src/matcho/core.clj b/src/matcho/core.clj index e6193b5..ec511d1 100644 --- a/src/matcho/core.clj +++ b/src/matcho/core.clj @@ -27,44 +27,51 @@ :else (when-not (= p x) {:expected p :but x}))) -(defn- match-recur [errors path x pattern] - (cond - (and (map? x) - (map? pattern)) - (let [strict? (:matcho/strict (meta pattern)) - errors (if (and strict? (not (= (set (keys pattern)) - (set (keys x))))) - (conj errors {:expected "Same keys in pattern and x" - :but (str "Got " (vec (keys pattern)) - " in pattern and " (vec (keys x)) " in x") - :path path}) - errors)] - (reduce (fn [errors [k v]] - (let [path (conj path k) - ev (get x k)] - (match-recur errors path ev v))) - errors pattern)) +(defn- normolize [coll n-fn] + (->> coll (map (juxt n-fn identity)) (into {}))) - (and (sequential? pattern) - (sequential? x)) - (let [strict? (:matcho/strict (meta pattern)) - errors (if (and strict? (not (= (count pattern) (count x)))) - (conj errors {:expected "Same number of elements in sequences" - :but (str "Got " (count pattern) - " in pattern and " (count x) " in x") - :path path}) - errors)] - (reduce (fn [errors [k v]] - (let [path (conj path k) - ev (nth (vec x) k nil)] - (match-recur errors path ev v))) - errors - (map (fn [x i] [i x]) pattern (range)))) - - :else (let [err (smart-explain-data pattern x)] - (if err - (conj errors (assoc err :path path)) - errors)))) +(defn- match-recur [errors path x pattern] + (let [n-fn (or (:matcho/as-map-by (meta x)) + (:matcho/as-map-by (meta pattern))) + as-map? (and (sequential? x) (sequential? pattern) n-fn)] + (cond + (or (and (map? x) (map? pattern)) as-map?) + (let [pattern (cond-> pattern as-map? (normolize n-fn)) + x (cond-> x as-map? (normolize n-fn)) + strict? (:matcho/strict (meta pattern)) + errors (if (and strict? (not (= (set (keys pattern)) + (set (keys x))))) + (conj errors {:expected "Same keys in pattern and x" + :but (str "Got " (vec (keys pattern)) + " in pattern and " (vec (keys x)) " in x") + :path path}) + errors)] + (reduce (fn [errors [k v]] + (let [path (conj path k) + ev (get x k)] + (match-recur errors path ev v))) + errors pattern)) + + (and (sequential? pattern) + (sequential? x)) + (let [strict? (:matcho/strict (meta pattern)) + errors (if (and strict? (not (= (count pattern) (count x)))) + (conj errors {:expected "Same number of elements in sequences" + :but (str "Got " (count pattern) + " in pattern and " (count x) " in x") + :path path}) + errors)] + (reduce (fn [errors [k v]] + (let [path (conj path k) + ev (nth (vec x) k nil)] + (match-recur errors path ev v))) + errors + (map (fn [x i] [i x]) pattern (range)))) + + :else (let [err (smart-explain-data pattern x)] + (if err + (conj errors (assoc err :path path)) + errors))))) (defn- match-recur-strict [errors path x pattern] (cond diff --git a/test/matcho/core_test.clj b/test/matcho/core_test.clj index 51925d7..05d7051 100644 --- a/test/matcho/core_test.clj +++ b/test/matcho/core_test.clj @@ -272,7 +272,6 @@ {:a :b})) (testing "non-inheritance of strict mode" - (m/assert ^:matcho/strict {:a [1 2]} @@ -286,4 +285,11 @@ (m/assert ^:matcho/strict {:a ^:matcho/strict [1 2]} - {:a [1 2]}))) + {:a [1 2]})) + + (testing "compare vector as map" + (m/assert + [{:id "1" :a 1 } {:id "2" :a 2}] + ^{:matcho/as-map-by :id} + [{:id "2" :a 2} {:id "1" :a 1}])) + )