nubank / matcher-combinators

Library for creating matcher combinator to compare nested data structures
Other
468 stars 23 forks source link

Allow using `(matchers/pred ...)` with a more descriptive error #145

Closed andrey-sanchez closed 1 year ago

andrey-sanchez commented 4 years ago

Currently, when a (matchers/pred fn) fails for a test the displayed error is the fn's string representation. My suggestion is to set (matchers/pred ...) as a multi-arity function and allow passing a descriptive message as parameter, something like this:

(defn pred
  "Matcher that will match when `pred` of the actual value returns true."
  ([pred] (core/->PredMatcher pred (str "predicate: " pred)))
  ([pred desc] (core/->PredMatcher pred desc)))
fernando-nubank commented 4 years ago

Another idea would be making pred a macro and just str the predicate symbol :thinking:

philomates commented 4 years ago

A while ago I tried to come up with something prettier than the str interpretation of the function but didn't get very far. I remember considering making pred a macro but I either couldn't get it to work well with the rest of the system or ran into the issue where once you add one macro you have to keep pilling more macros on in order to work further with it.

I definitely think this is something worth trying to improve but it would be cool to see if someone else could tackle it given that I ran into walls when I tried.

The idea of making pred multi-arity sounds pretty good. I do wonder if people will take the time to do so in their tests. I wonder this because to me adding additional info to tests that only shows when the test fails but otherwise doesn't provide context feels like something that generally won't be used. That said, perhaps this can be useful for identifying the exact predicate that was violated once you already have a failing test?

fernando-nubank commented 4 years ago

I changed pred to

(defmacro pred
  "Matcher that will match when `pred` of the actual value returns true."
  [pred-1]
  `(core/->PredMatcher ~pred-1 (str "predicate: " (quote ~pred-1))))

and it passes all tests. The result is

;; using (pred map?)
"predicate: map?"

;; using (pred #(= % 1))
"predicate: (fn* [p1__13597#] (= p1__13597# 1)) ; #() is a reader macro
fernando-nubank commented 4 years ago

That said, perhaps this can be useful for identifying the exact predicate that was violated once you already have a failing test?

I also don't see people using this description, but I believe that this is indeed very useful to debug a failing test.

The macro approach doesn't appeal to me anymore because the descriptions of anonymous functions are really ugly

philomates commented 1 year ago

I also don't see people using this description, but I believe that this is indeed very useful to debug a failing test.

one example of where it is kind of nice to see the description text:

https://github.com/nubank/matcher-combinators/issues/112#issuecomment-1350902734

anyways, https://github.com/nubank/matcher-combinators/pull/190 makes the original arity change suggestion