Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/malli/core.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -824,6 +824,7 @@
(defn -int-schema [] (-simple-schema {:type :int, :pred int?, :property-pred (-min-max-pred nil)}))
(defn -float-schema [] (-simple-schema {:type :float, :pred float?, :property-pred (-min-max-pred nil)}))
(defn -double-schema [] (-simple-schema {:type :double, :pred double?, :property-pred (-min-max-pred nil)}))
(defn -decimal-schema [] (-simple-schema {:type :decimal, :pred #?(:clj decimal? :cljs (constantly false)), :property-pred (-min-max-pred nil)}))

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the schema is meaningless in cljs then I propose :decimal not exist on that platform.

(defn -boolean-schema [] (-simple-schema {:type :boolean, :pred boolean?}))
(defn -keyword-schema [] (-simple-schema {:type :keyword, :pred keyword?}))
(defn -symbol-schema [] (-simple-schema {:type :symbol, :pred symbol?}))
Expand Down Expand Up @@ -2958,6 +2959,7 @@
:int (-int-schema)
:float (-float-schema)
:double (-double-schema)
:decimal (-decimal-schema)
:boolean (-boolean-schema)
:keyword (-keyword-schema)
:symbol (-symbol-schema)
Expand Down
1 change: 1 addition & 0 deletions src/malli/generator.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,7 @@
(defmethod -schema-generator :int [schema options] (gen/large-integer* (-min-max schema options)))
(defmethod -schema-generator :double [schema options] (double-gen schema options))
(defmethod -schema-generator :float [schema options] (double-gen schema options))
#?(:clj (defmethod -schema-generator :decimal [schema options] (gen-fmap bigdec (double-gen schema options))))

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think the current implementation works with :gen/infinite true and :gen/NaN? true.

It might make sense to never generate those values as in spec's generator:

https://github.com/clojure/spec.alpha/blob/6b698eed1787c14907082c86de3410dd51e816b4/src/main/clojure/clojure/spec/gen/alpha.clj#L158-L159

(defmethod -schema-generator :boolean [_ _] gen/boolean)
(defmethod -schema-generator :keyword [_ _] gen/keyword)
(defmethod -schema-generator :symbol [_ _] gen/symbol)
Expand Down
2 changes: 2 additions & 0 deletions src/malli/transform.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,7 @@
:int -string->long
:float -string->float
:double -string->double
#?@(:clj [:decimal -string->decimal])
:boolean -string->boolean

:> -string->long
Expand Down Expand Up @@ -369,6 +370,7 @@
:int -any->string
:float -any->string
:double -any->string
#?@(:clj [:decimal -any->string])
;:boolean -any->string

:> -any->string
Expand Down
18 changes: 18 additions & 0 deletions test/malli/core_test.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -2212,6 +2212,24 @@
[1.1 3.1 mt/string-transformer [:double {:encode/string {:enter inc, :leave inc}}]]]
:ast {:type :double, :properties {:min 1.0, :max 4.0}}
:form [:double {:min 1.0, :max 4.0}]}
#?@(:clj [:decimal {:schema [:decimal {:min 1.0M, :max 4.0M}]
:validate {:success [1.0M 2.2M 4.0M]
:failure [nil "invalid" 0.5M 1.0]}
:explain [[1.0M]
[false {:schema [:decimal {:min 1.0M, :max 4.0M}]
:value false
:errors [{:path []
:in []
:schema [:decimal {:min 1.0M, :max 4.0M}]
:value false}]}]]
:decode [["1.1" 1.1M mt/string-transformer]
["1.1" "1.1" mt/json-transformer]
[1.1M 3.1M mt/string-transformer [:decimal {:decode/string {:enter inc, :leave inc}}]]]
:encode [[1.1M "1.1" mt/string-transformer]
[1.1M 1.1M mt/json-transformer]
[1.1M 3.1M mt/string-transformer [:decimal {:encode/string {:enter inc, :leave inc}}]]]
:ast {:type :decimal, :properties {:min 1.0M, :max 4.0M}}
:form [:decimal {:min 1.0M, :max 4.0M}]}])
:keyword {:schema :keyword
:validate {:success [:abba :user/abba]
:failure [nil "invalid"]}
Expand Down
5 changes: 5 additions & 0 deletions test/malli/generator_test.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,11 @@
[:set {:min 1, :gen/min 10, :max 100, :gen/max 200} int?]
[:string {:min 1, :gen/min 10, :max 100, :gen/max 200}])))

#?(:clj
(deftest decimal-generator-test
(is (every? decimal? (mg/sample [:decimal {:min 0.0M, :max 1.0M}] {:size 100})))
(is (every? #(<= 0.0M % 1.0M) (mg/sample [:decimal {:min 0.0M, :max 1.0M}] {:size 100})))))

@frenchy64 frenchy64 May 3, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add some tests for :gen/min and :gen/max (see existing for other schemas), and some tests providing :min/:max as longs/doubles as in malli.generator-test/double-with-long-min-test.

Also tests that provide bounds outside the range of Double, for example {:min (inc (bigdec Double/MAX_VALUE))} should generate numbers greater than (bigdec Double/MAX_VALUE).

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually I'm not sure if anyone has released a BigDecimal generator that supports arbitrary bounds.

This is the closest I could find:

https://github.com/clojure/test.check/blob/5ba3a25b60cf66ff531db8f44d89145abfacfa5c/src/main/clojure/clojure/test/check/generators.cljc#L1389

I think at minimum we need a test to show that it throws rather than violating the expected bounds.


(deftest protocol-test
(let [values #{1 2 3 5 8 13}
schema (reify
Expand Down