Skip to content

Commit 270400f

Browse files
hagmonkbbatsov
authored andcommitted
[#537] A second stab at fixing the main/init problem (#539)
My fix yesterday was not properly tested - I started nREPL from the command line, but I didn't attempt to exercise it with messages. As a result, I missed the fact I was setting passing the middleware as the handler, which kept things just as broken. This PR contains a fix for that problem, plus a new test ns cider.nrepl.main-test that exercises the start-nrepl function by passing it a variety of valid and invalid option maps. The tests go as far as checking that two :op "clone" messages can be exchanged before declaring success.
1 parent c9ca4cb commit 270400f

File tree

2 files changed

+70
-9
lines changed

2 files changed

+70
-9
lines changed

src/cider_nrepl/main.clj

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,17 +28,35 @@
2828
[middleware-var-strs]
2929
(into [] mw-xf middleware-var-strs))
3030

31+
(defn- build-handler
32+
[middleware]
33+
(apply nrepl.server/default-handler (->mw-list middleware)))
34+
3135
(defn start-nrepl
32-
[opts]
33-
(let [{:keys [handler middleware bind port] :or {port 0 bind "::"}} opts
36+
"Starts a socket-based nREPL server. Accepts a map with the following keys:
37+
38+
* :port — defaults to 0, which autoselects an open port
39+
40+
* :bind — bind address, by default \"::\" (falling back to \"localhost\" if
41+
\"::\" isn't resolved by the underlying network stack)
42+
43+
* :handler — the nREPL message handler to use for each incoming connection;
44+
defaults to the result of `(nrepl.server/default-handler)`
3445
35-
handler (cond-> (or handler nrepl.server/default-handler)
36-
middleware (apply (->mw-list middleware)))
46+
* :middleware - a sequence of vars or string which can be resolved to vars,
47+
representing middleware you wish to mix in to the nREPL handler. Vars can
48+
resolve to a sequence of vars, in which case they'll be flattened into the
49+
list of middleware."
50+
[{:keys [handler middleware bind port] :as opts}]
51+
(let [handler
52+
(if handler
53+
(handler)
54+
(build-handler middleware))
3755

3856
{:keys [server-socket port] :as server}
3957
(nrepl.server/start-server :handler handler
40-
:bind bind
41-
:port port)
58+
:bind (or bind "localhost")
59+
:port (or port 0))
4260

4361
bind
4462
(-> server-socket (.getInetAddress) (.getHostName))]
@@ -50,8 +68,8 @@
5068

5169
(defn init
5270
([]
53-
(init nil))
54-
([handlers]
55-
(start-nrepl {:handler handlers})
71+
(start-nrepl {}))
72+
([middleware]
73+
(start-nrepl {:middleware middleware})
5674
;; Return nil so the value doesn't print
5775
nil))

test/clj/cider/nrepl/main_test.clj

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
(ns cider.nrepl.main-test
2+
(:require [cider.nrepl :refer [wrap-debug cider-middleware]]
3+
[cider-nrepl.main :as m]
4+
[clojure.test :refer :all]
5+
[clojure.tools.nrepl :as nrepl]
6+
[clojure.tools.nrepl.server :as nrepl.server]
7+
[clojure.tools.nrepl.transport :as transport]))
8+
9+
(defn start-stop-nrepl-session [opts]
10+
(with-open [server (#'m/start-nrepl opts)
11+
transport (nrepl/connect :port (:port server))]
12+
(transport/send transport {:op "clone" :id 1})
13+
(let [session-id (:new-session (transport/recv transport 1000))]
14+
(assert session-id)
15+
(transport/send transport {:session session-id
16+
:id 2
17+
:op "clone"})
18+
(is (= (:status (transport/recv transport 1000)) ["done"])))))
19+
20+
(deftest start-nrepl-test
21+
(testing "passing a specific handler should work"
22+
(let [opts {:handler nrepl.server/default-handler}]
23+
(start-stop-nrepl-session opts)))
24+
25+
(testing "passing a sequence instead of a map shouldn't crash"
26+
(let [opts ["cider.nrepl/cider-middleware"]]
27+
(start-stop-nrepl-session opts)))
28+
29+
(testing "passing nil shouldn't crash"
30+
(let [opts nil]
31+
(start-stop-nrepl-session opts)))
32+
33+
(testing "passing valid middleware should work"
34+
(let [opts {:middleware ["cider.nrepl/cider-middleware"]}]
35+
(start-stop-nrepl-session opts)))
36+
37+
(testing "passing options as given by boot task middleware should work"
38+
(let [opts {:middleware '(cider.nrepl.middleware.version/wrap-version
39+
cider.nrepl.middleware.apropos/wrap-apropos)
40+
:port nil
41+
:bind nil}]
42+
(start-stop-nrepl-session opts))))
43+

0 commit comments

Comments
 (0)