Skip to content
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

When a test fails, there is a set of parens around the actual result #735

Closed
marcomorain opened this issue Dec 8, 2021 · 7 comments · Fixed by #739
Closed

When a test fails, there is a set of parens around the actual result #735

marcomorain opened this issue Dec 8, 2021 · 7 comments · Fixed by #739
Labels

Comments

@marcomorain
Copy link

Moved from nrepl/nrepl#260

Expected behaviour

When a test fails in directly in Clojure, I get the following output:

$ clj
Clojure 1.10.3
user=> (require '[clojure.test :refer :all])
nil
user=> (is (= "a" \a))

FAIL in () (NO_SOURCE_FILE:1)
expected: (= "a" \a)
  actual: (not (= "a" \a))
false

Actual behavior

When I run the same test through a Cider nREPL, I get the following output, (this is taken from a Calva REPL):

clj꞉sample-project.core-test꞉> (require '[clojure.test :refer :all])
nil
clj꞉sample-project.core-test꞉> (is (= "a" \a))

FAIL in () (form-init17836416246985520428.clj:8)
expected: "a"
  actual: (\a)
false

The key difference here is that Clojure shows that the expected result was \a, but nREPL says the actual result was (\a).

This is confusing. It makes it difficult to debug why a test has failed, because it appears like the actual result is a list of \a, (i.e. '(\a)), rather that \a. This also makes it very difficult to copy+paste results into tests expectations.

Steps to reproduce the problem

Evaluate the following two forms in a nREPL:

(require '[clojure.test :refer :all])
(is (= "a" \a))

I see the following in the Calva nREPL log:

<- received
{
  id: '80',
  out: 'expected: "a"\n',
  session: 'd3f9f96c-2c5a-4e89-806d-0b86f1ab9e6b'
}

<- received
{
  id: '80',
  out: '  actual: (\\a)\n',
  session: 'd3f9f96c-2c5a-4e89-806d-0b86f1ab9e6b'
}

Which shows that the string is being produced server-side, and is not being altered by Calva.

Environment & Version information

cider-nrepl version

cider-nrepl 0.27.3
nrepl 0.8.3

Java version

openjdk version "16.0.1" 2021-04-20
OpenJDK Runtime Environment AdoptOpenJDK-16.0.1+9 (build 16.0.1+9)
OpenJDK 64-Bit Server VM AdoptOpenJDK-16.0.1+9 (build 16.0.1+9, mixed mode, sharing)

Operating system

macOS 12.0.1 (21A559)

@vemv
Copy link
Member

vemv commented Dec 8, 2021

Rings a bell, we tried to improve this area recently (which probably didn't worsen anything, but might not have fixed all cases).

We'll take a look!

@marcomorain
Copy link
Author

marcomorain commented Dec 8, 2021

I've found the cause of the issue – cider.nrepl.middleware.test.extensions/=-body .

cider-nrepl adds a new handler for clojure.test/assert-expr to handle =. This handler is passed the arguments to =.

If you macroexpand (is (= 1 2)), more will be the list (2). If you expand (is (= 1 2 3 4)), more will be (2 3 4).

This results in this behaviour:

(deftest cider-nrepl-behaviour
  (testing "2-artity"
    (is (= 1 2)))
  (testing "arity-3"
    (is (= 1 2 3))))
; Running test: cider-nrepl-behaviour…
; FAIL in core/cider-nrepl-behaviour (core.clj:20):
; 2-artity
; expected:
1
; actual:
(2)
; FAIL in core/cider-nrepl-behaviour (core.clj:22):
; arity-3
; expected:
1
; actual:
(2 3)
; 2 tests finished, problems found. 😭 errors: 0, failures: 2, ns: 1, vars: 1

@vemv
Copy link
Member

vemv commented Dec 8, 2021

Thanks for that!

That might be only half of the story though. Note that that ns hasn't changed over 2 years.

What has changed recently is the way of printing test results.

Will take a look at both areas 👀

@bbatsov bbatsov added the bug label Dec 9, 2021
@vemv
Copy link
Member

vemv commented Dec 9, 2021

(For clarity, I'm talking about #713)

@vemv
Copy link
Member

vemv commented Dec 9, 2021

Ok, so

which means this bug has existed as-is for a couple years at least. (I verified so just now by reviewing https://github.com/clojure-emacs/cider-nrepl/commits/master/src/cider/nrepl/middleware/test/extensions.clj)

Probably it has been unnoticed because a cider-nrepl based connection willl typically run tests through cider, rather than by hitting clojure.test directly?

Anyway this is an unfortunate situation, mutating clojure.test globally seems pretty far from ideal.

Maybe we can refactor things to not touch clojure.test multimethods while preserving the desired behavior?

For example here we define our own multimethod:

(defmulti report
"Handle reporting for test events.
This takes a test event map as an argument and updates the `current-report`
atom to reflect test results and summary statistics."
:type)
(defmethod report :default [_m])

That model seems cleaner.

@vemv
Copy link
Member

vemv commented Dec 9, 2021

Maybe instead of making the extension not-global, we could just fix it to handle & correctly.

Hopefully getting its intended diffing behavior reasonably right won't be too much of a hassle.

vemv added a commit that referenced this issue Dec 10, 2021
* Unwrap lists for :actual for `=` arity 2
* Use traditional clojure.test notation for `=` ariry 3+

Fixes #735
vemv added a commit that referenced this issue Dec 10, 2021
* Unwrap lists for :actual for `=` arity 2
* Use traditional clojure.test notation for `=` ariry 3+

Fixes #735
vemv added a commit that referenced this issue Dec 10, 2021
* Unwrap lists for :actual for `=` arity 2
* Use traditional clojure.test notation for `=` ariry 3+

Fixes #735
vemv added a commit that referenced this issue Dec 10, 2021
* Unwrap lists for :actual for `=` arity 2
* Use traditional clojure.test notation for `=` arity 3+

Fixes #735
vemv added a commit that referenced this issue Dec 10, 2021
* Unwrap lists for :actual for `=` arity 2
* Use traditional clojure.test notation for `=` arity 3+

Fixes #735
@vemv vemv closed this as completed in #739 Dec 10, 2021
vemv added a commit that referenced this issue Dec 10, 2021
* Unwrap lists for :actual for `=` arity 2
* Use traditional clojure.test notation for `=` arity 3+

Fixes #735
@vemv
Copy link
Member

vemv commented Dec 22, 2021

Released in CIDER 1.2 / cider-nrepl 0.27.4.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants