From 81d11036d48823b4e69825cfd7c8bcc278419cee Mon Sep 17 00:00:00 2001 From: Joshua Davey Date: Thu, 18 Apr 2024 22:35:10 -0400 Subject: [PATCH] Add :gen/resolve property This works much like `:gen/gen`, but will first attempt to resolve the fully-qualified symbol. This separation means that malli schemas are free to carry around this extra data about where generators live, without having to have them loaded at runtime. Instead, generators declared in this way are dynamically loaded when used. --- src/malli/generator.cljc | 13 +++++++++++++ test/malli/generator_test.cljc | 8 +++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/malli/generator.cljc b/src/malli/generator.cljc index ce3cfd3e6..9ec6979a0 100644 --- a/src/malli/generator.cljc +++ b/src/malli/generator.cljc @@ -504,6 +504,17 @@ (when-not (:gen/elements props) (-generator schema options)))) +(defn- -create-from-resolve + [props] + (when (contains? props :gen/resolve) + (let [sym (-> (:gen/resolve props))] + #?(:clj (let [v (requiring-resolve sym)] + (if (instance? clojure.lang.IDeref v) + @v + v)) + :cljs (when (cljs.core/exists? sym) + (resolve sym)))))) + (defn- -create-from-schema [props options] (some-> (:gen/schema props) (generator options))) @@ -511,6 +522,7 @@ (when-some [fmap (:gen/fmap props)] (gen/fmap (m/eval fmap (or options (m/options schema))) (or (-create-from-return props) + (-create-from-resolve props) (-create-from-elements props) (-create-from-schema props options) (-create-from-gen props schema options) @@ -521,6 +533,7 @@ (m/properties schema))] (or (-create-from-fmap props schema options) (-create-from-return props) + (-create-from-resolve props) (-create-from-elements props) (-create-from-schema props options) (-create-from-gen props schema options) diff --git a/test/malli/generator_test.cljc b/test/malli/generator_test.cljc index 7e200711d..89a3bc0df 100644 --- a/test/malli/generator_test.cljc +++ b/test/malli/generator_test.cljc @@ -236,7 +236,13 @@ (testing "gen/gen" (is (every? #{1 2} (mg/sample [:and {:gen/gen (gen/elements [1 2])} int?] {:size 1000}))) - (is (every? #{"1" "2"} (mg/sample [:and {:gen/gen (gen/elements [1 2]) :gen/fmap str} int?] {:size 1000}))))) + (is (every? #{"1" "2"} (mg/sample [:and {:gen/gen (gen/elements [1 2]) :gen/fmap str} int?] {:size 1000})))) + (testing "gen/resolve" + (is (every? #{1 2} (mg/sample [:and {:gen/resolve 'malli.generator-test/resolvable-gen} int?] {:size 1000}))) + (is (every? #{"1" "2"} (mg/sample [:and {:gen/resolve 'malli.generator-test/resolvable-gen :gen/fmap str} int?] {:size 1000}))))) + +(def resolvable-gen + (gen/elements [1 2])) (defn- schema+coll-gen [type children-gen] (gen/let [children children-gen]