|
180 | 180 | "(ns clojure.test.mode |
181 | 181 | (:use [clojure.test :only [file-position *testing-vars* *test-out* |
182 | 182 | join-fixtures *report-counters* do-report |
183 | | - test-var *initial-report-counters*]])) |
| 183 | + test-var *initial-report-counters*]] |
| 184 | + [clojure.pprint :only [pprint]])) |
184 | 185 |
|
185 | 186 | (def #^{:dynamic true} *clojure-test-mode-out* nil) |
| 187 | + (def fail-events #{:fail :error}) |
186 | 188 | (defn report [event] |
187 | 189 | (if-let [current-test (last clojure.test/*testing-vars*)] |
188 | 190 | (alter-meta! current-test |
189 | 191 | assoc :status (conj (:status (meta current-test)) |
190 | | - [(:type event) (:message event) |
191 | | - (str (:expected event)) |
192 | | - (str (:actual event)) |
| 192 | + [(:type event) |
| 193 | + (:message event) |
| 194 | + (when (fail-events (:type event)) |
| 195 | + (str (:expected event))) |
| 196 | + (when (fail-events (:type event)) |
| 197 | + (str (:actual event))) |
| 198 | + (when (fail-events (:type event)) |
| 199 | + (with-out-str (pprint (:actual event)))) |
193 | 200 | (if (and (= (:major *clojure-version*) 1) |
194 | 201 | (< (:minor *clojure-version*) 2)) |
195 | 202 | ((file-position 2) 1) |
|
240 | 247 | (dolist (is-result (rest result)) |
241 | 248 | (unless (member (aref is-result 0) clojure-test-ignore-results) |
242 | 249 | (incf clojure-test-count) |
243 | | - (destructuring-bind (event msg expected actual line) (coerce is-result 'list) |
| 250 | + (destructuring-bind (event msg expected actual pp-actual line) |
| 251 | + (coerce is-result 'list) |
244 | 252 | (if (equal :fail event) |
245 | 253 | (progn (incf clojure-test-failure-count) |
246 | 254 | (clojure-test-highlight-problem |
247 | | - line event (format "Expected %s, got %s" expected actual))) |
| 255 | + line event (format "Expected %s, got %s" expected actual) |
| 256 | + pp-actual)) |
248 | 257 | (when (equal :error event) |
249 | 258 | (incf clojure-test-error-count) |
250 | | - (clojure-test-highlight-problem line event actual)))))) |
| 259 | + (clojure-test-highlight-problem |
| 260 | + line event actual pp-actual)))))) |
251 | 261 | (clojure-test-echo-results)) |
252 | 262 |
|
253 | 263 | (defun clojure-test-echo-results () |
|
261 | 271 | ((not (= clojure-test-failure-count 0)) 'clojure-test-failure-face) |
262 | 272 | (t 'clojure-test-success-face))))) |
263 | 273 |
|
264 | | -(defun clojure-test-highlight-problem (line event message) |
| 274 | +(defun clojure-test-highlight-problem (line event message pp-actual) |
265 | 275 | (save-excursion |
266 | 276 | (goto-char (point-min)) |
267 | 277 | (forward-line (1- line)) |
|
271 | 281 | (overlay-put overlay 'face (if (equal event :fail) |
272 | 282 | 'clojure-test-failure-face |
273 | 283 | 'clojure-test-error-face)) |
274 | | - (overlay-put overlay 'message message))))) |
| 284 | + (overlay-put overlay 'message message) |
| 285 | + (overlay-put overlay 'actual pp-actual))))) |
275 | 286 |
|
276 | 287 | ;; Problem navigation |
277 | 288 | (defun clojure-test-find-next-problem (here) |
@@ -359,6 +370,68 @@ Retuns the problem overlay if such a position is found, otherwise nil." |
359 | 370 | (message (replace-regexp-in-string "%" "%%" |
360 | 371 | (overlay-get overlay 'message)))))) |
361 | 372 |
|
| 373 | +(defun clojure-test-pprint-result () |
| 374 | + "Show the result of the test under point." |
| 375 | + (interactive) |
| 376 | + (let ((overlay (find-if (lambda (o) (overlay-get o 'message)) |
| 377 | + (overlays-at (point))))) |
| 378 | + (when overlay |
| 379 | + (with-current-buffer (generate-new-buffer " *test-output*") |
| 380 | + (buffer-disable-undo) |
| 381 | + (insert (overlay-get overlay 'actual)) |
| 382 | + (switch-to-buffer-other-window (current-buffer)))))) |
| 383 | + |
| 384 | +;;; ediff results |
| 385 | +(defvar clojure-test-ediff-buffers nil) |
| 386 | + |
| 387 | +(defun clojure-test-ediff-cleanup () |
| 388 | + "A function for ediff-cleanup-hook, to cleanup the temporary ediff buffers" |
| 389 | + (mapc (lambda (b) (when (get-buffer b) (kill-buffer b))) |
| 390 | + clojure-test-ediff-buffers)) |
| 391 | + |
| 392 | +(defun clojure-test-ediff-result () |
| 393 | + "Show the result of the test under point as an ediff" |
| 394 | + (interactive) |
| 395 | + (let ((overlay (find-if (lambda (o) (overlay-get o 'message)) |
| 396 | + (overlays-at (point))))) |
| 397 | + (if overlay |
| 398 | + (let* ((m (overlay-get overlay 'actual))) |
| 399 | + (let ((tmp-buffer (generate-new-buffer " *clojure-test-mode-tmp*")) |
| 400 | + (exp-buffer (generate-new-buffer " *expected*")) |
| 401 | + (act-buffer (generate-new-buffer " *actual*"))) |
| 402 | + (with-current-buffer tmp-buffer |
| 403 | + (insert m) |
| 404 | + (clojure-mode) |
| 405 | + (goto-char (point-min)) |
| 406 | + (forward-char) ; skip a paren |
| 407 | + (paredit-splice-sexp) ; splice |
| 408 | + (lexical-let ((p (point))) ; delete "not" |
| 409 | + (forward-sexp) |
| 410 | + (delete-region p (point))) |
| 411 | + (lexical-let ((p (point))) ; splice next sexp |
| 412 | + (forward-sexp) |
| 413 | + (backward-sexp) |
| 414 | + (forward-char) |
| 415 | + (paredit-splice-sexp)) |
| 416 | + (lexical-let ((p (point))) ; delete operator |
| 417 | + (forward-sexp) |
| 418 | + (delete-region p (point))) |
| 419 | + (lexical-let ((p (point))) ; copy first expr |
| 420 | + (forward-sexp) |
| 421 | + (lexical-let ((p2 (point))) |
| 422 | + (with-current-buffer exp-buffer |
| 423 | + (insert-buffer-substring-as-yank tmp-buffer (+ 1 p) p2)))) |
| 424 | + (lexical-let ((p (point))) ; copy next expr |
| 425 | + (forward-sexp) |
| 426 | + (lexical-let ((p2 (point))) |
| 427 | + (with-current-buffer act-buffer |
| 428 | + (insert-buffer-substring-as-yank tmp-buffer (+ 1 p) p2))))) |
| 429 | + (kill-buffer tmp-buffer) |
| 430 | + (setq clojure-test-ediff-buffers |
| 431 | + (list (buffer-name exp-buffer) (buffer-name act-buffer))) |
| 432 | + (ediff-buffers |
| 433 | + (buffer-name exp-buffer) (buffer-name act-buffer))))))) |
| 434 | + |
362 | 435 | (defun clojure-test-load-current-buffer () |
363 | 436 | (let ((command (format "(clojure.core/load-file \"%s\")\n(in-ns '%s)" |
364 | 437 | (buffer-file-name) |
@@ -406,7 +479,8 @@ Retuns the problem overlay if such a position is found, otherwise nil." |
406 | 479 | (define-key map (kbd "C-c C-,") 'clojure-test-run-tests) |
407 | 480 | (define-key map (kbd "C-c ,") 'clojure-test-run-tests) |
408 | 481 | (define-key map (kbd "C-c M-,") 'clojure-test-run-test) |
409 | | - (define-key map (kbd "C-c C-'") 'clojure-test-show-result) |
| 482 | + (define-key map (kbd "C-c C-'") 'clojure-test-ediff-result) |
| 483 | + (define-key map (kbd "C-c M-'") 'clojure-test-pprint-result) |
410 | 484 | (define-key map (kbd "C-c '") 'clojure-test-show-result) |
411 | 485 | (define-key map (kbd "C-c k") 'clojure-test-clear) |
412 | 486 | (define-key map (kbd "C-c C-t") 'clojure-jump-between-tests-and-code) |
|
0 commit comments