1+ ; Copyright (c) Rich Hickey. All rights reserved.
2+ ; The use and distribution terms for this software are covered by the
3+ ; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
4+ ; which can be found in the file epl-v10.html at the root of this distribution.
5+ ; By using this software in any fashion, you are agreeing to be bound by
6+ ; the terms of this license.
7+ ; You must not remove this notice, or any other, from this software.
8+
9+ (ns clojure.test-clojure.multi-spec
10+ (:require [clojure.spec.alpha :as s]
11+ [clojure.test :as test :refer [deftest is testing]]
12+ [clojure.test-clojure.spec :refer [submap?]]))
13+
14+ (s/def :event/type keyword? )
15+ (s/def :event/timestamp int? )
16+ (s/def :search/url string? )
17+ (s/def :error/message string? )
18+ (s/def :error/code int? )
19+
20+ (defmulti event-type :event/type )
21+ (defmethod event-type :event/search [_]
22+ (s/keys :req [:event/type :event/timestamp :search/url ]))
23+ (defmethod event-type :event/error [_]
24+ (s/keys :req [:event/type :event/timestamp :error/message :error/code ]))
25+
26+ (s/def :event/event (s/multi-spec event-type :event/type ))
27+
28+ (deftest multi-spec-test
29+ (is (s/valid? :event/event
30+ {:event/type :event/search
31+ :event/timestamp 1463970123000
32+ :search/url " https://clojure.org" }))
33+ (is (s/valid? :event/event
34+ {:event/type :event/error
35+ :event/timestamp 1463970123000
36+ :error/message " Invalid host"
37+ :error/code 500 }))
38+ (is (submap?
39+ '#:clojure.spec.alpha{:problems
40+ [{:path [:event/restart ],
41+ :pred clojure.test-clojure.multi-spec/event-type,
42+ :val #:event{:type :event/restart }, :reason " no method" , :via [:event/event ], :in []}],
43+ :spec :event/event , :value #:event{:type :event/restart }}
44+ (s/explain-data :event/event
45+ {:event/type :event/restart })))
46+ (is (submap?
47+ '#:clojure.spec.alpha{:problems ({:path [:event/search ],
48+ :pred (clojure.core/fn [%] (clojure.core/contains? % :event/timestamp )),
49+ :val {:event/type :event/search , :search/url 200 },
50+ :via [:event/event ], :in []} {:path [:event/search :search/url ],
51+ :pred clojure.core/string?, :val 200 ,
52+ :via [:event/event :search/url ],
53+ :in [:search/url ]}), :spec
54+ :event/event , :value {:event/type :event/search , :search/url 200 }}
55+ (s/explain-data :event/event
56+ {:event/type :event/search
57+ :search/url 200 }))))
0 commit comments