Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Adding :with-repl option to start a clojure.main/repl in-between test execution #50

Merged
merged 4 commits into from
Feb 26, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changes

## NEXT

- Can now use the `:with-repl` flag to start a REPL for interacting with your project.

## 0.13.0

- Adds support for running tests once with the flag `:run-once`.
Expand Down Expand Up @@ -111,7 +115,7 @@ test namespace`.

- Nothing. This was an accidental release due to testing the release
script.

## 0.3.7

- Change success message to 'Passed all tests'
Expand Down
17 changes: 14 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ your `clojure.test` tests when a file in your project changes
- Supports `clojure.test`'s custom reports.
- Supports running your tests once! Useful for taking advantage of
custom test reporters or quiet output in CI systems.
- Has optional repl support for changing global state, such as timbre logging levels

[sample.project.clj](sample.project.clj) show optional configuration.
It and the rest of this readme should be used as documentation as to
Expand Down Expand Up @@ -62,10 +63,10 @@ output will look something like this.
*************** Running tests ***************

<standard clojure.test output>

Failed 1 of 215 assertions
Finished at 08:25:20.619 (run time: 9.691s)

Your terminal will just stay like that. Fairly often `lein-test-refresh`
polls the file system to see if anything has changed. When there is a
change your code is tested again.
Expand All @@ -92,7 +93,7 @@ For example, if you want to send OSX notifications using
you would add the following to your `project.clj` or `profiles.clj`

```clojure
:test-refresh {:notify-command ["terminal-notifier" "-title" "Tests" "-message"]}
:test-refresh {:notify-command ["terminal-notifier" "-title" "Tests" "-message"]}
```

`lein-test-refresh` also has built-in Growl support. To receive Growl
Expand Down Expand Up @@ -150,6 +151,16 @@ profiles.clj) or pass it as a command line option. Check out

Using it at the command line looks like `lein test-refresh :run-once`.

### Running with a REPL

`lein-test-refresh` can be run with `:with-repl` which will start up a repl
that you can interact with inbetween test runs. The main reason for this option
is that sometimes you want to affect global state in your application.
An example is when you see a test failure, you can call
`(taoensso.timbre/set-level! :debug)` and see more information.

See [this](https://github.com/jakemcc/lein-test-refresh/pull/50) pull request for details.

## Contributing

I encourage pull requests. If you're making a large change it is
Expand Down
2 changes: 1 addition & 1 deletion test-refresh/project.clj
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@
:username :gpg :password :gpg}]
["releases" {:url "https://clojars.org/repo"
:username :gpg :password :gpg}]]
:profiles {:dev {:dependencies [[org.clojure/clojure "1.6.0"]]}}
:profiles {:dev {:dependencies [[org.clojure/clojure "1.7.0"]]}}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I kept getting warnings about some of my plugins not running with 1.6.0.

:scm {:name "git"
:url "git@github.com:jakemcc/lein-test-refresh.git"})
52 changes: 40 additions & 12 deletions test-refresh/src/com/jakemccrary/test_refresh.clj
Original file line number Diff line number Diff line change
Expand Up @@ -163,13 +163,27 @@
(defn- something-changed? [x y]
(not= x y))

(defn- monitor-keystrokes [keystroke-pressed]
(def printing (atom false))

(defn- monitor-keystrokes [keystroke-pressed with-repl?]
(future
(loop [c (.read System/in)]
(if (= c -1)
(System/exit 0)
(do (reset! keystroke-pressed true)
(recur (.read System/in)))))))
(let [run-test-refresh! #(do (reset! keystroke-pressed true)
(reset! printing true))]
(if with-repl?
(clojure.main/repl
:prompt #(do (while @printing (Thread/sleep 100))
(clojure.main/repl-prompt))
:read (fn [request-prompt request-exit]
(if-let [line (read-line)]
(if-not (empty? (clojure.string/trim line))
(read-string line)
(do (run-test-refresh!) :run-tests))
(System/exit 0))))
(loop [c (.read System/in)]
(if (= c -1)
(System/exit 0)
(do (run-test-refresh!)
(recur (.read System/in)))))))))

(defn- create-user-notifier [notify-command]
(let [notify-command (if (string? notify-command)
Expand Down Expand Up @@ -198,20 +212,24 @@
keystroke-pressed (atom nil)
selectors (second (:nses-and-selectors options))
report (:report options)
run-once? (:run-once options)]
run-once? (:run-once options)
with-repl? (:with-repl options)
monitoring? (atom false)]

(when report
(println "Using reporter:" report))
(when (:quiet options)
(defmethod capture-report :begin-test-ns [m]))

(when-not run-once? (monitor-keystrokes keystroke-pressed))
(loop [tracker (make-change-tracker)]
(let [new-tracker (scan-for-changes tracker)]
(let [new-tracker (scan-for-changes tracker)
something-changed? (something-changed? new-tracker tracker)]
(try
(when (or @keystroke-pressed
(something-changed? new-tracker tracker))
(when (or @keystroke-pressed something-changed?)
(reset! keystroke-pressed nil)
(reset! printing true)

(when (and with-repl? @monitoring? something-changed?) (println))
(print-banner)

(let [was-failed (tracking-failed-tests?)
Expand All @@ -227,7 +245,17 @@
(when (should-notify? result)
(when should-growl
(growl (:status result) (:message result)))
(users-notifier (:message result)))))
(users-notifier (:message result))))
(reset! printing false)

(when (and with-repl? @monitoring? something-changed?)
(clojure.main/repl-prompt)
(flush))

(when (and (not run-once?)
(not @monitoring?))
(monitor-keystrokes keystroke-pressed with-repl?)
(reset! monitoring? true)))
(catch Exception ex (.printStackTrace ex)))
(Thread/sleep 200)
(if-not run-once?
Expand Down
10 changes: 6 additions & 4 deletions test-refresh/src/leiningen/test_refresh.clj
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,17 @@
(:test-paths project []))))

(defn parse-commandline [project args]
(let [{:keys [notify-command notify-on-success growl silence quiet report changes-only run-once]} (:test-refresh project)
(let [{:keys [notify-command notify-on-success growl silence quiet report changes-only run-once with-repl]} (:test-refresh project)
should-growl (or (some #{:growl ":growl" "growl"} args) growl)
changes-only (or (some #{:changes-only ":changes-only" "changes-only"} args) changes-only)
run-once? (or (some #{:run-once ":run-once" "run-once"} args) run-once)
with-repl? (or (some #{:with-repl ":with-repl" "with-repl"} args) with-repl)
args (remove #{:growl ":growl" "growl"
:changes-only ":changes-only" "changes-only"
:with-repl ":with-repl" "with-repl"
:run-once ":run-once" "run-once"} args)
notify-on-success (or (nil? notify-on-success) notify-on-success)
selectors (filter keyword? args)
]
selectors (filter keyword? args)]
{:growl should-growl
:changes-only changes-only
:notify-on-success notify-on-success
Expand All @@ -32,7 +33,8 @@
:test-paths (clojure-test-directories project)
:quiet quiet
:report report
:run-once run-once?}))
:run-once run-once?
:with-repl with-repl?}))

(defn test-refresh
"Autoruns clojure.test tests on source change or
Expand Down