{"id":26066186,"url":"https://github.com/travelboss/schema-plus","last_synced_at":"2025-08-24T10:21:57.901Z","repository":{"id":62434985,"uuid":"179153762","full_name":"travelboss/schema-plus","owner":"travelboss","description":"Adds easy mock generation and builder functions to plumatic/schema definitions","archived":false,"fork":false,"pushed_at":"2019-11-12T18:10:53.000Z","size":39,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-03-06T02:03:29.314Z","etag":null,"topics":["clojure","clojurescript","generators","mock-data","schemas"],"latest_commit_sha":null,"homepage":null,"language":"Clojure","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/travelboss.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-04-02T20:29:58.000Z","updated_at":"2019-11-12T18:10:53.000Z","dependencies_parsed_at":"2022-11-01T21:02:21.483Z","dependency_job_id":null,"html_url":"https://github.com/travelboss/schema-plus","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/travelboss%2Fschema-plus","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/travelboss%2Fschema-plus/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/travelboss%2Fschema-plus/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/travelboss%2Fschema-plus/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/travelboss","download_url":"https://codeload.github.com/travelboss/schema-plus/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":242133502,"owners_count":20077098,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["clojure","clojurescript","generators","mock-data","schemas"],"created_at":"2025-03-08T20:08:19.628Z","updated_at":"2025-03-08T20:08:20.146Z","avatar_url":"https://github.com/travelboss.png","language":"Clojure","funding_links":[],"categories":[],"sub_categories":[],"readme":"# schema-plus\nAdds easy mock generation and builder functions to [plumatic/schema](https://github.com/plumatic/schema) definitions.\n\n## Installation\n\nThis library is available through clojars. Add the following to your dependencies:\n\n[![Clojars Project](http://clojars.org/travelboss/schema-plus/latest-version.svg)](http://clojars.org/travelboss/schema-plus)\n\n## Usage\n\nThe main function you'll use is `schema-plus.core/defschema+`. Use this instead of Plumatic's `schema/defschema` to get mock generation capabilities, default example values for Ring-Swagger, and optional builder functions.\n\nA docstring (and documentation for usage in Ring-Swagger) can be supplied by passing an optional `:docs` argument followed by the string.\n\nBased on the types used in the schema definition, a `clojure.test.check.generators.Generator` instance will be created that can generate mock data satisfying the schema definition. This automatically handles any referenced schemas that were also created with defschema+.\n\nThe default generator behavior can be replaced or augmented by supplying a `:generator` option. The following argument should either be a `clojure.test.check.generators.Generator` instance (to totally replace the default generator) or a function accepting one argument. If a function is passed, it will be passed as the first argument to `clojure.test.check.generators/fmap`, with the default generator as the second argument. In other words, when generating, the output of the default generator will be passed to your custom function as the only argument.\n\nExample of supplying a custom generator:\n\n```clojure\n(defschema+ Person\n  {:name schema/Str\n   :age schema/Int}\n  :generator\n  (gen/return {:name \"Bob\" :age 42}))\n```\n\nExample of supplying an fmap function:\n\n```clojure\n(defschema+ Person\n  {:name schema/Str\n   :age schema/Int}\n  :generator\n  (fn [default-generated] (assoc default-generated :age 42)))\n```\n\nFull example with all options:\n\n```clojure\n(require '[schema-plus.core :refer [defschema+]])\n(require '[schema.core :as schema])\n(require '[clojure.test.check.generators :as gen])\n\n(defschema+ Person\n  {:name schema/Str\n   :age schema/Int}\n  :docs \"A person with a name and age\"\n  :generator (gen/hash-map :name gen/char-alphanumeric\n                           :age gen/nat)\n  :example {:name \"Bob\" :age 42}\n  :make-builders? false)\"\n```\n\n### Generating\n\nOnce `defschema+` has been used to define a schema, `schema-plus.core/generate` can be used to generate mock data that satisfies that schema. This includes handling nested references to other schema definitions (assuming they were also defined with `defschema+`):\n\n```\n=\u003e (schema-plus.core/generate Person)\n{:name \"Efi239af\" :age 1324}\n```\n\nIf you need direct access to the `Generator` for a particular schema, you can use `get-generator`:\n\n```\n=\u003e (schema-plus.core/get-generator Person)\n#clojure.test.check.generators.Generator{:gen #object[clojure.test.check.generators$gen_fmap$fn__3647 0x1513d1e2 \"clojure.test.check.generators$gen_fmap$fn__3647@1513d1e2\"]}\n```\n\nIf you need to set the `Generator` to use for a particular schema, Java Class, or something else that `defschema+` couldn't be used for directly, you can use `set-generator`:\n\n```\n=\u003e (schema-plus.core/set-generator Object (clojure.test.check.generators/return \"abc\"))\n...\n=\u003e (schema-plus.core/defschema+ Bar {:a Object})\n#'user/Bar\n=\u003e (schema-plus.core/generate Bar)\n{:a \"abc\"}\n```\n\n### Builder Functions\n\nIf `:make-builders?` is not supplied, or is followed by `true`, then default builder functions will be defined. This will automatically define the following functions in the current namespace (assuming the schema-name is `Foo` and there is a field named `:bar`):\n\n```\n(+Foo) - Create an initial, empty instance\n\n(+Foo m) - Create an initial instance populated with fields populated from a map\n\n(+Foo-with-bar this v) - set the `:bar` field on a Foo instance\n\n(+Foo-build this) - Finalize creation of a Foo instance, validate against the schema\n```\n\nThe basic way to a new instance would look like:\n\n```clojure\n(-\u003e (+Foo)\n    (+Foo-with-bar 123)\n    (+Foo-with-baz \"ABC\")\n    (+Foo-build))\n```\n\nTo make this a little less redundant, there is a threading macro defined for each schema. It removes the need for the final build call:\n\n```clojure\n(+Foo-\u003e (+Foo)\n        (+Foo-with-bar 123)\n        (+Foo-with-baz \"ABC\"))\n```\n\nYou can also start with a generated value. This is useful for tests, where mock data is fine for most fields, but one or two need to be specified explicitly.\n\n```clojure\n(+Foo-\u003e (generate Foo)\n        (+Foo-with-baz \"ABC\"))\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftravelboss%2Fschema-plus","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftravelboss%2Fschema-plus","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftravelboss%2Fschema-plus/lists"}