| 
Java example source code file (spec.clj)
 The spec.clj Java example source code
(ns clojure.test-clojure.spec
  (:require [clojure.spec :as s]
            [clojure.spec.gen :as gen]
            [clojure.spec.test :as stest]
            [clojure.test :refer :all]))
(set! *warn-on-reflection* true)
(defmacro result-or-ex [x]
  `(try
     ~x
     (catch Throwable t#
       (.getName (class t#)))))
(def even-count? #(even? (count %)))
(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)))
(deftest conform-explain
  (let [a (s/and #(> % 5) #(< % 10))
        o (s/or :s string? :k keyword?)
        c (s/cat :a string? :b keyword?)
        either (s/alt :a string? :b keyword?)
        star (s/* keyword?)
        plus (s/+ keyword?)
        opt (s/? keyword?)
        andre (s/& (s/* keyword?) even-count?)
        m (s/map-of keyword? string?)
        coll (s/coll-of keyword? [])
        lrange (s/int-in 7 42)
        drange (s/double-in :infinite? false :NaN? false :min 3.1 :max 3.2)
        irange (s/inst-in #inst "1939" #inst "1946")
        ]
    (are [spec x conformed ed]
      (let [co (result-or-ex (s/conform spec x))
            e (result-or-ex (::s/problems (s/explain-data spec x)))]
        (when (not= conformed co) (println "conform fail\n\texpect=" conformed "\n\tactual=" co))
        (when (not (submap? ed e)) (println "explain fail\n\texpect=" ed "\n\tactual=" e))
        (and (= conformed co) (submap? ed e)))
      lrange 7 7 nil
      lrange 8 8 nil
      lrange 42 ::s/invalid {[] {:pred '(int-in-range? 7 42 %), :val 42, :via [], :in []}}
      irange #inst "1938" ::s/invalid {[] {:pred '(inst-in-range? #inst "1939-01-01T00:00:00.000-00:00" #inst "1946-01-01T00:00:00.000-00:00" %), :val #inst "1938", :via [], :in []}}
      irange #inst "1942" #inst "1942" nil
      irange #inst "1946" ::s/invalid {[] {:pred '(inst-in-range? #inst "1939-01-01T00:00:00.000-00:00" #inst "1946-01-01T00:00:00.000-00:00" %), :val #inst "1946", :via [], :in []}}
      drange 3.0 ::s/invalid {[] {:pred '(<= 3.1 %), :val 3.0, :via [], :in []}}
      drange 3.1 3.1 nil
      drange 3.2 3.2 nil
      drange Double/POSITIVE_INFINITY ::s/invalid {[] {:pred '(not (isInfinite %)), :val Double/POSITIVE_INFINITY, :via [], :in []}}
      ;; can't use equality-based test for Double/NaN
      ;; drange Double/NaN ::s/invalid {[] {:pred '(not (isNaN %)), :val Double/NaN, :via [], :in []}}
      keyword? :k :k nil
      keyword? nil ::s/invalid {[] {:pred ::s/unknown :val nil :via []}}
      keyword? "abc" ::s/invalid {[] {:pred ::s/unknown :val "abc" :via []}}
      a 6 6 nil
      a 3 ::s/invalid '{[] {:pred (> % 5), :val 3 :via []}}
      a 20 ::s/invalid '{[] {:pred (< % 10), :val 20 :via []}}
      a nil "java.lang.NullPointerException" "java.lang.NullPointerException"
      a :k "java.lang.ClassCastException" "java.lang.ClassCastException"
      o "a" [:s "a"] nil
      o :a [:k :a] nil
      o 'a ::s/invalid '{[:s] {:pred string?, :val a :via []}, [:k] {:pred keyword?, :val a :via []}}
      c nil ::s/invalid '{[:a] {:reason "Insufficient input", :pred string?, :val (), :via []}}
      c [] ::s/invalid '{[:a] {:reason "Insufficient input", :pred string?, :val (), :via []}}
      c [:a] ::s/invalid '{[:a] {:pred string?, :val :a, :via []}}
      c ["a"] ::s/invalid '{[:b] {:reason "Insufficient input", :pred keyword?, :val (), :via []}}
      c ["s" :k] '{:a "s" :b :k} nil
      c ["s" :k 5] ::s/invalid '{[] {:reason "Extra input", :pred (cat :a string? :b keyword?), :val (5), :via []}}
      (s/cat) nil {} nil
      (s/cat) [5] ::s/invalid '{[] {:reason "Extra input", :pred (cat), :val (5), :via [], :in [0]}}
      either nil ::s/invalid '{[] {:reason "Insufficient input", :pred (alt :a string? :b keyword?), :val () :via []}}
      either [] ::s/invalid '{[] {:reason "Insufficient input", :pred (alt :a string? :b keyword?), :val () :via []}}
      either [:k] [:b :k] nil
      either ["s"] [:a "s"] nil
      either [:b "s"] ::s/invalid '{[] {:reason "Extra input", :pred (alt :a string? :b keyword?), :val ("s") :via []}}
      star nil [] nil
      star [] [] nil
      star [:k] [:k] nil
      star [:k1 :k2] [:k1 :k2] nil
      star [:k1 :k2 "x"] ::s/invalid '{[] {:pred keyword?, :val "x" :via []}}
      star ["a"] ::s/invalid {[] '{:pred keyword?, :val "a" :via []}}
      plus nil ::s/invalid '{[] {:reason "Insufficient input", :pred keyword?, :val () :via []}}
      plus [] ::s/invalid '{[] {:reason "Insufficient input", :pred keyword?, :val () :via []}}
      plus [:k] [:k] nil
      plus [:k1 :k2] [:k1 :k2] nil
      plus [:k1 :k2 "x"] ::s/invalid '{[] {:pred keyword?, :val "x", :via [], :in [2]}}
      plus ["a"] ::s/invalid '{[] {:pred keyword?, :val "a" :via []}}
      opt nil nil nil
      opt [] nil nil
      opt :k ::s/invalid '{[] {:pred (? keyword?), :val :k, :via []}}
      opt [:k] :k nil
      opt [:k1 :k2] ::s/invalid '{[] {:reason "Extra input", :pred (? keyword?), :val (:k2), :via []}}
      opt [:k1 :k2 "x"] ::s/invalid '{[] {:reason "Extra input", :pred (? keyword?), :val (:k2 "x"), :via []}}
      opt ["a"] ::s/invalid '{[] {:pred keyword?, :val "a", :via []}}
      andre nil nil nil
      andre [] nil nil
      andre :k :clojure.spec/invalid '{[] {:pred (& (* keyword?) even-count?), :val :k, :via []}}
      andre [:k] ::s/invalid '{[] {:pred even-count?, :val [:k], :via []}}
      andre [:j :k] [:j :k] nil
      m nil ::s/invalid '{[] {:pred map?, :val nil, :via []}}
      m {} {} nil
      m {:a "b"} {:a "b"} nil
      coll nil nil nil
      coll [] [] nil
      coll [:a] [:a] nil
      coll [:a :b] [:a :b] nil
      ;;coll [:a "b"] ::s/invalid '{[] {:pred (coll-checker keyword?), :val [:a b], :via []}}
      )))
(s/fdef flip-nums
        :args (s/cat :arg1 integer? :arg2 integer?)
        :ret vector?
        :fn (fn [{:keys [args ret]}]
              (= ret [(:arg2 args) (:arg1 args)])))
(def ^:dynamic *break-flip-nums* false)
(defn flip-nums
  "Set *break-flip-nums* to break this fns compatibility with
its spec for test purposes."
  [a b]
  (if *break-flip-nums*
    (when-not (= a b)
      (vec (sort [a b])))
    [b a]))
(defmacro get-ex-data
  [x]
  `(try
    ~x
    nil
    (catch Throwable t#
      (ex-data t#))))
;; Note the the complicated equality comparisons below are exactly the
;; kind of thing that spec helps you avoid, used here only because we
;; are near the bottom, testing spec itself.
(deftest test-instrument-flip-nums
  (when-not (= "true" (System/getProperty "clojure.compiler.direct-linking"))
    (binding [*break-flip-nums* true]
      (try
       (= [1 2] (flip-nums 2 1))
       (= [:a :b] (flip-nums :a :b))
       (= [1 2] (flip-nums 1 2))
       (is (nil? (flip-nums 1 1)))
       (s/instrument `flip-nums)
       (is (= [1 2] (flip-nums 2 1)))
       (is (submap? '{:clojure.spec/problems {[:args :arg1] {:pred integer?, :val :a, :via []}}, :clojure.spec/args (:a :b)}
              (get-ex-data (flip-nums :a :b))))
       (is (submap? '{:clojure.spec/problems {[:fn] {:pred (fn [{:keys [args ret]}] (= ret [(:arg2 args) (:arg1 args)])), :val {:args {:arg1 1, :arg2 2}, :ret [1 2]}, :via []}}, :clojure.spec/args (1 2)}
              (get-ex-data (flip-nums 1 2))))
       (is (submap? '{:clojure.spec/problems {[:ret] {:pred vector?, :val nil, :via []}}, :clojure.spec/args (1 1)}
              (get-ex-data (flip-nums 1 1))))
       (s/unstrument `flip-nums)
       (= [1 2] (flip-nums 2 1))
       (= [:a :b] (flip-nums :a :b))
       (= [1 2] (flip-nums 1 2))
       (is (nil? (flip-nums 1 1)))
       (s/unstrument `flip-nums)))))
(def core-pred-syms
  (into #{}
        (comp (map first) (filter (fn [s] (.endsWith (name s) "?"))))
        (ns-publics 'clojure.core)))
(def generatable-core-pred-syms
  (into #{}
        (filter #(gen/gen-for-pred @ (resolve %)))
        core-pred-syms))
(s/fdef generate-from-core-pred
        :args (s/cat :s generatable-core-pred-syms)
        :ret ::s/any
        :fn (fn [{:keys [args ret]}]
              (@(resolve (:s args)) ret)))
(defn generate-from-core-pred
  [s]
  (gen/generate (gen/gen-for-pred @(resolve s))))
(comment
  (require '[clojure.test :refer (run-tests)])
  (in-ns 'clojure.test-clojure.spec)
  (run-tests)
  (stest/run-all-tests)
  (stest/check-var #'generate-from-core-pred :num-tests 10000)
  )
Other Java examples (source code examples)Here is a short list of links related to this Java spec.clj source code file:  | 
| ... this post is sponsored by my books ... | |
         
           #1 New Release!  | 
      
         
           FP Best Seller  | 
  
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse 
URI on this website is
paid back to open source projects.