This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-12-27
Channels
- # ai (4)
- # beginners (102)
- # boot (216)
- # cider (20)
- # cljs-dev (9)
- # clojure (130)
- # clojure-russia (4)
- # clojure-spec (9)
- # clojure-uk (11)
- # clojurescript (59)
- # core-async (2)
- # cursive (10)
- # datomic (51)
- # figwheel (1)
- # flambo (3)
- # hoplon (2)
- # luminus (1)
- # om (17)
- # om-next (4)
- # onyx (2)
- # perun (2)
- # re-frame (79)
- # ring (5)
- # ring-swagger (9)
- # rum (3)
- # schema (3)
- # specter (9)
- # untangled (3)
- # vim (1)
Hi, I have the following scenario:
(s/def ::name string?)
(s/def ::person (s/keys :req-un [::name]))
(s/def ::name (s/and string? #(str/starts-with? % "Jean")))
(s/def ::french-person (s/keys :req-un [::name]))
I want to keep these specs in the same file, but I also want to disambiguate the different ::name specs, without giving them different names. Is there any way to do this? Something like ::french/name
vs just ::name
, but that isn't working.@mpenet Cool, thanks! Can I create a concatenation of the "current" ns with a symbol using create-ns
?
I want to test a function that has as input something like this : [{ :name "Roelof", :place "internet"} {:name "Jane Doe" :place "unknown" }]
and as output {"Roelof", "Jane Doe"}
. If I want to test this , can I use the same idea as this :
(def email-regex #"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,63}$")(s/def ::email-type (s/and string? #(re-matches email-regex %)))(s/def ::acctid int?)(s/def ::first-name string?)(s/def ::last-name string?)(s/def ::email ::email-type)(s/def ::person (s/keys :req [::first-name ::last-name ::email] :opt [::phone]))
Perhaps your question is constructed in a way that makes answering it a bit difficult. For example, “input something like this” is ambiguous — are there always two maps in the input vector, or might there be more? And, do you really mean to have a single k/v pair map as the output, where both the key and value are strings? Or did you mean to make that a vector of the :name
s from the input? It’s clearing up this confusion that results in the things the admins don’t want in the channel, I think.
But here’s some info that might be valuable to anyone new to spec, just a sample of how to construct what you’re asking for. What you want to do is ask, “what am I trying to spec”? In your case, it’s a function which takes a vector of maps, and returns a vector of strings. Those are your :args
and :ret
, and a decent sanity check for :fn
is that the number of names you return should equal the number of maps you were given. So, here’s a spec based on that:
(ns clj.core
(:require [clojure.spec :as s]
[clojure.spec.gen :as gen]
[clojure.spec.test :as stest]))
(defn get-names [v]
(reduce #(conj % (:name %2)) [] v))
(s/def ::name string?)
(s/def ::place string?)
(s/def ::get-names-args (s/coll-of
(s/keys :req-un [::name ::place])
:kind vector?
:gen-max 5))
(s/fdef get-names
:args (s/cat :v ::get-names-args)
:ret (s/coll-of string? :kind vector?)
:fn (fn [{{input-vector :v} :args, return-vector :ret}]
(= (count input-vector) (count return-vector))))