(ns my.ns
(:require [clojure.spec.alpha :as s]))(s/def ::even even?)Use a registered spec from another namespace
(require '[my.namespace :as mn])
(s/def ::even ::mn/even)(s/conform even? 4) ; returns the value or :clojure.spec.alpha/invalid
(s/valid? even? 4) ; returns true or false(s/explain-data even? 4) ; => nil
(s/explain-data even? 5)
; => #:clojure.spec.alpha{:problems [{:path [], :pred clojure.core/even?, :val 5, :via [], :in []}],
; :spec #function[clojure.core/even?],
; :value 5}(s/def ::even-and-above-10 (s/and even? #(> % 10)))
(s/valid? ::even-and-above-10 12) ; => true
(s/valid? ::even-and-above-10 8) ; => false(s/def ::name string?)
(s/def ::nickname string?)
(s/def ::age int?)
(s/def ::person (s/keys :req-un [::name ::age] :opt-un [::nickname]))
(s/explain-data ::person {:name "Pesho" :age 30 :nickname "10"}) ; => nil
(s/explain-data ::person {:name "Pesho" :age 30 :nickname 10})
; #:clojure.spec.alpha{:problems
; ({:path [:nickname],
; :pred clojure.core/string?,
; :val 10,
; :via [:user/person :user/nickname],
; :in [:nickname]}),
; :spec :user/person,
; :value {:name "Pesho", :age 30, :nickname 10}}(require '[clojure.spec.gen.alpha :as gen])(s/gen pos-int?)(s/gen (s/and pos-int? even?))(gen/generate (s/gen pos-int?)) ; => 14This works by clojure.spec generating values from the base spec (in this case string?) and then applying the subsequent predicates as filters. Since it only generates 100 initial values, this will probably not work for complex specs.
(def uuid-regex #"(?i)^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$")
(s/def ::uuid-string (s/and string? #(some? (re-matches uuid-regex %))))
(s/valid? ::uuid-string "c278820c-9734-4ac2-99f6-23dd959ee73c") ; => true
(gen/generate (s/gen ::uuid-string))
; =>
; Error:
; Execution error (ExceptionInfo) at clojure.test.check.generators/fn (generators.cljc:435).
; Couldn't satisfy such-that predicate after 100 tries.Takes a spec and a function, returning a generator, and returns a spec, which uses the generator to generate values.
(s/def ::my-even (s/with-gen
(s/and pos-int? even?)
#(s/gen #{2 100 980})))
(gen/generate (s/gen ::my-even)) ; => one of 2, 100 or 980Takes a function and a generator and returns a generator, whose values are transformed by the function
(gen/generate (s/gen uuid?)) ; => #uuid "a06baf1e-3d77-49b4-8279-bceb5cd74ecd"
(gen/generate (gen/fmap str (s/gen uuid?))) ; => "a06baf1e-3d77-49b4-8279-bceb5cd74ecd"(def uuid-regex #"(?i)^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$")
(s/def ::uuid-string
(s/with-gen (s/and string? #(some? (re-matches uuid-regex %)))
#(gen/fmap str (s/gen ::uuid))))
(gen/generate (s/gen ::uuid-string)) ; => "a06baf1e-3d77-49b4-8279-bceb5cd74ecd"