This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-01-07
Channels
- # aws (2)
- # bangalore-clj (4)
- # beginners (62)
- # boot (74)
- # cider (408)
- # cljsrn (17)
- # clojure (117)
- # clojure-dusseldorf (1)
- # clojure-russia (21)
- # clojure-spec (17)
- # clojure-uk (15)
- # clojurescript (154)
- # cursive (3)
- # datomic (16)
- # emacs (33)
- # funcool (3)
- # hoplon (99)
- # off-topic (7)
- # om (10)
- # overtone (3)
- # portland-or (1)
- # protorepl (9)
- # re-frame (83)
- # reagent (11)
- # remote-jobs (1)
- # ring-swagger (24)
- # specter (10)
- # untangled (1)
- # yada (11)
here is my code:
(defrecord Car [name type num-of-wheels make])
(def car-types [:sedan :suv :truck :big-truck])
(s/def ::name string?)
(s/def ::type (s/spec keyword? :gen #(gen/elements car-types)))
(s/def ::num-of-wheels (s/and int? (s/int-in 4 18)))
(s/def ::make string?)
(defn namespaced-kwd-map->kwd-map
[map]
(reduce-kv (fn [acc k v]
(assoc acc (keyword (name k)) v))
{} map))
(defn car-gen
[]
(gen/bind
(s/gen (s/spec (s/keys :req [::name ::type ::num-of-wheels ::make])))
#(gen/return (map->Car (namespaced-kwd-map->kwd-map %)))))
(s/def ::car (s/spec record? :gen car-gen))
(gen/generate (car-gen))
(s/exercise ::car 6)
this works
(map second (s/exercise ::car 6))
=>
(#exercises.spec_validation.Car{:name "", :type :big-truck, :num-of-wheels 8, :make ""} #exercises.spec_validation.Car{:name "", :type :suv, :num-of-wheels 10, :make "o"} #exercises.spec_validation.Car{:name "E9", :type :suv, :num-of-wheels 12, :make ""} #exercises.spec_validation.Car{:name "W", :type :sedan, :num-of-wheels 4, :make "yfo"} #exercises.spec_validation.Car{:name "", :type :truck, :num-of-wheels 5, :make "3l6a"} #exercises.spec_validation.Car{:name "Q5Og", :type :truck, :num-of-wheels 13, :make "w6F4r”})
(drop 198 (s/exercise ::car 200)
gives me this error:
ExceptionInfo Couldn't satisfy such-that predicate after 100 tries. clojure.core/ex-info (core.clj:4725)
also i just started playing around with clojure spec today so the code might not be the best. any advice on making it better would be awesome! thanks.
@dhruv1: change num-wheels to just int-in -- the problem is that it can randomly generate int? values that aren't in 4..17
The int-in spec will do what you want without int?
someone who can help me figure out why if I have tests in my code , proto-repl will not be at a point I can work with it.
Here are my settings for proto-repl : https://ibin.co/382ffGMbsY5p.png and https://imagebin.ca/v/382fuFWaO18T
I ask this because this fail message of a test :
{:spec
(fspec
:args
(cat :artObject :paintings2.api-get/artObject)
:ret
:basic/output
:fn
nil),
:sym paintings2.api-get/get-data-front-page,
:failure
{:clojure.spec/problems
({:path [:ret :name],
:pred string?,
:val nil,
:via [:paintings2.api-get/name],
:in [:name]}),
:clojure.spec.test/args
({:objectNumber "AA-A-0",
:principalMakers [],
:title "",
:description "",
:dating {:year 1900},
:objectCollection "",
:colors []}),
:clojure.spec.test/val {:id "AA-A-0", :name nil, :title ""},
:clojure.spec/failure :check-failed}}
@seancorfield ah i see. thank you!
The function looks like this :
(defn get-data-front-page
"Reads the title, description, date , collection, colors and url of a image"
[art-object]
(let [name (-> art-object
:principalMakers
first
:name)
id (:objectNumber art-object)
title (:title art-object)
checked (s/conform ::artObject art-object)]
(if (s/invalid? checked)
(throw (Exception. "Something wrong with the front-apage"))
{:id id :name name :title title})))
so the function returns a exception with the text "Something wrong with the front-page" or the object {:id id :name name :title title})))
which has the name :basic/output
Specs only talk about non-exceptional outcomes
when I do this : (stest/summarize-results (stest/check 'paintings2.api-get/get-data-front-page))
I see this spec message :
{:spec
(fspec
:args
(cat :artObject :paintings2.api-get/artObject)
:ret
:basic/output
:fn
nil),
:sym paintings2.api-get/get-data-front-page,
:failure
{:clojure.spec/problems
({:path [:ret :name],
:pred string?,
:val nil,
:via [:paintings2.api-get/name],
:in [:name]}),
:clojure.spec.test/args
({:objectNumber "AA-A-0",
:principalMakers [],
:title "",
:description "",
:dating {:year 1900},
:objectCollection "",
:colors []}),
:clojure.spec.test/val {:id "AA-A-0", :name nil, :title ""},
:clojure.spec/failure :check-failed}}
so I assumed that because :name nill the principalMakers are empty so there is no name
Not without your spec
@alexmiller here are all the specs :
(s/def ::id (s/and string? #(re-matches #"[A-Z]{2}-[A-Z]-\d{1,4}" %)))
(s/def ::objectNumber (s/and string? #(re-matches #"[A-Z]{2}-[A-Z]-\d{1,4}" %)))
(s/def ::name string?)
(s/def ::title string?)
(s/def ::description string?)
(s/def ::year (s/int-in 1900 2018))
(s/def ::objectCollection string?)
(s/def ::colors (s/coll-of string?))
(s/def :basic/output
(s/keys :req-un [::id ::name ::title]))
(s/def ::dating (s/keys :req-un [::year]))
(s/def ::principalMakers (s/coll-of (s/keys :req-un [::name])))
(s/def :basic/artObject
(s/keys :req-un [::objectNumber ::principalMakers ::title]))
(s/def :detail/artObject
(s/merge :basic/artObject (s/keys :req-un [::description ::dating ::objectCollection ::colors])))
(s/def ::artObject
(s/or :basic :basic/artObject :detail :detail/artObject))
(s/def :artObject/body
(s/keys :req-un [::artObject]))
(s/def :artObject/response
(s/keys :req-un [:artObject/body]))
; spec to test some functions
(s/fdef get-objectNumbers
:args (s/cat :response :artObject/response)
:ret (s/coll-of ::objectNumber))
(s/fdef get-art-object
:args (s/cat :response :artObject/response)
:ret ::artObject)
(s/fdef get-data-front-page
:args (s/cat :artObject ::artObject)
:ret :basic/output)
(s/fdef get-data-detail-page
:args (:artObject :artObject)
:ret :detail/artObject)
; some custom generators
(s/def ::id
(s/with-gen ::id
(fn [] (gen'/string-from-regex #"([A-Z]{2}-[A-Z]-\d{1,4})"))))
(s/def ::objectNumber
(s/with-gen ::objectNumber
(fn [] (gen'/string-from-regex #"([A-Z]{2}-[A-Z]-\d{1,4})"))))
Actually it say your name is nil but the spec is string?
on a valid input this schould be the output :
{:name "Rembrandt Harmensz. van Rijn",
:title "Schutters van wijk II onder leiding van kapitein Frans Banninck Cocq, bekend als de ‘Nachtwacht’",
:id "SK-C-5"}
Because :principalMakers is []
and when I exercise :name I see this :
(["" ""]
["5" "5"]
["v9" "v9"]
["b" "b"]
["t1W" "t1W"]
["2" "2"]
["" ""]
["jBVPdA" "jBVPdA"]
["h27h5" "h27h5"]
["" ""])
yep. but is it not true that this spec : (s/def ::principalMakers (s/coll-of (s/keys :req-un [::name])))
is taken care that principalMakers cannot be a empty vector ?
No that's valid
But you can use :min-count 1
In coll-of to make your spec more precise
There are other options to coll-of as well
Just at the end
It takes kwarg options
There are examples in the guide http://clojure.org/guides/spec
This is right : (s/def ::principalMakers (s/coll-of (s/keys :req-un [::name] :min-count 1)))
No - that's in s/keys
You want it in s/coll-of
So one paren to the right