Tutorial by Examples

Any predicate function can be used as a spec. Here's a simple example: (clojure.spec/valid? odd? 1) ;;=> true (clojure.spec/valid? odd? 2) ;;=> false the valid? function will take a spec and a value and return true if the value conforms to the spec and false otherwise. One other inte...
Let's say we have the following function: (defn nat-num-count [nums] (count (remove neg? nums))) We can write a spec for this function by defining a function spec of the same name: (clojure.spec/fdef nat-num-count :args (s/cat :nums (s/coll-of number?)) :ret integer? ...
In addition to predicates functioning as specs, you can register a spec globally using clojure.spec/def. def requires that a spec being registered is named by a namespace-qualified keyword: (clojure.spec/def ::odd-nums odd?) ;;=> :user/odd-nums (clojure.spec/valid? ::odd-nums 1) ;;=> tru...
clojure.spec/and & clojure.spec/or can be used to create more complex specs, using multiple specs or predicates: (clojure.spec/def ::pos-odd (clojure.spec/and odd? pos?)) (clojure.spec/valid? ::pos-odd 1) ;;=> true (clojure.spec/valid? ::pos-odd -3) ;;=> false or works similarl...
You can spec a record as follows: (clojure.spec/def ::name string?) (clojure.spec/def ::age pos-int?) (clojure.spec/def ::occupation string?) (defrecord Person [name age occupation]) (clojure.spec/def ::person (clojure.spec/keys :req-un [::name ::age ::occupation])) (clojure.spec/valid? ...
You can spec a map by specifying which keys should be present in the map: (clojure.spec/def ::name string?) (clojure.spec/def ::age pos-int?) (clojure.spec/def ::occupation string?) (clojure.spec/def ::person (clojure.spec/keys :req [::name ::age ::occupation])) (clojure.spec/valid? ::perso...
You can spec collections in a number of ways. coll-of allows you to spec collections and provide some additional constraints. Here's a simple example: (clojure.spec/valid? (clojure.spec/coll-of int?) [1 2 3]) ;; => true (clojure.spec/valid? (clojure.spec/coll-of int?) '(1 2 3)) ;; => tru...
spec can describe and be used with arbitrary sequences. It supports this via a number of regex spec operations. (clojure.spec/valid? (clojure.spec/cat :text string? :int int?) ["test" 1]) ;;=> true cat requires labels for each spec used to describe the sequence. cat describes a seq...

Page 1 of 1