Skip to content

Commit

Permalink
Merge pull request #1636 from clojure-emacs/tdd-mode
Browse files Browse the repository at this point in the history
Introduce cider-auto-test-mode
  • Loading branch information
bbatsov committed Mar 30, 2016
2 parents 1e7e289 + 6804a6a commit 1367053
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 10 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ an individual test using `C-c C-t t`.

### New Features

* [#1636](https://github.com/clojure-emacs/cider/pull/1636): New minor-mode `cider-auto-test-mode` for test-driven-development. When activated, tests are rerun after every load-file.
* Javadoc commands take into account the variable `clojure.java.javadoc/*remote-javadocs*`.
* Javadoc also works on classes of the AmazonAWS Java SDK.
* Apropos commands now accept lists of space-separated words as arguments, in addition to regular expressions (similar to Emacs's own apropos commands).
Expand Down
48 changes: 38 additions & 10 deletions cider-test.el
Original file line number Diff line number Diff line change
Expand Up @@ -533,21 +533,23 @@ This uses the Leiningen convention of appending '-test' to the namespace name."
(declare-function cider-emit-interactive-eval-output "cider-interaction")
(declare-function cider-emit-interactive-eval-err-output "cider-interaction")

(defun cider-test-execute (ns &optional tests)
(defun cider-test-execute (ns &optional tests silent)
"Run tests for NS, which may be a keyword, optionally specifying TESTS.
This tests a single NS, or multiple namespaces when using keywords `:project',
`:loaded' or `:non-passing'. Optional TESTS are only honored when a single
namespace is specified. Upon test completion, results are echoed and a test
report is optionally displayed. When test failures/errors occur, their sources
are highlighted."
are highlighted.
If SILENT is non-nil, suppress all messages other then test results."
(cider-test-clear-highlights)
(cider-map-connections
(lambda (conn)
(if (and tests (= (length tests) 1))
;; we generate a different message when running individual tests
(cider-test-echo-running ns (car tests))
(cider-test-echo-running ns))
(unless silent
(if (and tests (= (length tests) 1))
;; we generate a different message when running individual tests
(cider-test-echo-running ns (car tests))
(cider-test-echo-running ns)))
(cider-nrepl-send-request
(list "op" (cond ((stringp ns) "test")
((eq :project ns) "test-all")
Expand All @@ -562,7 +564,8 @@ are highlighted."
(lambda (response)
(nrepl-dbind-response response (summary results status out err)
(cond ((member "namespace-not-found" status)
(message "No test namespace: %s" (cider-propertize ns 'ns)))
(unless silent
(message "No test namespace: %s" (cider-propertize ns 'ns))))
(out (cider-emit-interactive-eval-output out))
(err (cider-emit-interactive-eval-err-output err))
(results
Expand Down Expand Up @@ -607,21 +610,23 @@ are highlighted."
(interactive)
(cider-test-execute :project))

(defun cider-test-run-ns-tests (suppress-inference)
(defun cider-test-run-ns-tests (suppress-inference &optional silent)
"Run all tests for the current Clojure namespace context.
If SILENT is non-nil, suppress all messages other then test results.
With a prefix arg SUPPRESS-INFERENCE it will try to run the tests in the
current ns."
(interactive "P")
(if-let ((ns (if suppress-inference
(cider-current-ns t)
(funcall cider-test-infer-test-ns (cider-current-ns t)))))
(cider-test-execute ns)
(cider-test-execute ns nil silent)
(if (eq major-mode 'cider-test-report-mode)
(when (y-or-n-p (concat "Test report does not define a namespace. "
"Rerun failed/erring tests?"))
(cider-test-rerun-tests))
(message "No namespace to test in current context"))))
(unless silent
(message "No namespace to test in current context")))))
(define-obsolete-function-alias 'cider-test-run-tests
'cider-test-run-ns-tests "0.11.0")

Expand All @@ -641,6 +646,29 @@ is searched."
(cider-test-execute ns (cdr def))
(message "No test at point"))))))

;;; Auto-test mode
(defun cider--test-silently ()
"Like `cider-test-run-tests', but with less feedback.
Only notify the user if there actually were any tests to run and only after
the results are received."
(when (cider-connected-p)
(let ((cider-auto-select-test-report-buffer nil)
(cider-test-show-report-on-success nil))
(cider-test-run-ns-tests nil 'soft))))

;;;###autoload
(define-minor-mode cider-auto-test-mode
"Toggle automatic testing of Clojure files.
When enabled this reruns tests every time a Clojure file is loaded.
Only runs tests corresponding to the loaded file's namespace and does
nothing if no tests are defined or if the file failed to load."
nil (cider-mode " Test") nil
:global t
(if cider-auto-test-mode
(add-hook 'cider-file-loaded-hook #'cider--test-silently)
(remove-hook 'cider-file-loaded-hook #'cider--test-silently)))

(provide 'cider-test)

;;; cider-test.el ends here
14 changes: 14 additions & 0 deletions doc/extended_workflow.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,20 @@ passed or failed:
(setq cider-test-show-report-on-success t)
```

#### Running tests automatically (test-driven development)

CIDER provides a minor-mode that automatically runs all tests for a namespace
whenever you load a file (with <kbd>C-c C-k</kbd>). You can toggle it
manually with <kbd>M-x</kbd> `cider-auto-test-mode`, or you can use:

```el
(cider-auto-test-mode 1)
```

This is completely equivalent to manually typing <kbd>C-c C-t C-n</kbd> every
time you load a Clojure buffer. Also, as described above before, CIDER is smart
enough to figure out the namespace containing the tests.

#### Using cider-test with alternative test libraries

The `clojure.test` machinery is designed to be pluggable. Any test library
Expand Down

0 comments on commit 1367053

Please sign in to comment.