reifyhealth / specmonstah

Specmonstah will eat the face off your test fixtures
MIT License
360 stars 18 forks source link

Nested relations? #47

Closed orestis closed 5 years ago

orestis commented 6 years ago

I'm evaluating Specmonstah to generate test data for Mongodb. I'd like to be able to specify paths for relations, instead of only top-level keys. Example:

(def schema
  {:user      {:prefix :user
               :spec   ::user}
   :client    {:prefix    :client
               :spec      ::client}
   :site      {:prefix    :site
               :spec     ::site
               :relations {[:meta :client_id] [:client :id]}}})

With the expectation that the generated site entity will look like this:

{:id 1
 :name "etc etc"
 :meta {:client_id 2}}

Does that sound reasonable?

orestis commented 6 years ago

A similar use case would be to be able to generate vectors of relation ids. I'm not sure what the relation syntax would look, but the result should look something like this:

;; site
{:id 1
 :name "etc etc"
 :clients [2 3 4]}

Where [2 3 4] are ids that point to some other entity, e.g. user and have to be unique.

orestis commented 6 years ago

I have a feeling that this could be done in a post-processing visitation function though?

flyingmachine commented 6 years ago

the :clients use case is already handled with :coll relation types :) check out this test and the related schema

Your initial suggestion is something I'll need to spend more time looking into. I think it should be supported but I haven't touched the codebase in a while, and I'm not sure how difficult it would be to accomplish or what priority it should be :)

stevebuik commented 5 years ago

This feature is really useful

:constraints {:some/key #{:coll}}

but it is not clearly documented. I discovered it by looking in this issue.

I'd suggest that this is added to the readme (already awesome) so that others can more easily learn how to populate n-arity relations declaratively.

stevebuik commented 5 years ago

One more "feature" related to :coll constraints that would be useful is the ability to ensure the sort/order of the inserted values. currently it's variable. Let me know if you would like me to create a new issue for this?

flyingmachine commented 5 years ago

After quite some time I've finally been able to look at it. One potential issue is that in

:relations {[:meta :client_id] [:client :id]}

It's ambiguous as to whether [:meta :client_id] is meant to represent a path into a map, or a top-level key on a map. However, there is a workaround, which is to create your own spec-gen visitor.

Here is where a referenced value gets associated with the ent referencing it. This is part of a 3-step process for using spec to generate values. You could replace that second step with one of your own that interprets vectors as paths and uses assoc-in instead of assoc. Hope this helps, even though it's like 5000 years later 📦