I'm trying to refer to schemas directly in my schema:
(m/explain
[:map
[:function-name :string]
[:description :string]
[:signature :schema]] ; I've also tried m/schema?
{:function-name "add"
:description "Adds two (and only two) numbers"
:signature (m/schema [:=> [:cat :int :int] :int])}) ; also tried without the m/schema wrapping
The value of :signature should be the function schema, not a function conforming to the schema.
This results in a rather cryptic:
{:type clojure.lang.ExceptionInfo,
:message ":malli.core/child-error",
:data
{:type :malli.core/child-error,
:message :malli.core/child-error,
:data
{:type :schema, :properties nil, :children nil, :min 1, :max 1}},
:at [malli.core$_exception invokeStatic "core.cljc" 157]}]
Interestingly using [:signature m/schema?] results in an invalid schema error for some reason.yeah :schema gives you a child error because it's used as a wrapper for things like recursive schemas internally, so always in the form [:schema <something else>]
m/schema? is the right thing to check for, but it doesn't work because malli has an explicit whitelist of predicate schemas
[:fn m/schema?] should work, however
user=> (m/explain
[:map
[:function-name :string]
[:description :string]
[:signature [:fn m/schema?]]]
{:function-name "add"
:description "Adds two (and only two) numbers"
:signature (m/schema [:=> [:cat :int :int] :int])})
nil
user=> (m/explain
[:map
[:function-name :string]
[:description :string]
[:signature [:fn m/schema?]]]
{:function-name "add"
:description "Adds two (and only two) numbers"
:signature false})
{:schema [:map [:function-name :string] [:description :string] [:signature [:fn #object[malli.core$schema_QMARK_ 0x7757a37f "malli.core$schema_QMARK_@7757a37f"]]]], :value {:function-name "add", :description "Adds two (and only two) numbers", :signature false}, :errors ({:path [:signature], :in [:signature], :schema [:fn #object[malli.core$schema_QMARK_ 0x7757a37f "malli.core$schema_QMARK_@7757a37f"]], :value false})}btw, here is the list of supported predicate schemas: https://github.com/metosin/malli?tab=readme-ov-file#mallicorepredicate-schemas
Oh interesting thank you. I assumed I could use any predicate function as a predicate (like spec I guess)
This restriction in Malli is because one of the points of Malli was to make schemas that can be persisted in a db
so can't allow for arbitrary code, or for references to functions that might change between serialising and deserialising the schema
recently there's been a move away from functions-as-schemas to named schemas: :int instead of int? etc
just to give some context to you
I'm surprised there isn't a builtin named schema for [:fn m/schema?]
It seems like something that would crop up more
yeah
I'm thinking of using malli to generate mocks for database queries in testing. Is there any prior art out there I could use as reference?
I wouldn't directly mock the DB, but instead generate data and actually insert it in a rollback TX. I've been bitten by too many slight differences in behavior. I have used https://github.com/donut-party/datapotato for this and liked it overall, but it does have limitations & quirks
https://cljdoc.org/d/metosin/malli/0.17.0/doc/readme#value-generation
using with-redefs or a test component, you can have the database query function return generated conforming values for your schemas
i'm on mobile or i'd write an example, but i think it's self explanatory