Composable generators. These functions return a schema, which can be used
with hegel-clj.test/gen to produce an actual value. We generally follow
Hegel's protocol, but with a Clojure flavor: we use vec instead of list,
because it generates vectors, and bytes instead of binary, and so on.
Option names use :kebab-case keywords and the usual :flag? for boolean
options.
See https://hegel.dev/reference/protocol#schemas for details.
Composable generators. These functions return a *schema*, which can be used with hegel-clj.test/gen to produce an actual value. We generally follow Hegel's protocol, but with a Clojure flavor: we use `vec` instead of `list`, because it generates vectors, and `bytes` instead of `binary`, and so on. Option names use :kebab-case keywords and the usual :flag? for boolean options. See https://hegel.dev/reference/protocol#schemas for details.
(bind f schema)Like fmap, returns a Schema which transforms the values generated by another Schema in some way. Instead of returning a specific value, the transforming function returns a generator, which is in turn used to generate a value. For example, to build a schema which generates two vectors wth the same size, one with ints, the other with floats:
Like fmap, returns a Schema which transforms the values generated by another Schema in some way. Instead of returning a specific *value*, the transforming function returns a *generator*, which is in turn used to generate a value. For example, to build a schema which generates two vectors wth the same size, one with ints, the other with floats:
(bytes)(bytes opts)Generates a byte array. Hegel calls this bytes. Options:
:min-size Minimum size :max-size Maximum size
Generates a byte array. Hegel calls this `bytes`. Options: :min-size Minimum size :max-size Maximum size
A partial regular expression pattern for the basic characters that can make up a Clojure symbol.
A partial regular expression pattern for the basic characters that can make up a Clojure symbol.
A partial regular expression pattern for the basic characters that can start a Clojure symbol
A partial regular expression pattern for the basic characters that can start a Clojure symbol
(collect [coll-sym init & [opts]] & body)Syntax for generating a variably-sized collection. Takes a binding vector
[coll-name initial-value], and a body. Invokes body multiple times,
beginning with coll-name bound to initial-value, and expects body to
evaluate to either a new value for coll, or the special value
:hegel-clj/reject, which means that you'd like to skip whatever element you
generated. The binding vector can optionally include a map of options. To
generate a sorted map of even integers to strings:
(g/collect [m (sorted-map) {:min-size 1, :max-size 10}]
(g/let [k (g/integer)
v (g/string)]
(if (even? k)
(assoc m k v)
:hegel-clj/reject)))
Syntax for generating a variably-sized collection. Takes a binding vector
`[coll-name initial-value]`, and a body. Invokes body multiple times,
beginning with `coll-name` bound to `initial-value`, and expects body to
evaluate to either a new value for `coll`, or the special value
`:hegel-clj/reject`, which means that you'd like to skip whatever element you
generated. The binding vector can optionally include a map of options. To
generate a sorted map of even integers to strings:
(g/collect [m (sorted-map) {:min-size 1, :max-size 10}]
(g/let [k (g/integer)
v (g/string)]
(if (even? k)
(assoc m k v)
:hegel-clj/reject)))(collect* opts init expand)Generates a variably-sized collection, with a function. Takes an option map,
an initial value for the collection, and a function (expand coll) => coll'
which adds an element to coll, presuambly by generating values. expand
should return either a new collection (which is fed to the next call to
expand, or the special value :hegel-clj/reject, which signals that you'd
like to skip whatever was generated.
Generates a variably-sized collection, with a function. Takes an option map, an initial value for the collection, and a function `(expand coll) => coll'` which adds an element to coll, presuambly by generating values. `expand` should return either a new collection (which is fed to the next call to `expand`, or the special value `:hegel-clj/reject`, which signals that you'd like to skip whatever was generated.
(constant x)A schema that always generates x. Internally we ask Hegel to generate 0
every time, and return x locally; that way we can return arbitrary
objects.
TODO: I think this is bad; we probably need to send up unique integers so Hegel can do unique constraints on vectors.
A schema that always generates `x`. Internally we ask Hegel to generate 0 every time, and return `x` locally; that way we can return arbitrary objects. TODO: I think this is bad; we probably need to send up unique integers so Hegel can do unique constraints on vectors.
(constant* x)Always generates x. This schema passes the value up to Hegel-core, so it
must be something that round-trips through CBOR.
Always generates `x`. This schema passes the value up to Hegel-core, so it must be something that round-trips through CBOR.
(domain)Generates a domain name as a string, per RFC 1035.
Generates a domain name as a string, per RFC 1035.
(email)Generates an email address as a string, per RFC 5322 section 3.4.1
Generates an email address as a string, per RFC 5322 section 3.4.1
(float)(float opts)(float min max)Generates a floating-point number. Options:
:min Minimum value :max Maximum value (ditto) :exclude-min? Exclude the minimum value :exclude-max? Exclude the maximum value :nan? Whether to allow NaNs :infinity? Whether to allow infinity :width Bit width: 32 or 64
Generates a floating-point number. Options: :min Minimum value :max Maximum value (ditto) :exclude-min? Exclude the minimum value :exclude-max? Exclude the maximum value :nan? Whether to allow NaNs :infinity? Whether to allow infinity :width Bit width: 32 or 64
(fmap f schema)Transforms generated values. Takes a function which takes one generated value to another, and a Schema. Returns an Schema which applies f to those values. For example, to generate even integers:
(fmap (partial * 2) (integers))
Transforms generated values. Takes a function which takes one generated
value to another, and a Schema. Returns an Schema which applies f to those
values. For example, to generate even integers:
(fmap (partial * 2) (integers))(fn-or-schema->fn f-or-schema)Turns a zero-arity function or a schema into a zero-arity function which generates values.
Turns a zero-arity function or a schema into a zero-arity function which generates values.
(hmap m)Generates a heterogenous map. Takes a map of keys (any objects) to schemas, and returns a schema which produces maps with those keys, and values drawn from their corresponding schemas. For example:
(g/hmap {:name (g/string) :age (g/integer)})
Generates a heterogenous map. Takes a map of keys (any objects) to schemas,
and returns a schema which produces maps with those keys, and values drawn
from their corresponding schemas. For example:
(g/hmap {:name (g/string)
:age (g/integer)})(integer)(integer opts)(integer min max)Generates an integer. Options:
:min Minimum value, inclusive :max Minimum value, inclusive
Generates an integer. Options: :min Minimum value, inclusive :max Minimum value, inclusive
(ip-address-str)(ip-address-str version)Generates an IP address; version should be either 4 for ipv4, or 6 for
ipv6. With no version, generates both kinds.
Generates an IP address; version should be either `4` for ipv4, or `6` for ipv6. With no version, generates both kinds.
(keyword)A Clojure keyword, either simple or qualified.
A Clojure keyword, either simple or qualified.
(let binding-forms & body)Like Clojure's let, but when a right-hand side is a schema, draws a value using hegel-clj.core/gen. This lets you mix generators and regular values. For example:
(gen/let [a (gen/integer) ; Drawn randomly by hegel-clj
b (+ a 2)] ; Evaluated as normal
...)
Like Clojure's let, but when a right-hand side is a schema, draws a value
using hegel-clj.core/gen. This lets you mix generators and regular values.
For example:
(gen/let [a (gen/integer) ; Drawn randomly by hegel-clj
b (+ a 2)] ; Evaluated as normal
...)(list elements)(list opts elements)Like vector, but returns lists.
Like vector, but returns lists.
(local-date)Generates a java.time.LocalDate.
Generates a java.time.LocalDate.
(local-date-str)Generates an ISO 8601 date string, like 1987-02-16
Generates an ISO 8601 date string, like 1987-02-16
(local-date-time)Generates a java.time.LocalDateTime.
Generates a java.time.LocalDateTime.
(local-date-time-str)Generates an ISO 8601 datetime string, like 2024-03-15T14:30:00
Generates an ISO 8601 datetime string, like 2024-03-15T14:30:00
(local-time)Generates a java.time.LocalTime.
Generates a java.time.LocalTime.
(local-time-str)Generates an ISO 8601 time string, like 14:30:00.123
Generates an ISO 8601 time string, like 14:30:00.123
(map keys values)(map {:keys [size min-size max-size]} keys values)Generates a map of keys to values, given a schema for keys and another for values. Options:
:size Shorthand for {:min-size size, :max-size size} :min-size The minimum number of elements, inclusive :max-size The maximum number of elements, inclusive
Note that Hegel does not seem to be able to generate keys with some types--you can't, for instance, generate keys which are vectors of integers.
Generates a map of keys to values, given a schema for keys and another
for values. Options:
:size Shorthand for {:min-size size, :max-size size}
:min-size The minimum number of elements, inclusive
:max-size The maximum number of elements, inclusive
Note that Hegel does not seem to be able to generate keys with some
types--you can't, for instance, generate keys which are vectors of integers.(one-of & gens)A value drawn from one of several generators. Returns just values, whereas
one-of* returns [index, value] pairs.
A value drawn from one of several generators. Returns just values, whereas one-of* returns `[index, value]` pairs.
(one-of* & gens)A value drawn from one of several generators. Returns [index, value]
pairs, where index is the index of the generator which was used, and
value is the value it produced.
A value drawn from one of several generators. Returns `[index, value]` pairs, where `index` is the index of the generator which was used, and `value` is the value it produced.
(qualified-keyword)An unqualified Clojure keyword, e.g. :foo/bar
An unqualified Clojure keyword, e.g. :foo/bar
(qualified-symbol)A qualified Clojure symbol, e.g. 'foo/bar
A qualified Clojure symbol, e.g. 'foo/bar
(rand-nth vector-schema)Takes a schema returning an nth-indexed collection of elements. Returns a schema which selects a random element from them.
Takes a schema returning an nth-indexed collection of elements. Returns a schema which selects a random element from them.
(recursive- leaf branch)EXERIMENTAL! Produces recursive data structures using arbitrary functions.
Takes two functions: (leaf), which produces a leaf node, and (branch nodes), which takes a vector of nodes and produces a branch node. Either
function can return hegel.clj/reject to reject a generated element.
Leaf can optionally be a schema, instead of a function.
I'm not really sure what the right shape is for this yet; might change later.
EXERIMENTAL! Produces recursive data structures using arbitrary functions. Takes two functions: `(leaf)`, which produces a leaf node, and `(branch nodes)`, which takes a vector of nodes and produces a branch node. Either function can return `hegel.clj/reject` to reject a generated element. Leaf can optionally be a schema, instead of a function. I'm not really sure what the right shape is for this yet; might change later.
(recursive-helper leaf branch depth)Inner loop for recursive-
Inner loop for recursive-
(regex pattern)(regex pattern opts)Generates a string (not a regex!) matching the given regular expression, which can be either a regex or string. Hegel doesn't say what the regular expression language is, so this may not work with all patterns; consider double-checking generated values.
IMPORTANT: I suspect that the Hegel regex semantics are Python; for example, #"^\d$" will produce digits like "߄". The Python syntax for enabling ASCII mode is illegal in Java patterns, so you'll have to fall back to [0-9] or a string if you want to generate the usual ASCII digits:
(regex "(?a)^\d+$") ; => 5, 2, 0, 3, ...
Options:
:full-match? Whether the pattern must match the full string, or if a substring match is allowed. Default false.
Generates a string (not a regex!) matching the given regular expression,
which can be either a regex or string. Hegel doesn't say what the regular
expression language *is*, so this may not work with all patterns; consider
double-checking generated values.
IMPORTANT: I suspect that the Hegel regex semantics are Python; for example,
#"^\d$" will produce digits like "߄". The Python syntax for enabling
ASCII mode is illegal in Java patterns, so you'll have to fall back to [0-9]
or a string if you want to generate the usual ASCII digits:
(regex "(?a)^\d+$") ; => 5, 2, 0, 3, ...
Options:
:full-match? Whether the pattern must match the full string, or if a
substring match is allowed. Default false.(schema type hegel-opts clj-opts & rewrite-pairs)Helper macro for constructing schemas. Takes a type string, a Hegel options
map (e.g. {"value" 2}, a Clojure options map (e.g. {:min 2}, and a flat
series of clojure-name hegel-name pairs where clojure-name is a keyword and
hegel-name is a string. Expands into code which constructs an instance of
Schema, merging into the Hegel options map options taken from the CLojure
options map, rewriting keys using rewrite-pairs.
Helper macro for constructing schemas. Takes a type string, a Hegel options
map (e.g. `{"value" 2}`, a Clojure options map (e.g. `{:min 2}`, and a flat
series of `clojure-name hegel-name` pairs where clojure-name is a keyword and
hegel-name is a string. Expands into code which constructs an instance of
Schema, merging into the Hegel options map options taken from the CLojure
options map, rewriting keys using rewrite-pairs.(schema* type m)Constructs an instance of Basic. Takes a type and a map of options which will be passed to hegel core.
Constructs an instance of Basic. Takes a type and a map of options which will be passed to hegel core.
(set elements)(set opts elements)Generates sets of elements. Options:
:size Shorthand for {:min-size size, :max-size size} :min-size The minimum number of elements, inclusive :max-size The maximum number of elements, inclusive
Generates sets of elements. Options:
:size Shorthand for {:min-size size, :max-size size}
:min-size The minimum number of elements, inclusive
:max-size The maximum number of elements, inclusive(shuffle vector-schema)A schema which produces a shuffled version of the given schema, which should produce vectors. For instance:
(g/shuffle (g/constant [1 2 3]))
A schema which produces a shuffled version of the given schema, which should produce vectors. For instance: (g/shuffle (g/constant [1 2 3]))
(simple-keyword)An unqualified Clojure keyword, e.g. :foo
An unqualified Clojure keyword, e.g. :foo
(simple-symbol)A unqualified Clojure symbol, e.g. 'foo
A unqualified Clojure symbol, e.g. 'foo
(sorted-map keys values)(sorted-map opts keys values)Like map, but generates sorted maps.
Like `map`, but generates sorted maps.
(sorted-set elements)(sorted-set opts elements)Like set, but generates sorted sets.
Like `set`, but generates sorted sets.
(string)(string opts)Generates a Unicode string. Options:
:min-size Minimum size, in code points :max-size Maximum size, in code points
Generates a Unicode string. Options: :min-size Minimum size, in code points :max-size Maximum size, in code points
(symbol)Generates a Clojure symbol, either simple or qualified.
Generates a Clojure symbol, either simple or qualified.
(tuple)(tuple a)(tuple a b)(tuple a b c)(tuple a b c d)(tuple a b c d & rest)Takes any number of schemas and generates a fixed-size vector of that size, where each element is drawn from the corresponding schema.
Takes any number of schemas and generates a fixed-size vector of that size, where each element is drawn from the corresponding schema.
(tuple* elements)Takes a sequential of schemas and generates a fixed-size vector of that size, where each element is drawn from the corresponding schema.
Takes a sequential of schemas and generates a fixed-size vector of that size, where each element is drawn from the corresponding schema.
(url-str)Generates a URL as a string, per RFC 3986.
Generates a URL as a string, per RFC 3986.
(vector elements)(vector {:keys [size min-size max-size unique?]} elements)Generates a vector of elements. Takes options and a schema for elements.
:size Shorthand for {:min-size size, :max-size size} :min-size The minimum number of elements, inclusive :max-size The maximum number of elements, inclusive :unique? If set, picks unique elements
Generates a vector of elements. Takes options and a schema for elements.
:size Shorthand for {:min-size size, :max-size size}
:min-size The minimum number of elements, inclusive
:max-size The maximum number of elements, inclusive
:unique? If set, picks unique elementscljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |