Fork me on GitHub
#clojure-spec
<
2017-07-17
>
danielcompton00:07:35

@lwhorton I don't think you can spec protocols, the recommendation I got at the time was to create a regular function in front of the protocol function and spec that

lwhorton00:07:52

congratulations by the way. i hope you have a heck of a time with the kiddo. I’‘ll certainly miss The REPL.

danielcompton02:07:53

I won't be gone for too long 🙂

lwhorton00:07:27

yea .. that’s what I’m rolling with. I probably wasn’t clear, but in my question I’m trying to address the issue with trying to test.check multiple “regular functions in front of the protocol function” for each possible argument type

lwhorton00:07:03

as @seancorfield mentions, they’re open for extension so you can’t cover every base. that being said, i’m only trying to cover my particular bases.

rickmoynihan09:07:48

Worth remembering also that you can spec that the value your wrapping fn receives satisfies? the protocol. You’ll need to write a custom generator to generate conforming values for each of the implementations you care about though. You don’t get that for free like you do with multi-spec.

rickmoynihan09:07:28

This said if your implementations had a common construction interface… e.g. they all took a string as a single argument to their constructor, you could easily write a dynamic generator by inspecting the protocol i.e. by using (keys (:impls foo.bar/Protocol))

rickmoynihan09:07:54

then mapping the implementation classes to constructors/generators

samueldev11:07:21

does anybody have any specs around HTML5 filetypes?

samueldev11:07:50

I have a fn I'd like to spec but am currently omitting spec'ing one particular argument, which I'm expecting to be an HTML5 File/Blob

samueldev11:07:28

@bbrinck hey ben, do I have to do anything special to make expound work in CLJS?

samueldev11:07:38

nvm I didn't realize the transition from cljs.spec -> cljs.spec.alpha

samueldev11:07:43

had happened

samueldev11:07:46

all good now 🙂

bbrinck14:07:59

@samueldev I’ll add that to the README

bbrinck14:07:43

A user has also reported a issue on CLJS 1.9.671 (I had been testing on CLJS 1.9.542). Just FYI: https://github.com/bhb/expound/issues/3

samueldev15:07:00

@bbrinck using the lib and converted all my spec explains to yours this morning; quite pleased 🙂

samueldev15:07:19

its aim seems to be to output developer-friendly error messages; have you considered the use case of going all the way and having it output non-developer-friendly error messages, that can be presented to an end-user? for example if I'm doing some simple validation on a POST route in my API to create an entity, and they omit a required key, an output-string provided along the lines of "Missing required key: _____"

samueldev15:07:55

as it stands now, I'm using regular spec explains and iterating over the problems and generating these strings

samueldev15:07:43

(with some hard-coded mappings from something like a str? predicate failing --> a string being generated along the lines of "Value provided for key ____ must be a string."

samueldev15:07:09

this is something I've considered lib-ifying for my own sake but could instead PR it into expound perhaps, if you see value in it

bbrinck16:07:27

Yes, in the future, I want to have good defaults for a number of contexts: test failures, REPL, end-user, etc

bbrinck16:07:15

That won’t replace the current error message, but it’ll either be another namespace or perhaps some way to configure expound

bbrinck16:07:57

But more generally, I want to extract out a set of helper functions that work on clojure.spec.problems such that you can trivially build your own custom string representation without dealing with all the details of spec

bbrinck16:07:23

That way, if you don’t like the default “user-facing” error message, you can peek underneath and see how its built and build your own.

bbrinck16:07:26

@samueldev If you want to create a GH issue with an example of a spec, a value, and the error string you’d like to see for a user-facing error, that would be very helpful!

adamfrey15:07:17

for a spec that can potentially generate huge values (like giant nested maps with long keywords), what is the most efficient way to get a small values (for playing around with at the repl)

schmee15:07:19

for some reason, my spec errors are printed without newline, which makes them completely unreadable:

:error-while-loading kleinheit.datomic.impl
#error {
 :cause "Call to clojure.core/refer-clojure did not conform to spec:\nIn: [2 1] val: :as fails at: [:args :exclude :op :quoted-spec :spec] predicate: #{:exclude}\nIn: [2 1] va......

schmee15:07:28

any idea what might cause this?

bbrinck16:07:19

@schmee It looks like you’re printing out the entire error record. Is it possible to just get the :cause and print that?

schmee16:07:40

I hope so 😄

schmee16:07:51

I don’t get why it prints the whole error record in the first place

bbrinck16:07:06

Sorry, what is “it”?

schmee16:07:23

lein repl 🙂

bbrinck16:07:24

Ah, I see. Can you perhaps write a wrapper function that calls the function in a try/catch?

bbrinck16:07:23

I have not tested this, but you could

bbrinck16:07:43

@schmee Or, after you see an error like that, could you just do something like (println (:cause (ex-data *e))) to print out the cause of the last error?

schmee16:07:10

I suppose so, but I would prefer if I could get the REPL to always do that for me

bbrinck16:07:11

(just put that on the REPL after the error has been caused)

bbrinck16:07:40

@schmee I haven’t tried this, but it looks like lein let’s you configure the error handler https://github.com/technomancy/leiningen/blob/master/sample.project.clj#L357-L370. Note that by only printing the cause, you’ll presumably be losing other contextual information about the error, which may or may not be useful.

bbrinck16:07:12

In any case, this isn’t really related to spec, so you may have more luck tracking down an answer in #leiningen . Good luck!

schmee16:07:35

ahh, now that’s what I’m looking for, thanks! 😄

schmee17:07:43

is there a “recursive” version of describe, that resolves non-fn specs?

schmee17:07:42

what’s the easiest way to constrain a s/cat into a vector?

schmee17:07:06

(s/and vector? (s/cat ...)) seem to fail to generate data with exercise

schmee17:07:48

here’s how I’m doing it now, just curious if there is a better way:

(spec/def ::pred* (spec/cat :k any? :pred any?))
(spec/def ::pred (spec/with-gen (spec/and vector? ::pred*) #(gen/fmap vec (spec/gen ::pred*))))

bbrinck18:07:24

@schmee My understanding is that vector sequences is a known problem that isn’t yet solved: https://clojurians.slack.com/archives/C1B1BB2Q3/p14988354

bbrinck18:07:15

Or, perhaps I should say “regex specs that are also vectors”

gfredericks18:07:18

I feel like in some platonic sense the regex specs fit seqs much more than vectors but that doesn't mean it wouldn't be terribly useful to have regexes for vectors

gfredericks18:07:30

probably mostly/entirely for macros?

bbrinck18:07:32

I’ve also had use cases when using conform/unform on vectors

bbrinck18:07:47

We have cases where we like the succinctness of using vectors e.g. something like hiccup: [:p {} "hi"]. When we manipulate it, it’s handy to have named parts by using a regex spec, but then we can unform it back to the vector form

bbrinck18:07:22

Right now we have to unform, then convert the list to a vector

schmee18:07:28

yeah, a catv would be nice

schmee18:07:35

is there a JIRA or something for this?

schmee19:07:41

cheers 👍

taylor19:07:00

are there/will there be specs for the return values of explain-data?

schmee19:07:17

there’s a JIRA for “specs-for-spec”: https://dev.clojure.org/jira/browse/CLJ-2112

lwhorton21:07:05

@schmee I was doing exactly that yesterday with clojure.test.check.generators and the gen/vector api.

lwhorton21:07:43

you can define the spec with (s/with-gen (s/cat ...) and hand the with-gen something that always returns a vec