diff --git a/deps.edn b/deps.edn index 61ea0607..fe1307cc 100644 --- a/deps.edn +++ b/deps.edn @@ -12,16 +12,16 @@ org.clojure/core.async {:mvn/version "1.1.587"}, org.clojure/tools.cli {:mvn/version "1.0.194"}, org.clojure/data.csv {:mvn/version "1.0.0"}, - cheshire {:mvn/version "5.10.0"} + cheshire/cheshire {:mvn/version "5.10.0"} org.clojure/data.xml {:mvn/version "0.2.0-alpha6"} - fipp {:mvn/version "0.6.22"} + fipp/fipp {:mvn/version "0.6.22"} clj-commons/clj-yaml {:mvn/version "0.7.1"} com.cognitect/transit-clj {:mvn/version "1.0.324"} nrepl/bencode {:mvn/version "1.1.0"} seancorfield/next.jdbc {:mvn/version "1.0.424"} org.postgresql/postgresql {:mvn/version "42.2.12"} org.hsqldb/hsqldb {:mvn/version "2.4.0"} - datascript {:mvn/version "0.18.11"}} + datascript/datascript {:mvn/version "0.18.11"}} :aliases {:main {:main-opts ["-m" "babashka.main"]} :profile @@ -31,28 +31,28 @@ :jvm-opts ["-Djdk.attach.allowAttachSelf"] :main-opts ["-m" "babashka.profile"]} :lib-tests - {:extra-deps {clj-http-lite + {:extra-deps {babashka/clj-http-lite {:git/url "https://github.com/babashka/clj-http-lite" :sha "f44ebe45446f0f44f2b73761d102af3da6d0a13e"} - spartan.spec {:git/url "https://github.com/borkdude/spartan.spec" + borkdude/spartan.spec {:git/url "https://github.com/borkdude/spartan.spec" :sha "16f7eec4b6589c77c96c9fcf989f78fffcee7c4c"} - regal {:git/url "https://github.com/lambdaisland/regal" + lambdaisland/regal {:git/url "https://github.com/lambdaisland/regal" :sha "b059fdb06d5586a9a04c27e7b011c467ad8546db"} - medley {:git/url "https://github.com/weavejester/medley" - :sha "a4e5fb5383f5c0d83cb2d005181a35b76d8a136d"} - babasha.curl {:local/root "babashka.curl"} - cprop {:mvn/version "0.1.16"} - comb {:mvn/version "0.1.1"} + weavejester/medley {:git/url "https://github.com/weavejester/medley" + :sha "a4e5fb5383f5c0d83cb2d005181a35b76d8a136d"} + babashka/babasha.curl {:local/root "babashka.curl"} + cprop/cprop {:mvn/version "0.1.16"} + comb/comb {:mvn/version "0.1.1"} mvxcvi/arrangement {:mvn/version "1.2.0"} org.clojure/data.zip {:mvn/version "1.0.0"} - clojure-csv {:mvn/version "2.0.2"} + clojure-csv/clojure-csv {:mvn/version "2.0.2"} org.clojure/math.combinatorics {:mvn/version "0.1.6"} - doric {:mvn/version "0.9.0"} - cljc.java-time + doric/doric {:mvn/version "0.9.0"} + henryw374/cljc.java-time {:git/url "https://github.com/henryw374/cljc.java-time.git" :sha "e3d184b78e933322b3fcaa6ca66cbb8f42a6b35c"} - camel-snake-kebab {:mvn/version "0.4.1"} - aero {:mvn/version "1.1.6"} + camel-snake-kebab/camel-snake-kebab {:mvn/version "0.4.1"} + aero/aero {:mvn/version "1.1.6"} org.clojure/data.generators {:mvn/version "1.0.0"} - honeysql {:mvn/version "1.0.444"} - minimallist {:mvn/version "0.0.1"}}}}} + honeysql/honeysql {:mvn/version "1.0.444"} + minimallist/minimallist {:mvn/version "0.0.6"}}}}} diff --git a/test-resources/lib_tests/minimallist/core_test.cljc b/test-resources/lib_tests/minimallist/core_test.cljc index 9b9a6360..d86176f1 100644 --- a/test-resources/lib_tests/minimallist/core_test.cljc +++ b/test-resources/lib_tests/minimallist/core_test.cljc @@ -1,7 +1,38 @@ (ns minimallist.core-test (:require [clojure.test :refer [deftest testing is are]] - [minimallist.core :refer [valid?]] - [minimallist.helper :as h])) + [minimallist.core :refer [valid? explain describe undescribe] :as m] + [minimallist.helper :as h] + [minimallist.util :as util])) + +(comment + (#'m/sequence-descriptions {} + ; [:cat [:+ pos-int?] + ; [:+ int?]] + (h/cat (h/+ (h/fn pos-int?)) + (h/+ (h/fn int?))) + [3 4 0 2]) + + (#'m/sequence-descriptions {} + ; [:repeat {:min 0, :max 2} int?] + (h/repeat 0 2 (h/fn int?)) + (seq [1 2])) + + (#'m/sequence-descriptions {} + ; [:alt [:ints [:repeat {:min 0, :max 2} int?]] + ; [:keywords [:repeat {:min 0, :max 2} keyword?]] + (h/alt [:ints (h/repeat 0 2 (h/fn int?))] + [:keywords (h/repeat 0 2 (h/fn keyword?))]) + (seq [1 2])) + + (#'m/sequence-descriptions {} + ; [:* int?] + (h/* (h/fn int?)) + (seq [1 :2])) + + (#'m/sequence-descriptions {} + ; [:+ int?] + (h/+ (h/fn int?)) + (seq [1 2 3]))) (deftest valid?-test (let [test-data [;; fn @@ -76,7 +107,8 @@ [[1 :a] '(1 2 3) #{1 2 3} `(1 2 ~3)] ;; sequence with size specified using a model - (-> (h/sequence) (h/with-count (h/enum #{2 3}))) + (-> (h/sequence-of (h/fn any?)) + (h/with-count (h/enum #{2 3}))) ['(1 2) [1 "2"] `(1 ~"2") [1 "2" :3]] [#{1 "a"} [1 "2" :3 :4]] @@ -176,10 +208,10 @@ [:node (h/in-vector (h/cat (h/fn keyword?) (h/? (h/map)) (h/* (h/not-inlined (h/ref 'hiccup)))))] - [:primitive (h/or (h/fn nil?) - (h/fn boolean?) - (h/fn number?) - (h/fn string?))])] + [:primitive (h/alt (h/fn nil?) + (h/fn boolean?) + (h/fn number?) + (h/fn string?))])] (h/ref 'hiccup)) [nil false @@ -212,3 +244,217 @@ (is (valid? model data))) (doseq [data invalid-coll] (is (not (valid? model data))))))) + + +(deftest describe-test + (let [test-data [;; fn + (h/fn #(= 1 %)) + [1 1 + 2 :invalid] + + ;; enum + (h/enum #{1 "2" false nil}) + [1 1 + "2" "2" + false false + nil nil + true :invalid] + + ;; and + (h/and (h/fn pos-int?) + (h/fn even?)) + [0 :invalid + 1 :invalid + 2 2 + 3 :invalid + 4 4] + + ;; or + (h/or (h/fn int?) + (h/fn string?)) + [1 1 + "a" "a" + :a :invalid] + + ;; set + (h/set-of (h/fn int?)) + [#{1} #{1}] + + ;; map + (h/map [:a {:optional true} (h/fn int?)] + [:b (h/or (h/fn int?) + (h/fn string?))]) + [{:a 1, :b 2} {:a 1, :b 2} + {:a 1, :b "foo"} {:a 1, :b "foo"} + {:a 1, :b [1 2]} :invalid + ; missing optional entry + {:b 2} {:b 2} + ; missing entry + {:a 1} :invalid + ; extra entry + {:a 1, :b 2, :c 3} {:a 1, :b 2}] + + ;; map-of - :keys + (h/map-of (h/fn keyword?) (h/fn any?)) + [{:a 1, :b 2} {:a 1, :b 2} + {"a" 1} :invalid] + + ;; map-of - :values + (h/map-of (h/fn any?) (h/fn int?)) + [{:a 1, "b" 2} {:a 1, "b" 2} + {:a "1"} :invalid] + + ;; sequence - :elements-model + (h/sequence-of (h/fn int?)) + [[1 2 3] [1 2 3] + '(1 2 3) '(1 2 3) + [1 "2" 3] :invalid] + + ;; sequence - :elements-model with condition + (-> (h/sequence-of (h/fn int?)) + (h/with-condition (h/fn (fn [coll] (= coll (reverse coll)))))) + [[1 2 1] [1 2 1] + '(1 2 3) :invalid] + + ;; sequence - :coll-type vector + (h/vector-of (h/fn any?)) + [[1 2 3] [1 2 3] + '(1 2 3) :invalid] + + ;; sequence - :entries + (h/tuple (h/fn int?) (h/fn string?)) + [[1 "a"] [1 "a"] + [1 2] :invalid + [1] :invalid] + + ;; sequence - :count-model + (-> (h/sequence-of (h/fn any?)) + (h/with-count (h/val 3))) + [[1 2] :invalid + [1 2 3] [1 2 3] + [1 2 3 4] :invalid] + + ;; alt - not inside a sequence + (h/alt [:number (h/fn int?)] + [:sequence (h/cat (h/fn string?))]) + [1 [:number 1] + ["1"] [:sequence ["1"]] + [1] :invalid + "1" :invalid] + + ;; alt - inside a cat + (h/cat (h/fn int?) + (h/alt [:option1 (h/fn string?)] + [:option2 (h/fn keyword?)] + [:option3 (h/cat (h/fn string?) + (h/fn keyword?))]) + (h/fn int?)) + [[1 "2" 3] [1 [:option1 "2"] 3] + [1 :2 3] [1 [:option2 :2] 3] + [1 "a" :b 3] [1 [:option3 ["a" :b]] 3] + [1 ["a" :b] 3] :invalid] + + ;; alt - inside a cat, but with :inline false on its cat entry + (h/cat (h/fn int?) + (h/alt [:option1 (h/fn string?)] + [:option2 (h/fn keyword?)] + [:option3 (h/not-inlined (h/cat (h/fn string?) + (h/fn keyword?)))]) + (h/fn int?)) + [[1 "2" 3] [1 [:option1 "2"] 3] + [1 :2 3] [1 [:option2 :2] 3] + [1 "a" :b 3] :invalid + [1 ["a" :b] 3] [1 [:option3 ["a" :b]] 3]] + + ;; cat of cat, the inner cat is implicitly inlined + (h/cat (h/fn int?) + (h/cat (h/fn int?))) + [[1 2] [1 [2]] + [1] :invalid + [1 [2]] :invalid + [1 2 3] :invalid] + + ;; cat of cat, the inner cat is explicitly not inlined + (h/cat (h/fn int?) + (h/not-inlined (h/cat (h/fn int?)))) + [[1 [2]] [1 [2]] + [1 '(2)] [1 [2]] + [1] :invalid + [1 2] :invalid + [1 [2] 3] :invalid] + + ;; repeat - no collection type specified + (h/repeat 0 2 (h/fn int?)) + [[] [] + [1] [1] + [1 2] [1 2] + '() [] + '(1) [1] + '(2 3) [2 3] + [1 2 3] :invalid + '(1 2 3) :invalid] + + ;; repeat - inside a vector + (-> (h/repeat 0 2 (h/fn int?)) + (h/in-vector)) + [[1] [1] + '(1) :invalid] + + ;; repeat - inside a list + (-> (h/repeat 0 2 (h/fn int?)) + (h/in-list)) + [[1] :invalid + '(1) [1]] + + ;; repeat - min > 0 + (h/repeat 2 3 (h/fn int?)) + [[] :invalid + [1] :invalid + [1 2] [1 2] + [1 2 3] [1 2 3] + [1 2 3 4] :invalid] + + ;; repeat - max = +Infinity + (h/repeat 2 ##Inf (h/fn int?)) + [[] :invalid + [1] :invalid + [1 2] [1 2] + [1 2 3] [1 2 3]] + + ;; repeat - of a cat + (h/repeat 1 2 (h/cat (h/fn int?) + (h/fn string?))) + [[1 "a"] [[1 "a"]] + [1 "a" 2 "b"] [[1 "a"] [2 "b"]] + [] :invalid + [1] :invalid + [1 2] :invalid + [1 "a" 2 "b" 3 "c"] :invalid] + + ;; repeat - of a cat with :inlined false + (h/repeat 1 2 (h/not-inlined (h/cat (h/fn int?) + (h/fn string?)))) + [[[1 "a"]] [[1 "a"]] + [[1 "a"] [2 "b"]] [[1 "a"] [2 "b"]] + ['(1 "a") [2 "b"]] [[1 "a"] [2 "b"]] + [] :invalid + [1] :invalid + [1 2] :invalid + [1 "a"] :invalid + [1 "a" 2 "b"] :invalid + [1 "a" 2 "b" 3 "c"] :invalid] + + ;; let / ref + (h/let ['pos-even? (h/and (h/fn pos-int?) + (h/fn even?))] + (h/ref 'pos-even?)) + [0 :invalid + 1 :invalid + 2 2 + 3 :invalid + 4 4]]] + + (doseq [[model data-description-pairs] (partition 2 test-data)] + (doseq [[data description] (partition 2 data-description-pairs)] + (is (= [data (describe model data)] + [data description]))))))