Fork me on GitHub
#malli
<
2024-02-26
>
Bingen Galartza Iparragirre10:02:04

I think I spotted a bug with strip-extra-keys-transformer and map-of:

dev> (malli.core/encode [:map [:a [:string]] [:b [:string]]] {:a "a" :b "b" :c "c"} malli.transform/strip-extra-keys-transformer)
{:a "a", :b "b"}
dev> (malli.core/encode [:map [:a [:string]] [:b [:string]]] {:a "a" :c "c"} malli.transform/strip-extra-keys-transformer)
{:a "a"}
dev> (malli.core/encode [:map-of [:string] [:map [:a [:string]] [:b [:string]]]] {"string" {:a "a" :b "b" :c "c"}} malli.transform/strip-extra-keys-transformer)
{"string" {:a "a", :b "b"}}
dev> (malli.core/encode [:map-of [:string] [:map [:a [:string]] [:b [:string]]]] {"string" {:a "a" :c "c"}} malli.transform/strip-extra-keys-transformer)
{}
The last example should not be empty

Bingen Galartza Iparragirre10:02:49

I found a comment in [this PR](https://github.com/metosin/malli/pull/963)

There is a pending issue when an invalid key in :map-of instead of being removed from the value invalidates the whole :map-of. This would probably require recursive validation, which may add some computational complexity.

Bingen Galartza Iparragirre10:02:20

But I can't find an open issue :thinking_face: Should I open one? or it's already somewhere?

ikitommi06:03:08

please open

frozenlock16:02:38

Is this the correct way to say "I want a vector with a minimum length of 2, and the first item must be a keyword"?

(m/validate [:and [:cat {:min-count 2} :keyword [:* :any]] vector?] [:kw "a" 1])
; => true
Using this with a generator fails after 100 tries...
(mg/generate [:and [:cat {:min-count 2} :keyword [:* :any]] vector?])
Execution error (ExceptionInfo) at clojure.test.check.generators/fn (generators.cljc:435).
Couldn't satisfy such-that predicate after 100 tries.

Stig Brautaset17:02:11

I think you want a tuple? Something like this:

[:tuple :keyword [:* :any]]

Stig Brautaset17:02:49

Ah, because you don't want a tuple you want a cat:

[:cat :keyword [:* :any]]
(Better yet:
[:cat :keyword [:+ :any]]
to ensure there are at least 2 items)

Noah Bogart17:02:30

that's what frozenlock has originally

🙇 1
Noah Bogart17:02:36

i think it's an error in the generator

Stig Brautaset18:02:45

I would drop the {:min-count 2} and replace :* with :+ which might improve the generator.

Stig Brautaset18:02:45

[:and [:cat :keyword [:+ :any]] vector?]

frozenlock18:02:16

But that still doesn't work with generators, right?

(mg/generate [:and [:cat :keyword [:+ :any]] vector?])

Execution error (ExceptionInfo) at clojure.test.check.generators/fn (generators.cljc:435).
Couldn't satisfy such-that predicate after 100 tries.

Stig Brautaset18:02:38

I don't understand why it does not work with generators :thinking_face: It works in the http://malli.io page 🤷

1
frozenlock18:02:23

Oh wait, it looks like it can work if vector? is first:

(mg/generate [:and vector? [:cat :keyword [:+ :any]]])

=> [:!P4+
 -1708474864121283778364080570989949433939248745244365942N
 4.0
 true
 ##NaN
 "L`{]aY:;Vj9:4'/i#G1=E!!g~r"
 #uuid "3231ba6a-b098-41d7-b9ce-8fc700d1d67a"
 false
 0.0019298376955703134
 -
 :Z910dDG9.
 YbA+dM/J*.._CI8]

Noah Bogart18:02:36

maybe it keeps generating conforming sequences for the :cat and then those aren't vectors so it fails

ambrosebs19:02:13

The key thing to understand is that malli generates values from the first child of an :and, and then only picks ones that pass the entire schema. So the :cat has to go first to have a reliable generator. This should work: [:and [:cat {:gen/fmap vec} :keyword [:* :any]] vector?] https://malli.io/?value=(%3Aa)&amp;schema=%5B%3Aand%20%5B%3Acat%20%7B%3Agen%2Ffmap%20vec%7D%20%20%3Akeyword%20%5B%3A*%20%3Aany%5D%5D%20vector%3F%5D

👍 3
ambrosebs20:02:36

Added this tip to the readme, if anyone has time to proof read: https://github.com/metosin/malli/pull/1012

frozenlock20:02:20

Looks like the parser is losing the metadata along the way. Bug?

(def id-schema
  [:and
   ;; Nested :and to be able to add metadata to generated content
   [:and {:gen/fmap #(with-meta % {:kw-id true})}
    [:cat {:gen/fmap vec}
     :keyword
     [:+ :string]]
    vector?]
   [:fn #(:kw-id (meta %))] ; <- causes issues with the parser?
   ])

(meta (mg/generate id-schema))
;=> {:kw-id true}

(m/parse id-schema (mg/generate id-schema))
;=> :malli.core/invalid
If you comment out the metadata test and try again, it works:
(def id-schema
  [:and
   ;; Nested :and to be able to add metadata to generated content
   [:and {:gen/fmap #(with-meta % {:kw-id true})}
    [:cat {:gen/fmap vec}
     :keyword
     [:+ :string]]
    vector?]
   ;[:fn #(:kw-id (meta %))] ; <- causes issues with the parser?
   ])

(m/parse id-schema (mg/generate id-schema))
;=> [:+_8X.u
 ["W3Iz5qe"
  "9r01WwNdDl91Gdzyk3QF7"
  "45BD4Z8qx6xa7ab5E5JbU6mLAv"
  "r01uuAvF6cmet7Kc964F7L"
  "BoUJv"
  "0q445EvwmMBj3JlaTYmT0n"]]

ikitommi06:03:49

please write an issue out of this

✔️ 1