-
Notifications
You must be signed in to change notification settings - Fork 177
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix a regression in test results formatting. #713
Fix a regression in test results formatting. #713
Conversation
@@ -152,7 +152,11 @@ | |||
(is (= "custom-output\n" | |||
(#'test/print-object (with-meta {:not :printed} {:type ::custom})))) | |||
(is (= "{:a :b, :c :d}\n" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a somewhat deceitful example, because a map of symbols printed by println
and pprint
looks identical:
user=> (println {:a :b :c :d})
{:a :b, :c :d}
nil
user=> (clojure.pprint/pprint {:a :b :c :d})
{:a :b, :c :d}
nil
the differences become apparent once you add strings, symbols, and other data:
user=> (println {:a "string" :c "42" :d 'symbol})
{:a string, :c 42, :d symbol}
nil
user=> (clojure.pprint/pprint {:a "string" :c "42" :d 'symbol})
{:a "string", :c "42", :d symbol}
nil
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice observation! These tests are good to keep, however please write them in the form (is (= ...) "pprint is chosen, as it can be seen in the quotation marks")
src/cider/nrepl/middleware/test.clj
Outdated
(get-method print-method :default)) | ||
pp/pprint | ||
println)] | ||
(let [custom-type (:type (meta object)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(:type (meta object))
is clearly nil
for any standard Clojure data type and (get-method print-method nil)
is never (get-method print-method :default)
(it is (get-method print-method nil)
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add a test that explicitly exercises this dispatch?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for this one! Looking good.
A few suggestions for shipping this one with full confidence.
src/cider/nrepl/middleware/test.clj
Outdated
(get-method print-method :default)) | ||
pp/pprint | ||
println)] | ||
(let [custom-type (:type (meta object)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add a test that explicitly exercises this dispatch?
src/cider/nrepl/middleware/test.clj
Outdated
pp/pprint | ||
println)] | ||
(let [custom-type (:type (meta object)) | ||
print-fn (if (and custom-type |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand much what's going on here.
- What's a
custom-type
?- i.e. worth adding a comment
- why can custom types result in a vanilla
println
?- I'm not sure of how 'customness' relates to the choice of
println
.
- I'm not sure of how 'customness' relates to the choice of
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@@ -152,7 +152,11 @@ | |||
(is (= "custom-output\n" | |||
(#'test/print-object (with-meta {:not :printed} {:type ::custom})))) | |||
(is (= "{:a :b, :c :d}\n" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice observation! These tests are good to keep, however please write them in the form (is (= ...) "pprint is chosen, as it can be seen in the quotation marks")
(#'test/print-object {:a :b :c :d}))) | ||
(is (= "{:a \"b\", :c \"d\"}\n" | ||
(#'test/print-object {:a "b" :c "d"}))) | ||
(is (= "\"string\"\n" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd add another case in which a \n
can be seen. That makes it more even more evident that pprint
is being used.
(is (= "{:a \"b\", :c \"d\"}\n" | ||
(#'test/print-object {:a "b" :c "d"}))) | ||
(is (= "\"string\"\n" | ||
(#'test/print-object "string"))))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As hinted in Can you add a test that explicitly exercises this dispatch?
I'd suggest that one also tests that one can get a vanilla print
ln by passing the right option.
IOW, I should see a test case for {:a string, :c 42, :d symbol}
and another for {:a "string", :c "42", :d symbol}
per https://github.com/clojure-emacs/cider-nrepl/pull/713/files#r710635100
a7de95c
to
a096e57
Compare
@vemv I made the changes that you requested, attempting to preserve the logic added in #683 unchanged while fixing the regression. That said, if you want my honest opinion: #683 should be completely reverted. I don’t understand that change, and I have a suspicion that it doesn’t work at all. That (= (get-method print-method "foo")
(get-method print-method :default))
; => true
(= (get-method print-method {})
(get-method print-method :default))
; => true maybe the below would work instead, but if it’s in fact broken, I’d rather revert than try to fix something that has been broken and nobody complained 🤷♂️ (defn- print-object
"Print `object` using pprint or a custom print-method, if available."
[object]
(let [print-fn (if (not= (get-method print-method object)
(get-method print-method :default))
println
pp/pprint)]
(with-out-str (print-fn object)))) |
Thanks for the iteration! Looking great. Taking a quick look at the #683 rationale, it seems a good idea to try exercising i.e. if we can ensure the matchers-combinators integration will keep working (or identify that it wasn't working properly), so much the bettter. We can always ping the author in question @FelipeCortez (done!) |
@vemv I spent a little more time looking into this and turned out I was wrong about this:
Example: (defmethod clojure.core/print-method ::custom [_ out]
(binding [*out* out]
(print "custom-output")))
(println (with-meta {:foo "bar"} {:type ::custom}))
; custom output
; nil Overall, I don’t feel like I have enough context (or proper motivation) to propose changes to existing matchers-combinators support. This PR fixes an issue affecting the majority of cider-nrepl users while satisfying the tests (and preserving the logic) provided for matchers-combinators support. To me, it sounds like a win-win. Can we merge it and track any potential matchers-combinators issues separately? |
Hi,
I don't think so, we can't be casually wrong about things and still go ahead with our original plans. A great PR will fix things for everyone. If you'd like to give the complete task a shot let us know! Cheers - V |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR is on the right track, following BetterThanTomorrow/calva#794 I can relate that issue to weird output formats I've seen in certain CIs when tests fail.
Suggesting a simple actionable thing for the test coverage, after that it would be probably ready.
Maybe we'd need an integration test that can't be fooled so easily, but that can be tackled separately.
(#'test/print-object (with-meta {:a "b" :c "42"} {:type {}}))) | ||
"pprint is chosen, because :type is printed via :default print-method") | ||
(is (= "{:a b, :c 42}\n" | ||
(#'test/print-object (with-meta {:a "b" :c "42"} {:type Number}))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A more realistic test setting would involve defining a print-method
for e.g. a defrecord TestRecord
and asserting that that print-method is invoked, instead of vanilla println
.
@vemv fair enough. I’m going on vacation until later next week so don‘t expect any updates in the meantime. I’ll be thinking about the following things (feedback welcome):
|
Cheers. I wonder if we could ask the matchers-combinators authors to use something ns-qualified in addition / instead of :type if that helps? |
ping :-) |
a096e57
to
4519f16
Compare
@vemv @bbatsov sorry for disappearing.
Right, this is where I arrived at as well and it’s already possible. I changed the PR to limit (ns calva-bug.core-test
(:require [clojure.test :refer [deftest is]]
[calva-bug.core :refer :all]
[matcher-combinators.test]
[matcher-combinators.matchers :as m]))
(deftest a-test
(is (= {:foo "bar"} {:foo "buz"})))
(deftest test-matching-with-explicit-matchers
(is (match? (m/equals 37) (+ 29 3)))
(is (match? (m/regex #"fox") "The quick brown fox jumps over the lazy dog")))
(deftest test-matching-scalars
;; most scalar values are interpreted as an `equals` matcher
(is (match? 37 (+ 29 8)))
(is (match? "this string" (str "this" " " "string")))
(is (match? :this/keyword (keyword "this" "keyword")))
;; regular expressions are handled specially
(is (match? #"fox" "The quick brown fox jumps over the lazy dog"))) Test output:
Looks like both clojure.test and matcher-combinators examples print the expected output. I should add that this is a potentially breaking change for other hypothetical test libs that rely on
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the update!
Looks like we can aim for this to be merged for the upcoming major release.
The changes introduced in clojure-emacs#683 resulted in test results always being printed via println instead of clojure.pprint/pprint. BetterThanTomorrow/calva#1280 describes the degraded user experience caused by this issue. This PR limits println usage to matchers-combinators results.
4519f16
to
01a7002
Compare
LGTM, it's fairly clear that this PR reverts kind of a dubious prior PR adding more coverage. Please add a changelog entry and we're good to go 🍻 |
🎉 |
Appreciated! A PR would be nice briefly summarizing the impact of the change for anyone that might have relied on the transient behavior we had (which seems unlikely) |
I added a basic changelog entry myself. I don't think there's any need to elaborate on this change further, given we considered it a bugfix. |
Released in |
The changes introduced in #683 resulted in test results always being
printed via
println
instead ofclojure.pprint/pprint
.BetterThanTomorrow/calva#1280 describes the degraded user experience
caused by this issue.