Specmonstah
  • Introduction
  • Infomercial
  • Tutorial
    • Concepts
    • 01: ent db
    • 02: schemas
    • 03: queries
    • 04: refs
    • 05: progressive construction
    • 06: spec-gen
    • 07: spec gen customization and omission
    • 08: visiting functions
    • 09: performing inserts
    • 10: uniqueness constraint
    • 11: collection constraint (vector of foreign keys)
    • 12: what about cycles?
Powered by GitBook
On this page

Was this helpful?

  1. Tutorial

07: spec gen customization and omission

You can override the values produces by ent-db-spec-gen in the query:

(ns reifyhealth.specmonstah-tutorial.07
  (:require [reifyhealth.specmonstah.core :as sm]
            [loom.io :as lio]
            [clojure.spec.alpha :as s]
            [reifyhealth.specmonstah.spec-gen :as sg]))

(s/def ::id (s/and pos-int? #(< % 100)))
(s/def ::not-empty-string (s/and string? not-empty #(< (count %) 10)))

(s/def ::username ::not-empty-string)
(s/def ::user (s/keys :req-un [::id ::username]))

(s/def ::name ::not-empty-string)
(s/def ::topic (s/keys :req-un [::id ::name ::owner-id]))

(s/def ::owner-id ::id)
(s/def ::topic-id ::id)
(s/def ::content ::not-empty-string)
(s/def ::post (s/keys :req-un [::id ::owner-id ::topic-id ::content]))

(def schema
  {:user  {:prefix :u
           :spec   ::user}
   :topic {:prefix    :t
           :spec      ::topic
           :relations {:owner-id [:user :id]}}
   :post  {:prefix    :p
           :spec      ::post
           :relations {:topic-id [:topic :id]}}})

(defn ex-01
  []
  (sg/ent-db-spec-gen-attr {:schema schema}
                           {:user [[1 {:spec-gen {:username "barb"}}]]
                            :post [[1 {:spec-gen {:content "so good to be barb"}}]]}))

(ex-01)
;; =>
{:p0 {:id 81, :owner-id 96, :topic-id 68, :content "so good to be barb"}
 :t0 {:id 68, :name "3l1IR8", :owner-id 3}
 :u0 {:id 3, :username "barb"}}
{:user [[1 {:spec-gen {:username "barb"}}]]
 :post [[1 {:spec-gen {:content "so good to be barb"}}]]}

You can also specify that you don't want an ent to reference one of the ents defined in its schema. For example, if a :todo-list's :owner-id is optional and you don't want it to be present, you could do this:

(defn ex-02
  []
  (sg/ent-db-spec-gen-attr {:schema schema}
                           {:topic [[1 {:refs {:owner-id ::sm/omit}}]]}))
(ex-02)
;; =>
{:t0 {:id 12, :name "418y13ST"}}

::sm/omit prevents the referenced ent from even being created in the ent db. It's as if the :owner-id relation didn't exist in the schema. spec generation respects this and omits :owner-id from the map it generates. If you want the key :owner-id to be present with the value nil, you'd have to specify that like this:

(defn ex-03
  []
  (sg/ent-db-spec-gen-attr {:schema schema}
                           {:topic [[1 {:refs     {:owner-id ::sm/omit}
                                        :spec-gen {:owner-id nil}}]]}))

(ex-03)
;; =>
{:t0 {:id 2, :name "pijm" :owner-id nil}}
Previous06: spec-genNext08: visiting functions

Last updated 5 years ago

Was this helpful?

We're using the same specs and schema as in . Things get interesting at line 34, where we have this query:

In the we saw that query terms could take an optional map. Here, the optional maps are {:spec-gen {:username "barb"}} and {:spec-gen {:content "so good to be barb"}} . When you include :spec-gen key, the associated map is merged into whatever value is generated by clojure.spec.

the last section
refs section