* Add tests for markdown-clj and tools.namespace
See comment for why only one markdown test could be run.
Closes #1069 and #1064
* Convert 10 test libs using add-libtest
Also improved add-libtest to only require maven artifact
and rely on clojars for getting git-url most of the time
* Convert 8 more test libs using add-libtest
Also updated table and added comment for newline test
* Fix doric test
* Disable tools.namespace test that fails on windows
* Added dozen manual test libs and converted 2 test libs
add-libtest.clj supports manually-added and test-directories options
* Converts last tests to test namespaces and write libraries.csv
* Add a number of library tests from projects.md
Also add more docs around adding test libs and tweak add script
* Use :sha for gitlib and older clojure cli
* Revert "Use :sha for gitlib and older clojure cli"
This reverts commit c663ab8368.
* Fix and disable failing tests
Disabled tests that fail consistently and fixed windows one
97 lines
3.4 KiB
Clojure
97 lines
3.4 KiB
Clojure
(ns expound.spec-gen
|
|
(:require [clojure.spec.alpha :as s]
|
|
[com.stuartsierra.dependency :as deps]
|
|
[clojure.test.check.generators :as gen]
|
|
[expound.alpha :as expound]))
|
|
|
|
;; I want to do something like
|
|
;; (s/def :specs.coll-of/into #{[] '() #{}})
|
|
;; but Clojure (not Clojurescript) won't allow
|
|
;; this. As a workaround, I'll just use vectors instead
|
|
;; of vectors and lists.
|
|
;; FIXME - force a specific type of into/kind one for each test
|
|
;; (one for vectors, one for lists, etc)
|
|
|
|
(s/def :specs.coll-of/into #{[] #{}})
|
|
(s/def :specs.coll-of/kind #{vector? list? set?})
|
|
(s/def :specs.coll-of/count pos-int?)
|
|
(s/def :specs.coll-of/max-count pos-int?)
|
|
(s/def :specs.coll-of/min-count pos-int?)
|
|
(s/def :specs.coll-of/distinct boolean?)
|
|
|
|
(s/def :specs/every-args
|
|
(s/keys :req-un
|
|
[:specs.coll-of/into
|
|
:specs.coll-of/kind
|
|
:specs.coll-of/count
|
|
:specs.coll-of/max-count
|
|
:specs.coll-of/min-count
|
|
:specs.coll-of/distinct]))
|
|
|
|
(defn apply-coll-of [spec {:keys [into max-count min-count distinct]}]
|
|
(s/coll-of spec :into into :min-count min-count :max-count max-count :distinct distinct))
|
|
|
|
(defn apply-map-of [spec1 spec2 {:keys [into max-count min-count distinct _gen-max]}]
|
|
(s/map-of spec1 spec2 :into into :min-count min-count :max-count max-count :distinct distinct))
|
|
|
|
;; Since CLJS prints out entire source of a function when
|
|
;; it pretty-prints a failure, the output becomes much nicer if
|
|
;; we wrap each function in a simple spec
|
|
(expound/def :specs/string string? "should be a string")
|
|
(expound/def :specs/vector vector? "should be a vector")
|
|
(s/def :specs/int int?)
|
|
(s/def :specs/boolean boolean?)
|
|
(expound/def :specs/keyword keyword? "should be a keyword")
|
|
(s/def :specs/map map?)
|
|
(s/def :specs/symbol symbol?)
|
|
(s/def :specs/pos-int pos-int?)
|
|
(s/def :specs/neg-int neg-int?)
|
|
(s/def :specs/zero #(and (number? %) (zero? %)))
|
|
(s/def :specs/keys (s/keys
|
|
:req-un [:specs/string]
|
|
:req [:specs/map]
|
|
:opt-un [:specs/vector]
|
|
:opt [:specs/int]))
|
|
|
|
(def simple-spec-gen (gen/one-of
|
|
[(gen/elements [:specs/string
|
|
:specs/vector
|
|
:specs/int
|
|
:specs/boolean
|
|
:specs/keyword
|
|
:specs/map
|
|
:specs/symbol
|
|
:specs/pos-int
|
|
:specs/neg-int
|
|
:specs/zero
|
|
:specs/keys])
|
|
(gen/set gen/simple-type-printable)]))
|
|
|
|
(defn spec-dependencies [spec]
|
|
(->> spec
|
|
s/form
|
|
(tree-seq coll? seq)
|
|
(filter #(and (s/get-spec %) (not= spec %)))
|
|
distinct))
|
|
|
|
(defn topo-sort [specs]
|
|
(deps/topo-sort
|
|
(reduce
|
|
(fn [gr spec]
|
|
(reduce
|
|
(fn [g d]
|
|
;; If this creates a circular reference, then
|
|
;; just skip it.
|
|
(if (deps/depends? g d spec)
|
|
g
|
|
(deps/depend g spec d)))
|
|
gr
|
|
(spec-dependencies spec)))
|
|
(deps/graph)
|
|
specs)))
|
|
|
|
#?(:clj
|
|
(def spec-gen (gen/elements (->> (s/registry)
|
|
(map key)
|
|
topo-sort
|
|
(filter keyword?)))))
|