This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-08-29
Channels
- # admin-announcements (2)
- # beginners (20)
- # boot (139)
- # cider (6)
- # clara (1)
- # cljs-dev (7)
- # cljsrn (4)
- # clojure (160)
- # clojure-berlin (1)
- # clojure-canada (6)
- # clojure-gamedev (1)
- # clojure-japan (7)
- # clojure-russia (14)
- # clojure-spec (90)
- # clojure-uk (10)
- # clojurescript (73)
- # clojutre (1)
- # conf-proposals (8)
- # crypto (67)
- # cursive (9)
- # datomic (6)
- # editors-rus (1)
- # events (1)
- # figwheel (6)
- # funcool (2)
- # hoplon (19)
- # instaparse (37)
- # kekkonen (4)
- # lein-figwheel (2)
- # leiningen (5)
- # luminus (1)
- # off-topic (1)
- # om (10)
- # onyx (60)
- # protorepl (2)
- # re-frame (81)
- # reagent (10)
- # ring-swagger (15)
- # rum (6)
- # specter (17)
- # test-check (10)
- # uncomplicate (31)
- # untangled (12)
- # yada (6)
next question: is there an ad hoc way to supply a :gen
for function :args
to stest/check
?
I see you can s/def
the args, then supply a gen. I'm not opposed to the notion that you must name something to use it elsewhere (even if that elsewhere is a test), but I thought there might be some sugar out there.
Is there any chance of a with-instrument macro, and/or a clojure.test + clojure.spec.test.check deftest macro a la defspec with test.check? (Too many similarly named words; I feel like I screwed that up)
We just started really looking into clojure.spec last week, and while we are still figuring out how to best leverage it, I definitely agree that a clojure.test integration and a with-instrument macro sound like useful additions.
Hm, I am not sure, but, so far I would want to have everything instrumented during my tests
Yes, in general, you want to have everything instrumented. However, if you are using stubs or overriding specs, you may only want to do that within the scope of a few checks.
Hey! I'm trying to cryptographically sign data structures in Clojure/ClojureScript. The approach I am taking is to serialize my structures into a canonical form - namely recursively sorting the keywords of every hash-map in the structure, prior to serializing with transit. (1) Is there already something that does this for me?
(3) If there isn't a better way, how do you enforce that a data structure is canonical in spec
?
I’m personally using nippy, but I don’t think that has any particular canonical form guarantees
@xcthulhu How do you keep the hash-map structure in the serialized form whilst being sorted?
Serialized form comes after the thing is canonical. Yeah, I've gone to pretty extreme lengths to keep all of my signatures deterministic.
I'm doing ECC in ClojureScript and I don't believe I can get a reasonable secure RNG without resorting to RFC 6979
Sure; when you say canonicalizing a data structure the first things that come to mind are ASN.1 C(X)ER
Fortunately RFC 6979 + ed25519 is how you’d want to do it anyway regardless of how much you care about that determinism 🙂
Right now, I'm just publishing a JAR - https://github.com/Sepia-Officinalis/secp256k1
(The devil’s advocate argument against JS crypto usually goes by how you ship the source to begin with)
Because I started this when I was doing consulting for digital currency and it's what everyone uses because of BitCoin
@fenton A thing I’ve done previously with schema is wrap a channel with a validation to check anything put into the channel conforms to the schema. This causes exceptions to be thrown where you’re putting the unexpected value onto the channel which is really useful. Sure you could do the same thing with spec if you wanted to.
@lfn3 re doc string, not currently but feel free to vote on http://dev.clojure.org/jira/browse/CLJ-1965
@lvh re with-instrument, if you wanted to log a jira, that would help us remember this idea (seems quite reasonable)
@fenton https://gist.github.com/lfn3/0aaf4c420df206484372e9b7bbbe6c6f <- demo of using specs to validate things put on channels.
if I have a vector of maps:
(def accounts
[{:name "Foo"} {:name "Bar"} {:name "Baz"}])
How do I define a spec that confirms to be one of the names, e.g.:
(s/def ::account-name ,,,)
: so when I do:
(gen/generate (s/gen ::account-name))
it would generate something like :account-name “Baz”
Hello all. I'm stuck at defining a map with undefined keys with clojure.spec. For instance, I'm defining a map with keyword keys and string values. I can define it as below with Schema library:
(require '[schema.core :as schema])
(def Data {schema/Keyword schema/Str})
(schema/validate Data {:x "str"})
> {:x "str"}
(schema/validate Data {:x 0})
> ExceptionInfo Value does not match schema: {:x (not (matches-some-precondition? 0))} schema.core/validator/fn--8583 (core.clj:155)
How can I define such a map with clojure.spec?@emrehan map-of
http://clojure.github.io/clojure/branch-master/clojure.spec-api.html#clojure.spec/map-of (s/def ::a-map (s/map-of keyword? string?))
what if I have a collection and want a spec that satisfies for one of the items in the collection? e.g.
(def accounts
[{:name "Foo" :type :foo}
{:name "Bar" :type :bar}
{:name "Baz" :type :baz}])
(s/def ::foo-or-bar-or-baz #_(any of those))
@ag not sure what you're saying, could you give a (s/valid ::account-name ...) => true example? also is accounts
known at spec definition time?
so when I do (gen/generate (s/gen ::foo-or-bar-or-baz))
it would give me one of the maps of accounts
vector
assuming accounts
is known at spec definition time, and accounts
is reasonably small, then (s/def ::foo-or-bar-or-baz (set accounts))
Is there a nice way to combine to clojure.spec definitions? I have a definition that must conform two defined schemas and I defined it as below:
(s/def ::spec3 (s/and #(s/valid? ::spec1 %) #(s/valid? ::spec2 %)))
Is there a better way to define this?I didn’t look at the spec but I tried that form. It didn’t work, maybe I’m missing something.
if ::spec1 conforms then the conformed value will be passed to ::spec2 instead of the original value
I think s/and conforming with the first spec has tripped a few people up so the docstrings are probably being worked I imagine. iirc the guide does cover it though
(s/def ::type (s/or :string string? :number number?))
(s/def ::a-map (s/map-of keyword? ::type))
(s/def ::id int?)
(s/def ::with-id (s/keys :req-un [::id]))
(s/def ::metadata (s/and #(s/valid? ::a-map %) #(s/valid? ::with-id %)))
(s/valid? ::metadata {:id 1 :n 1 :s "dsa"})
> true
(s/def ::metadata (s/and ::a-map ::with-id))
(s/valid? ::metadata {:id 1 :n 1 :s "dsa"})
> false
(s/def ::metadata (s/and any? ::a-map ::with-id))
(s/valid? ::metadata {:id 1 :n 1 :s "dsa"})
> false
It seems to me that s/and passes the return value of (s/conform ::a-map {:id 1 :n 1 :s "dsa"})
to the second conform. However, the when s/or
is conformed the return value is different from the input.
yes, conforming means changing the value to explain how it is true given the spec, ie if the spec has a branch
boot.user=> (s/conform any? {:id 1 :n 1 :s "dsa"})
{:id 1, :n 1, :s "dsa"}
boot.user=> (s/conform (s/and any? ::a-map) {:id 1 :n 1 :s "dsa"})
{:id [:number 1], :n [:number 1], :s [:string "dsa"]}
boot.user=> (s/conform (s/and any? ::a-map ::with-id) {:id 1 :n 1 :s "dsa"})
:clojure.spec/invalid
anyway, you have options. if you want to preserve the conforming behaviour, I would just re-order your predicates so that ::with-id comes first. if you want to do away with it then creating a new predicate with #(s/valid? ::a-map %) just around the spec that you don't want to conform anymore seems sensible
boot.user=> (s/valid? (s/merge ::a-map ::with-id) {:id 1 :n 1 :s "dsa"}) true boot.user=> (s/conform (s/merge ::a-map ::with-id) {:id 1 :n 1 :s "dsa"}) {:id 1, :n 1, :s "dsa"}
merge
appears to conform using the last spec. is that right @alexmiller ?
boot.user=> (s/conform (s/merge ::with-id ::a-map) {:id 1 :n 1 :s "dsa"})
{:id [:number 1], :n [:number 1], :s [:string "dsa"]}
Merge does not flow conformed values like and, it's more like union
is it possible to have “inlined” spec in keys
I don’t think it’s working for me.
(s/def ::foo (s/keys :req [(s/def ::bar string?)]))
@bfabry s/and has always flowed conformed values. We may change it to not flow and add s/and-> still as both are sometimes useful
@ag s/keys always requires registered keys - that's part of the design that is talked about at http://clojure.org/about/spec