From d724906cf6ed789e2dcead20967ac6371367357a Mon Sep 17 00:00:00 2001 From: Asko Nõmm Date: Thu, 27 Jul 2023 14:23:16 +0000 Subject: Release 1.3.4. --- README.md | 6 +++++ project.clj | 2 +- src/ruuter/core.cljc | 14 +++++++++-- test/ruuter/core_test.cljc | 63 ++++++++++++++++++++++++++++++++-------------- 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)))))) -- cgit v1.2.3