summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md6
-rw-r--r--project.clj2
-rw-r--r--src/ruuter/core.cljc14
-rw-r--r--test/ruuter/core_test.cljc63
4 files changed, 63 insertions, 22 deletions
diff --git a/README.md b/README.md
index edc0eff..dee0ba1 100644
--- a/README.md
+++ b/README.md
@@ -178,6 +178,12 @@ What the actual map can contain that you return depends again on the HTTP server
## Changelog
+### 1.3.4
+
+- Fixes an issue where if used with middlewares (like Ring), or really anything that passes a `:params` key from outside of Ruuter in the request, Ruuter overwrites the `:params` key with its own parametarization. It now does a deep merge instead, with the outside parameters having priority. This means that Ruuter parameters will remain unless overwritten, and should co-exist with outside parameters nicely. [Issue #6](https://github.com/askonomm/ruuter/issues/6).
+
+- Added and fixed some tests
+
### 1.3.3
- Removed ClojureScript from dependencies to make the bundle size smaller in case you want to use Ruuter with nbb.
diff --git a/project.clj b/project.clj
index 0a2881e..0764e17 100644
--- a/project.clj
+++ b/project.clj
@@ -1,4 +1,4 @@
-(defproject org.clojars.askonomm/ruuter "1.3.3"
+(defproject org.clojars.askonomm/ruuter "1.3.4"
:description "A tiny HTTP router"
:url "https://github.com/askonomm/ruuter"
:license {:name "MIT"
diff --git a/src/ruuter/core.cljc b/src/ruuter/core.cljc
index ec382ec..41201cc 100644
--- a/src/ruuter/core.cljc
+++ b/src/ruuter/core.cljc
@@ -3,6 +3,16 @@
[clojure.string :as string])
#?(:clj (:gen-class)))
+(defn deep-merge [& maps]
+ (letfn [(reconcile-keys [val-in-result val-in-latter]
+ (if (and (map? val-in-result)
+ (map? val-in-latter))
+ (merge-with reconcile-keys val-in-result val-in-latter)
+ val-in-latter))
+ (reconcile-maps [result latter]
+ (merge-with reconcile-keys result latter))]
+ (reduce reconcile-maps maps)))
+
(defn- path->regex-path
"Takes in a raw route `path` and turns it into a regex pattern to
match against the request URI."
@@ -105,8 +115,8 @@
; when using a function, you get the whole `req` and params
; with it as well.
(fn? response)
- (response (->> {:params (path+uri->path-params path uri)}
- (merge req)))
+ (response (-> {:params (path+uri->path-params path uri)}
+ (deep-merge req)))
; if by whatever reason we make it here it must mean the
; route is invalid, or doesn't exist, in which case we return
; an error message.
diff --git a/test/ruuter/core_test.cljc b/test/ruuter/core_test.cljc
index 1164124..7464fe0 100644
--- a/test/ruuter/core_test.cljc
+++ b/test/ruuter/core_test.cljc
@@ -49,22 +49,47 @@
(deftest route+req->response-test
(let [testfn #'ruuter/route+req->response]
- (testing "Returning a map when the response is a direct map"
- (= {:status 200
- :body "Hello."}
- (testfn {:path "/hello"
- :response {:status 200
- :body "Hello."}}
- {:uri "/hello"})))
- (testing "Returning a map via a fn when the response is a fn"
- (= {:status 200
- :body "Hello, world."}
- (testfn {:path "/hello/:who"
- :response (fn [req]
- {:status 200
- :body (str "Hello, " (:who (:params req)))})}
- {:uri "/hello/world"})))
- (testing "Returning an error map when route is invalid"
- (= {:status 404
- :body "Not found."}
- (testfn nil {:uri "/hello"})))))
+ (testing "Returns a map when the response is a direct map"
+ (is (= {:status 200
+ :body "Hello."}
+ (testfn {:path "/hello"
+ :response {:status 200
+ :body "Hello."}}
+ {:uri "/hello"}))))
+ (testing "Returns a map via a fn when the response is a fn"
+ (is (= {:status 200
+ :body "Hello, world."}
+ (testfn {:path "/hello/:who"
+ :response (fn [req]
+ {:status 200
+ :body (str "Hello, " (:who (:params req)) ".")})}
+ {:uri "/hello/world"}))))
+ (testing "Returns an error map when route is invalid"
+ (is (= {:status 404
+ :body "Not found."}
+ (testfn nil {:uri "/hello"}))))
+
+ (testing "Returns a combined :params map"
+ (let [params (atom nil)]
+ (testfn {:path "/hello/:who"
+ :response (fn [req]
+ (reset! params (:params req))
+ {:status 200
+ :body ""})}
+ {:uri "/hello/world"
+ :params {:some-params :from-elsewhere}})
+ (is (= {:who "world"
+ :some-params :from-elsewhere}
+ @params))))
+
+ (testing "Overwrites :params if needed"
+ (let [params (atom nil)]
+ (testfn {:path "/hello/:who"
+ :response (fn [req]
+ (reset! params (:params req))
+ {:status 200
+ :body ""})}
+ {:uri "/hello/world"
+ :params {:who "overwritten"}})
+ (is (= {:who "overwritten"}
+ @params))))))