This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-02-17
Channels
- # beginners (106)
- # cider (20)
- # cljs-dev (4)
- # cljsrn (1)
- # clojure (65)
- # clojure-austin (7)
- # clojure-canada (2)
- # clojure-russia (1)
- # clojure-spec (28)
- # clojure-uk (2)
- # clojurebridge (1)
- # clojurescript (32)
- # datomic (8)
- # docs (1)
- # emacs (27)
- # events (7)
- # fulcro (13)
- # garden (1)
- # hoplon (3)
- # leiningen (4)
- # luminus (2)
- # off-topic (32)
- # onyx (4)
- # parinfer (6)
- # pedestal (16)
- # re-frame (7)
- # reagent (5)
- # shadow-cljs (8)
- # spacemacs (2)
- # uncomplicate (4)
- # vim (3)
Is there a way to ensure two values are the same in a structure with spec? I didn't see anything in the spec docs (but maybe I missed it). I'd like to define a spec :account/by-id
that specs data like this:
{-5 {:db/id -5 :account/title "customer five"}}
Here's what I've got so far:
(s/def :db/id (s/or :db/id int? :uuid uuid?))
(s/def :account/title string?)
(s/def ::account (s/keys :req [:db/id :account/title]))
(s/def :account/by-id (s/map-of :db/id ::account))
but gen/generate
gives me stuff like this:
{7 {:db/id -5 :account/title "customer five"}}
@bmaddy look at s/and
to add a constraint
(s/def :account/by-id (s/and (s/map-of :db/id ::account) db-id-matches))
where db-id-matches
checks that the values matchThanks @seancorfield, that's what I was missing!
then you'll have to modify the generator too, to just copy the id from the key spot to the attribute spot
I'm trying to add clojure.spec.test.alpha/check
based testing to my clojure.test
tests, but the integration doesn't seem trivial. Do I have to write my own transform of the check
map to some sensible assert or is there a lib for that out already?
that's asked a lot; I don't know if anybody's published anything. but in any case doing the integration manually should be just barely nontrivial
I mean I can whip up something. I have to note that one thing that is very confusing is the :failure
key in the return map
it comes back set to false
on a failed check
this will probably confuse a lot of people
yes there's a ticket about that
There seems to be a curious mix of namespaces in the returned maps as well: To get predicate that failed you need to get:
(-> (stest/check `fnsym)
:clojure.spec.test.check/ret
:result-data
:clojure.test.check.properties/error
(.getData)
:clojure.spec.alpha/problems
(get 0)
:pred)
Goes from spec
to test.check
back to spec
keys.yeah, I think spec is currently embedding data in an ExceptionInfo object because test.check didn't used to have a mechanism for adding any info to a failure
I thought it was being unwrapped somehow though
I'm trying to do spec-and-test driven development in ClojureScript, and specs are not resolving like I expect them to. This test (https://github.com/mathpunk/sherman/blob/master/test/sherman/grammar_test.cljs#L13) passes if I uncomment the specification above it, but fails as is, with the specification in another namespace (https://github.com/mathpunk/sherman/blob/master/src/sherman/grammar.cljs#L7)
@mathpunk Your test namespace does not require
the namespace containing the spec -- how would it know about it?
@seancorfield thanks! Since the name of the spec has the namespace in it, I didn't realize the test namespace still needed to require it
You need to load the namespace for the s/def
to be executed, otherwise the spec isn't defined -- the keyword is just a keyword.
Also, spec names (keywords) have no connection to code namespaces (except insofar as the ::
alias resolution works).
wow! ok, I thought they were somehow being 'registered' in a way that needed to match the namespaces
s/def
and s/fdef
are the functions that perform the registration and the spec name just needs to be as globally unique within your application as it needs to be in order to not clash with any other specs.
Namespace-qualified keywords have been around for a long time before spec and have never been tied to code namespaces. For example, we use :ws.web/config
as a key in Ring requests in our applications for our application configuration map -- but we don't have a ws.web
namespace.
You can also set up aliases without needing code namespaces to match:
(alias 'm (create-ns 'ws.domain.member))
(alias 'mu (create-ns 'ws.domain.member.update))
(alias 'mv (create-ns 'ws.domain.member.validation))
The first one is used for specs (`::m/username` for example), the other two are just used as part of unique keys in maps.(it just so happens we do have code namespaces matching those, but where we use the aliases, we don't need the functions or specs from those namespaces so we don't require
the namespaces)
(hope that helps @mathpunk?)
@seancorfield Thank you, it does