Fork me on GitHub
#clojure-spec
<
2016-09-28
>
jfntn00:09:25

I can’t find a good solution to write different specs that all have a :db/id key but with different values

danielcompton00:09:04

@jfntn what do you mean by ‘different values’?

jfntn00:09:12

Well one would be say a ::temp-entity spec that’d check that :db/id is a datomic/tempid, and the other would be an ::entity spec that would check that :db/id is an entity id (long)

jfntn00:09:11

So I need to attach multiple specs to the same namespaced key, but s/or won’t do since the point is to be able to assert whether an entity is temporary or not...

jfntn00:09:33

I found a weird trick using multiple slashes in the spec name and using :req-un in the spec, but those don’t seem to really be supported since I’m getting intermitent analyzer errors and the keys won’t compile in cljs

bhagany00:09:04

I think in this case, I would use s/or, and use the conformed value to say whether it’s a temp id or not

bhagany00:09:00

it’s an extra step, but I don’t see another way to make it work

bhagany00:09:38

if you’re spec-ing a function that needs to take a temp entity, or something like that, you could always make a predicate function, temp-entity? or some such, that conforms its argument and checks which branch s/or took

jfntn00:09:17

@bhagany that’s a good idea!

jfntn00:09:14

Not as direct, but I’m able to express what I wanted, which is a reusable keys spec and combine it with the temp and final specs

misha06:09:03

@jfntn

-(s/def :datomic.tempid/idx int?)
+(s/def :datomic.tempid/idx neg-int?)

przemek06:09:42

Hi, while trying to migrate from schema to spec I've come across an issue. Following the guide I was able to define specs for maps, but I think I have a case that is not covered. Basically the same key i.e. :id or :name may be an attribute of different entities. If I define ::name then the only way to use a different type definition for :name is to use namespaces which puts me in sort of OO style when I keep module per "noun".... Is there not a way to decouple key from value so that I can define i.e. ::plan-name type, but use :name in my map?

misha06:09:34

@przemek what about (s/keys :req-un [...] :opt-un [...]?

misha06:09:21

basically, you'd have multiple namespaced specs for name: :foo/name, :bar/name; and then use them in map specs, but inside :req-un (or :opt-un), with the only requirement of keeping (name kw) identical

misha06:09:47

(s/def :foo/id int?)
(s/def :bar/id string?)
(s/def :foo/thing (s/keys :req-un [:foo/id]))
(s/def :bar/thing (s/keys :req-un [:bar/id]))

(s/valid? :foo/thing {:id 1})
=> true
(s/valid? :foo/thing {:id "one"})
=> false

(s/valid? :bar/thing {:id "one"})
=> true
(s/valid? :bar/thing {:id 1})
=> false

przemek07:09:47

hell yes 🙂 That looks like what I was looking for. I makes sense to document more how namespacing looks in action. I am gonna try this one in a moment. thanks

przemek07:09:58

it works. I guess for Datomic that :xxx/yy pattern is heavily used (I have not used it though). thanks again!

jmglov07:09:21

Is there anyone here who can shed any light on my customer generator for an atom holding a map? https://clojurians.slack.com/archives/clojure-spec/p1474549130002028

jmglov07:09:38

Or is this something better posted to the mailing list?

przemek08:09:11

Another question. Given this definition (s/def ::email (s/and string? #(re-matches email-regex %))) I am not able to generate a sample getting "Couldn't satisfy such-that predicate after 100 tries".

przemek08:09:47

Ok. Solved. Found a paragraph in the guide on custom generators.

przemek10:09:14

@madstap thx, will look at that. I managed to build a custom gen, but this is more elegant

jfntn13:09:52

@misha good catch, thanks!