This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-02-28
Channels
- # announcements (11)
- # aws (1)
- # babashka (12)
- # babashka-sci-dev (6)
- # beginners (46)
- # biff (15)
- # calva (57)
- # clerk (6)
- # clj-kondo (50)
- # clj-together (1)
- # cljs-dev (14)
- # clojure (89)
- # clojure-doc (1)
- # clojure-europe (36)
- # clojure-nl (1)
- # clojure-norway (50)
- # clojure-spec (4)
- # clojure-uk (1)
- # clojurescript (56)
- # conjure (10)
- # cursive (1)
- # datalevin (2)
- # datomic (3)
- # fulcro (15)
- # honeysql (36)
- # hyperfiddle (74)
- # malli (19)
- # membrane (16)
- # off-topic (33)
- # pathom (6)
- # polylith (2)
- # reagent (14)
- # releases (2)
- # rum (5)
- # shadow-cljs (51)
- # sql (6)
- # tools-build (10)
- # xtdb (6)
Q: is there a recommended way to specify in Malli that something is to be a json-encoded string? Motivation: i want to use a json-encoded string as a GET query param using Reitit. It kinda works with a hacky workaround, specifying [:map [:filter [:maybe [:or [:map :str]]]]]
as the schema, so that Swagger understands it as a map (but submits it as a string). Any other approach I might want to try? Cheers.
without :or :string
I'm getting a coercion error server side
This appears to work, found the pointer in another 🧵. Thanks!
(m/-simple-schema
{:type :map
:pred map?
:type-properties
{:decode/string #(try
(-> %
(json/read-str)
(w/keywordize-keys))
(catch Exception _ %))}})
Then you can add any constraints you might have about the entries like you would a regular map, yes?
Got it. 👍
I was a bit surprised by this behavior. I initially expected :*
and :+
to produce similar results to :vector
(although maybe as eg a list rather than vector), but it's very different.
user> (mg/generate [:* [:* [:* int?]]] {:seed 1, :size 3})
(0 -2 0 -1)
user> (mg/generate [:vector [:vector [:vector int?]]] {:seed 1, :size 3})
[[] [[0 -2 0] [-1]] []]
My guess is that what's going on is that :*
and :+
just mean 'some number of instances of a type' without any implication of containment, and that the only reason we're seeing the outer list in the :*
case is that if generate
generates > 1 item it has to throw them in a sequence just so that it's a single return val.
Is that correct, or am I more fundamentally misunderstanding something?You know, I've used spec a bunch and I've somehow just never run across that flattening behavior. Oh well, always more corners to discover 😁
Hi, I am sorry if my question sounds stupid, I am not sure why mi/check
is not working for me
I have this function with it’s schema:
(defn get-user! [id])
(m/=> get-user! [:=> [:cat uuid?]
[:map
[:user/first-name string?]
[:user/email [:and
{:gen/elements ["" ""]}
string?]]]])
First I run:
(dev/start! {:gen mg/generate :report (pretty/reporter)})
so then:
(get-user! (random-uuid)) ;; => #:user{:first-name "34Xdu9532PWK", :email ""}
(get-user! "2") ;; => Schema error
But when I try:
(mi/check {:filters [(mi/-filter-var #{#'get-user!})]
:gen mg/generate
:report (pretty/reporter)})
mi/check
does not generate a fake map value, but instead returns nil
which causes the check to fail.
am I using this wrong? my goal is to use generative testing, but I couldn’t find a working example that uses the function schemas with something like defspec
.oh, this is unfortunate, mi/check
has a separate branch in mi/-strument
so it ignores the :gen
option. Please write an issue of this
overheard at work: is there a trick to get something like recursive seqexps with Malli?
e.g. this schema works for generation, but not validation. is there a trick to get it working?
(let [sk [:schema {:registry {::filter
[:or
:boolean
[:cat [:= :and] [:* [:ref ::filter]]]]}}
::filter]]
(mg/generate sk)
;; => (:and false (:and (:and) (:and) true false))
(mc/validate sk true))
Hi. recursive self-flattening regex schemas are not allowed. You can wrap the :ref
with schema to make it work here:
(let [sk [:schema {:registry {::filter
[:or
:boolean
[:cat [:= :and] [:* [:schema [:ref ::filter]]]]]}}
::filter]]
(mg/generate sk)
;; => (:and false (:and (:and) (:and) true false))
(mc/validate sk true))
not sure if that’s clearly described in the README. Documentation improvements most welcome!
example from readme:
(def Hiccup
[:schema {:registry {"hiccup" [:orn
[:node [:catn
[:name keyword?]
[:props [:? [:map-of keyword? any?]]]
[:children [:* [:schema [:ref "hiccup"]]]]]]
[:primitive [:orn
[:nil nil?]
[:boolean boolean?]
[:number number?]
[:text string?]]]]}}
"hiccup"])
(def parse-hiccup (m/parser Hiccup))
(parse-hiccup
[:div {:class [:foo :bar]}
[:p "Hello, world of data"]])
;[:node
; {:name :div
; :props {:class [:foo :bar]}
; :children [[:node
; {:name :p
; :props nil
; :children [[:primitive [:text "Hello, world of data"]]]}]]}]