diff --git a/test-resources/lib_tests/clojure/test_clojure/multi_spec.clj b/test-resources/lib_tests/clojure/test_clojure/multi_spec.clj new file mode 100644 index 00000000..fdd25e4f --- /dev/null +++ b/test-resources/lib_tests/clojure/test_clojure/multi_spec.clj @@ -0,0 +1,57 @@ +(ns clojure.test-clojure.multi-spec + (:require [clojure.spec.alpha :as s] + [clojure.test :as test :refer [deftest is testing]])) + +(defn submap? + "Is m1 a subset of m2?" + [m1 m2] + (if (and (map? m1) (map? m2)) + (every? (fn [[k v]] (and (contains? m2 k) + (submap? v (get m2 k)))) + m1) + (= m1 m2))) + +(s/def :event/type keyword?) +(s/def :event/timestamp int?) +(s/def :search/url string?) +(s/def :error/message string?) +(s/def :error/code int?) + +(defmulti event-type :event/type) +(defmethod event-type :event/search [_] + (s/keys :req [:event/type :event/timestamp :search/url])) +(defmethod event-type :event/error [_] + (s/keys :req [:event/type :event/timestamp :error/message :error/code])) + +(s/def :event/event (s/multi-spec event-type :event/type)) + +(deftest multi-spec-test + (is (s/valid? :event/event + {:event/type :event/search + :event/timestamp 1463970123000 + :search/url "https://clojure.org"})) + (is (s/valid? :event/event + {:event/type :event/error + :event/timestamp 1463970123000 + :error/message "Invalid host" + :error/code 500})) + (is (submap? + '#:clojure.spec.alpha{:problems + [{:path [:event/restart], + :pred clojure.test-clojure.multi-spec/event-type, + :val #:event{:type :event/restart}, :reason "no method", :via [:event/event], :in []}], + :spec :event/event, :value #:event{:type :event/restart}} + (s/explain-data :event/event + {:event/type :event/restart}))) + (is (submap? + '#:clojure.spec.alpha{:problems ({:path [:event/search], + :pred (clojure.core/fn [%] (clojure.core/contains? % :event/timestamp)), + :val {:event/type :event/search, :search/url 200}, + :via [:event/event], :in []} {:path [:event/search :search/url], + :pred clojure.core/string?, :val 200, + :via [:event/event :search/url], + :in [:search/url]}), :spec + :event/event, :value {:event/type :event/search, :search/url 200}} + (s/explain-data :event/event + {:event/type :event/search + :search/url 200}))))