This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-03-23
Channels
- # beginners (63)
- # cljs-dev (1)
- # cljsjs (1)
- # cljsrn (11)
- # clojure (208)
- # clojure-berlin (2)
- # clojure-dusseldorf (5)
- # clojure-italy (5)
- # clojure-norway (56)
- # clojure-russia (7)
- # clojure-spec (85)
- # clojure-uk (27)
- # clojurescript (191)
- # core-async (73)
- # cursive (4)
- # datomic (62)
- # defnpodcast (1)
- # hoplon (2)
- # jobs-rus (1)
- # juxt (14)
- # keechma (1)
- # leiningen (1)
- # lumo (126)
- # off-topic (2)
- # om (11)
- # onyx (27)
- # pedestal (52)
- # planck (21)
- # powderkeg (1)
- # re-frame (32)
- # reagent (14)
- # ring-swagger (1)
- # rum (3)
- # slack-help (19)
- # specter (23)
- # untangled (32)
- # vim (7)
- # yada (43)
Hi, I am trying to do a simple function check using spec in ClojureScript (:require [cljs.spec :as s] [cljs.spec.test :as test]... (defn my-index-of "Returns the index at which search appears in source" [source search] (clojure.string/index-of source search)) (s/fdef my-index-of :args (s/cat :source string? :search string?) :ret nat-int? :fn #(<= (:ret %) (-> % :args :source count))) and (test/check 'my-index-of) instead of returning a problem , always returns [] meaning basically that it doesn't do anything?
I am basically trying this in ClojureScript https://www.youtube.com/watch?v=W6crrbF7s2s
this however fails with CompilerException java.lang.Exception: Unable to resolve spec: :user/y, ...
(deftype MySpec []
s/Spec
(conform* [_ x]
::s/invalid))
(s/def ::x (MySpec.))
(s/explain ::x :foo)
@alexmiller is that a bug? I suspect the problem is in with-name
which is called in def-impl
. deftype
isn't IObj
, defrecord
is, as is reify
which is used everywhere in spec
I've added a keyz
spec that's like s/keys
but with :deny :rest
that will allow only keys in :req, :req-un, :opt and :opt-un
https://github.com/yonatane/spec-grind/blob/master/test/spec_grind/grind_test.clj#L67
It's currently just a hack and doesn't have nice explain data. That will require implementing Spec just for the deny part.
@yonatanel was that intended for me?
not exactly the same thing, but I thought about adding the do not allow unspecified keys
thing
I just have a bunch of old data and otherwise open maps that I can't easily create namespaced keys for
Regarding just using s/and
I am doing it, combining s/keys
and a set predicate on the map keys, but the explain message is crap.
ah right, well if you stick to defrecord
and avoid the headache that caused the impl for explain/conform is rather straightforward
@thheller Got you. I wanted to do the same thing, so would be nice if you release your inlined map spec in github.
@thheller spec-tools have something similar that you might find interesting: https://github.com/metosin/spec-tools
I like how you implemented explain unlike spec which creates a contains? pred for each key.
I have to validate a datastructure that already exists in some systems that's a) not using namespaced keys b) not always using keywords as the keys for maps
and sometimes the value types of the (non-namespaced) keys are conditional on something else
i.e.
{:job-type :simple
:output "is a string}
{:job-type :complicated
:output {:is "a map of something}}
@yonatanel added the closed version
(s/def ::y (map-spec :req {:foo string?} :closed? true))
(s/explain ::y {:foo "1" :x 1})
might not be the best idea but I want to use that to validate react component props, it might actually be better to use closed maps there
@thheller Do you think the closed map explain data should show all the allowed keys instead of just the illegal one from the input?
@yonatanel I tried using a multi spec that points and keys
specs in different namespaces but that seemed to not work the way I needed
ohhh, I guess I could probably s/def with namespaced keywords instead of using :: to autoresolve?
@yonatanel not sure about the explain data, good error messages are hard. could put anything in there really
@hospadar i think that’s typical usage as specs are meant to augment a separate namespace that contains the keywords
how does clojure.spec/instrument
play with direct linking?
wondering if someone has tried that before I go and play with it
it won’t do anything
because direct linking doesn’t use vars
@alexmiller got me a little confused there. by “won’t do anything” do you mean it won’t instrument or it won’t be impacted by direct linking?
I mean it won’t instrument
or rather it will instrument, but direct linked calls don’t use either the original var or the instrumented var, so instrumentation will have no effect on those call sites
new, non direct linked invocations will use the instrumented vars
@thheller re your question yesterday, there is an implicit assumption in the code that spec impls also implement IObj. so in one sense, I’d say your example is at fault of that. And in another sense that spec code could fall through to throwing an error in that case to better let you know that.
thanks
Agreed. We only enable direct linking on QA/prod. It gets in the way of REPL-driven development.
@alexmiller didn't know about the implicit assumption about IObj, took me about 2h to figure that out. an error would have helped a lot.
Ticket would be fine
@mpenet right, there are no plans to change wrt direct linking
@mpenet @seancorfield we have some functions for which we want to turn instrumentation on in prod, hence my question
we don’t have direct linking in dev
that would be my next question
we’re currently using Plumatic Schema
and we have (s/set-fn-validation! true)
for the namespace
apparently instrument won’t do what I expect it to
I would say that if you want the checks to always be performed (i.e., in production) then explicitly code that into the functions themselves — that gives you more control over the error handling anyway.
As @mpenet notes, even if you did instrument functions in production, any higher-order functions that get instrumented would trigger generative testing, and instrumentation doesn’t check function returns anyway, just arguments.
@anmonteiro would s/assert be a better choice for production code?
hrm I thought s/assert
‘s point was to be turned off in Prod
Currently I’m thinking about going with a combination of s/valid?
and s/explain
that we send to Sentry
Sounds sensible.