Fork me on GitHub
#clojure-spec
<
2021-09-21
>
johanatan19:09:40

is there ever a situation where the :ret value passed to a (failing) fdef :fn checker would diverge from the value you get when you run the function in question with the associated :args manually ?

johanatan19:09:50

(I'm seeing this currently and it's a bit baffling)

johanatan19:09:23

these are the reported values:

:cljs.spec.alpha/value
  {:args {:maps ({:A/A ""} {:A/A ""})}, :ret {:A/A " "}},

colinkahn04:09:41

I think unless it’s being conformed into that different value it will be the same. You could try doing:

(s/conform (:ret (s/get-spec `your-function)) {:A/A ""}) 
as a sanity check to make sure your spec isn’t changing it during conforming.

johanatan18:09:22

the :ret spec here is simply map?

johanatan18:09:18

but for completeness:

johanatan18:09:21

utils.utils=> (s/conform (:ret (s/get-spec `-merge-attribs)) {:A/A ""})
{:A/A ""}

johanatan18:09:44

could this be a bug in clojure spec ? it is in alpha after all. @U064X3EF3 ?

Alex Miller (Clojure team)18:09:40

sorry, can you re-explain?

johanatan18:09:59

is there ever a situation where the :ret value passed to a (failing) fdef :fn checker would diverge from the value you get when you run the function in question with the associated :args manually ?

johanatan18:09:11

these are the reported values:

:cljs.spec.alpha/value
  {:args {:maps ({:A/A ""} {:A/A ""})}, :ret {:A/A " "}},

johanatan18:09:31

this is the manual repl invocation of the function in question:

utils.utils=> (-merge-attribs '({:A/A ""} {:A/A ""}))
{:A/A ""}
the manual repl invocation is the "correct" one

johanatan18:09:57

Notice that the one reported by spec includes a \space and the one returned from the manual invocation is merely the empty string.

johanatan18:09:08

(the :ret that is)

Alex Miller (Clojure team)18:09:08

it seems like you're asking me a question about your function, not spec

Alex Miller (Clojure team)18:09:05

maybe there is more here than you can "see" - that "empty" string could have a Unicode non-breaking space or something in it

Alex Miller (Clojure team)18:09:36

or zero-width space, whatever that weird unicode thing is

Alex Miller (Clojure team)18:09:33

in general, my answer to your original question is no (unless you're using spec :stub instrumentation or something)

johanatan18:09:17

i think you misunderstood.

johanatan18:09:05

spec says that for some input a specific return value is returned. when i run that function manually in the repl with the exact same input a different value is returned.

johanatan18:09:24

i.e., "" != " "

johanatan18:09:30

regardless what that character is

johanatan18:09:38

empty string is empty string

johanatan18:09:45

" " is not empty string

Alex Miller (Clojure team)18:09:00

a 1-character string with a Unicode zero-width space character looks like an empty string

johanatan18:09:23

is there any way to get the raw characters to be printed ?

johanatan18:09:34

from what i've seen spec seem to report escape sequences for those

johanatan18:09:40

like \b, \f etc etc

johanatan18:09:21

ah, ok. thanks. any other characters like that i should know about ?

Alex Miller (Clojure team)18:09:36

well, that's one I've had this problem with. there are probably others

johanatan18:09:24

hehe 🙂 too bad https://clojuredocs.org/clojure.core/char-escape-string doesn't exist in cljs (although seems that wouldn't cover all of these anyway)

Alex Miller (Clojure team)18:09:28

you add a debug in your :fn function to print the count of the input strings or map char etc

Alex Miller (Clojure team)18:09:09

I'm just guessing here - this is a possible answer that matches what I see, but you should validate

johanatan18:09:17

yes of course

Alex Miller (Clojure team)18:09:15

these kinds of things happen with generative tests :)

johanatan18:09:26

unfortunately i think it might be something else:

johanatan18:09:30

comparing v: '1 1', and: '1 1', count v: 5, count joined: 5 false

johanatan18:09:35

ooh, there's two non-printable chars in there

johanatan18:09:44

and they're probably in opposing positions

johanatan18:09:36

found it. silly mistake.

johanatan18:09:53

i added a spurious reverse on the array of values i was comparing against

johanatan18:09:54

might be worth thinking about how to better report string values (adding perhaps unicode escapes for these as well as the platform default escapes)

johanatan19:09:07

thanks for your help!

johanatan19:09:24

fyi... i had used simple-type-equatable as my inner-type for a recursive map gen. if i had used instead simple-type-printable-equatable, this probably wouldn't have happened

johanatan19:09:40

this is the manual repl invocation of the function in question:

johanatan19:09:48

utils.utils=> (-merge-attribs '({:A/A ""} {:A/A ""}))
{:A/A ""}

johanatan19:09:56

the manual repl invocation is the "correct" one

johanatan19:09:39

(i have deleted the target/ directory and restarted the repl so it should not be a stale code issue)