This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2024-03-08
Channels
- # announcements (11)
- # babashka (13)
- # beginners (11)
- # biff (2)
- # calva (17)
- # cider (19)
- # clojure (60)
- # clojure-berlin (1)
- # clojure-dev (20)
- # clojure-europe (48)
- # clojure-nl (1)
- # clojure-norway (98)
- # clojure-spec (7)
- # clojure-uk (5)
- # core-typed (32)
- # cursive (13)
- # datomic (12)
- # dev-tooling (5)
- # emacs (7)
- # figwheel-main (2)
- # graalvm (4)
- # hyperfiddle (4)
- # introduce-yourself (1)
- # malli (14)
- # missionary (32)
- # off-topic (7)
- # overtone (4)
- # pedestal (10)
- # proletarian (4)
- # re-frame (8)
- # releases (11)
- # tools-build (1)
- # tools-deps (4)
- # xtdb (38)
How can I construct a set spec that assert the present and absence of certain values. I am generating specs dynamically based on parsed expressions so I would need a dynamic way to construct my spec. What I am looking for is something like.
(mg/generate
[:and
[:set [:enum 1 2 3 4 5 6 7 8 9]] ; This is the full domain of the set, all combinations should be generated and then filtered based on predicated as described below
; ex1 set should include 1 AND 4 but NOT 8 other values are ok
; ex2 set should include 1 AND 4 but NOT 8 other values NOT ok
; ex3 set should include 3 OR 4 but not both
])
maybe this should be :or
schemas, a union of different conforming values
No each rule I have now will restrict the set in some way and all the restrictions need to be valid for the set to be valid. I have the same setup for a map and it works great, however I can not find any good example how to restrict a set/collection using Malli.
Or maybe I misunderstand what you mean, can you give some example code that would generate what I want using :or
?
I filled in ex3 here:
(mc/validate
[:and
;; This is the full domain of the set, all combinations should be generated and then filtered based on predicated as described below
[:set [:enum 1 2 3 4 5 6 7 8 9]]
;; ex1 set should include 1 AND 4 but NOT 8 other values are ok
;; ex2 set should include 1 AND 4 but NOT 8 other values NOT ok
;; ex3 set should include 3 OR 4 but not both
[:fn (fn [s] (not (and (contains? s 3) (contains? s 4))))]
]
#{3 4})
;; => false
Is there any way to force more then 100 tries when you generate values, looking at the code I get the feeling that this value is not meant to be changed?
for generating tricky datastructures, there are some tools, the simplest is supplying elements with :gen/elements (these all go on the and), or :gen/fmap which would be a function that can return valid sets for you
The simplest would be just to be able to generate more values, the shape is not that tricky and all combinations would probably be generated for 5000 tries. So would be nice to just be able to increase the number of tries. Currently I do this by not wrapping the first clause in an and, instead I just generate a value and then filter if over the validation of the remaining schema validations. Then I can loop this until I find a match. Since I generate the schema dynamically it is nice to not have not to custom schemas. I am trying to keep them simple as possible and then rather just spend some more time on random generation.
As I understanding if I am to do what you say I would need to dynamically build but generators rather then schemas?
If someone has a good proposal for a generator combinator thing in malli, happy to hear. E.g. where :and
would collect generator part from it's children and construct a functioning generator out of that automatically.
I am now using m/generator to get the generator then I can use test.check instead. Combining that with malli specs has really been a nice fit for my use case so far.