This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-10-31
Channels
- # bangalore-clj (3)
- # beginners (15)
- # boot (128)
- # cider (4)
- # cljs-dev (12)
- # cljsjs (1)
- # clojure (105)
- # clojure-austin (5)
- # clojure-canada (6)
- # clojure-italy (5)
- # clojure-russia (14)
- # clojure-spec (70)
- # clojure-uk (21)
- # clojurebridge (3)
- # clojurescript (264)
- # cloverage (6)
- # cursive (4)
- # data-science (6)
- # datomic (10)
- # dirac (5)
- # editors (30)
- # events (3)
- # hoplon (9)
- # klipse (7)
- # leiningen (3)
- # luminus (4)
- # off-topic (9)
- # om (5)
- # om-next (1)
- # onyx (1)
- # parinfer (2)
- # perun (28)
- # re-frame (5)
- # ring (1)
- # rum (11)
- # spacemacs (2)
- # specter (10)
- # sql (3)
- # uncomplicate (4)
- # untangled (67)
- # vim (2)
- # yada (1)
I feel like there's a missing flag on s/keys, something like 'complete' or {:allow-unspecified false} as an option. A couple of times while using s/check i've spelled something wrong, in the spec, or set a key badly in the transform code, and spec isn't yelling at me about it, despite everything being spec'd up, it comes down to this for me:
(s/def ::key integer?)
(s/def ::other integer?)
(s/def ::map
(s/keys :req [::key]
:opt [::other]))
(s/valid? ::map {::key 1 ::others "2"}) => true
I've clearly got this wrong (::others instead of ::other), but it's really easy to just not notice something like this, but if I could do this:
(s/def ::map
(s/keys :req [::key]
:opt [::other]
:complete true))
and have spec shout if it see's any key it's not ready for, then I'd be getting more out of my spec's! Just something that's bothered me this morning as i realised I'd mistakenly pluralised a key word 🙂The usual workaround is to combine the s/keys
spec with an s/map-of
spec
(I agree that a :complete
flag would be a welcome addition to the s/keys
macro, but Rich seems committed to open maps as the preferred general data structure)
specs always make positive statements about data, not negative ones and we do not plan to add anything to s/keys along these lines
however there is something we’re considering that would allow making these additional assertions easier
@donaldball that does work, but is pretty ugly isn't it. Sound like a 'wait and see' situation
It’s not a hard macro to write, a keys
variant that allows a complete?
flag
I get a caller, but I go to that line, and it's downstream from the function that :sym
references :thinking_face:
the fact that it’s printing unknown there is a known issue with describing preds
so that part is a known bug
but you have the path so it should be pretty narrowly scoped to where the pred is failing?
ok, that helps, so go through and perhaps exercise
my specs to see if anything's funny?
I'm probably doing this the worst way, by trying to migrate from schema instead of using on a fresh codebase
as with most programming things, it’s best to start small and build up
with a lot of side-effects, traditional unit-testing can work just fine, and I just want to make sure functions deep in the call stack are getting the right arguments and returning something valid
my impression after a couple weeks is that spec makes this some of this more difficult over, say, schema
and maybe that's the intent: lower-level, more correct, more powerful, etc., it just also means there aren't yet companion libraries to help with the porcelain
You don’t need to buy into generative testing to use clojure.spec. instrument
with traditional example-based tests is pretty useful.
@donaldball that was my early reaction as well, but I lost the ability to check return values, which I get, that's for check
, but then that forces me into the generative style
Alas, nothing public, sorry
IIRC clojure.java.jdbc uses this to good effect tho
@jrheard this thread was helpful in describing the philosophy https://groups.google.com/d/msg/clojure/JU6EmjtbRiQ/WSrueFvsBQAJ
and I think I agree, I just have the same desire as this guy https://groups.google.com/forum/#!msg/clojure/RLQBFJ0vGG4/E0tHqVyQBgAJ
@mattly: The link works for me with no google account signed in
(s/def ::select
(s/coll-of (s/or :attribute string?
:subselect (s/every-kv string? ::select :count 1))))
(clojure.pprint/pprint
(s/conform ::select
["1"
{"2" ["2.1"
{"2.2" ["2.2.1"]}]}]))
;; => [[:attribute "1"] [:subselect {"2" ["2.1" {"2.2" ["2.2.1"]}]}]]
Why does that inner ::select
clause not tagged the way the outer one is?You need conform-keys
Hmm, :conform-keys
is only listed as an option for map-of
but I would expect it to work here too...
Nope, only works with map-of
— but if you change :subselect
to be (s/map-of string? ::select :count 1 :conform-keys true)
then you get this
[[:attribute "1"]
[:subselect
{"2"
[[:attribute "2.1"] [:subselect {"2.2" [[:attribute “2.2.1”]]}]]}]]
Yeah, I think I misunderstood what you were saying didn’t work..
Is the output I got with map-of
what you want?
(You’re right, you don’t need :conform-keys
but you do need map-of
, not every-kv
)
Per the docs, every-kv
does not conform all values — map-of
does.
"Unlike 'every-kv', map-of will exhaustively conform every value."
"Note that 'every' does not do exhaustive checking, rather it samples
coll-check-limit elements. Nor (as a result) does it do any
conforming of elements.” — and every-kv
is like every
(I must admit, I find it counter-intuitive that every / every-kv do not in fact check every element but coll-of / map-of do)
After all, they have every in their name so you’d sort of expect them to check every item...
"every" is an assertion of belief
Not a statement of what they do