mirror of
https://github.com/metosin/reitit.git
synced 2025-12-17 16:31:11 +00:00
Initial sketch for a ring-router
This commit is contained in:
parent
a208f7df6c
commit
fa37e3e198
3 changed files with 111 additions and 2 deletions
43
src/reitit/ring.cljc
Normal file
43
src/reitit/ring.cljc
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
(ns reitit.ring
|
||||||
|
(:require [reitit.core :as reitit]))
|
||||||
|
|
||||||
|
(defprotocol ExpandMiddleware
|
||||||
|
(expand-middleware [this]))
|
||||||
|
|
||||||
|
(extend-protocol ExpandMiddleware
|
||||||
|
|
||||||
|
#?(:clj clojure.lang.APersistentVector
|
||||||
|
:cljs cljs.core.PersistentVector)
|
||||||
|
(expand-middleware [[f & args]]
|
||||||
|
(fn [handler]
|
||||||
|
(apply f handler args)))
|
||||||
|
|
||||||
|
#?(:clj clojure.lang.Fn
|
||||||
|
:cljs function)
|
||||||
|
(expand-middleware [this] this)
|
||||||
|
|
||||||
|
nil
|
||||||
|
(expand-middleware [_]))
|
||||||
|
|
||||||
|
(defn compile-handler [[path {:keys [middleware handler] :as meta}]]
|
||||||
|
(when-not handler
|
||||||
|
(throw (ex-info
|
||||||
|
(str "path '" path "' doesn't have a :handler defined")
|
||||||
|
{:path path, :meta meta})))
|
||||||
|
(let [wrap (->> middleware
|
||||||
|
(keep identity)
|
||||||
|
(map expand-middleware)
|
||||||
|
(apply comp identity))]
|
||||||
|
(wrap handler)))
|
||||||
|
|
||||||
|
(defn router [data]
|
||||||
|
(reitit/router data {:compile compile-handler}))
|
||||||
|
|
||||||
|
(defn ring-handler [router]
|
||||||
|
(fn
|
||||||
|
([request]
|
||||||
|
(if-let [match (reitit/match-by-path router (:uri request))]
|
||||||
|
((:handler match) request)))
|
||||||
|
([request respond raise]
|
||||||
|
(if-let [match (reitit/match-by-path router (:uri request))]
|
||||||
|
((:handler match) request respond raise)))))
|
||||||
64
test/cljc/reitit/ring_test.cljc
Normal file
64
test/cljc/reitit/ring_test.cljc
Normal file
|
|
@ -0,0 +1,64 @@
|
||||||
|
(ns reitit.ring-test
|
||||||
|
(:require [clojure.test :refer [deftest testing is are]]
|
||||||
|
[reitit.core :as reitit]
|
||||||
|
[reitit.ring :as ring])
|
||||||
|
#?(:clj
|
||||||
|
(:import (clojure.lang ExceptionInfo))))
|
||||||
|
|
||||||
|
(defn mw [handler name]
|
||||||
|
(fn
|
||||||
|
([request]
|
||||||
|
(-> request
|
||||||
|
(update ::mw (fnil conj []) name)
|
||||||
|
(handler)
|
||||||
|
(update :body (fnil conj []) name)))
|
||||||
|
([request respond raise]
|
||||||
|
(handler
|
||||||
|
(update request ::mw (fnil conj []) name)
|
||||||
|
#(respond (update % :body (fnil conj []) name))
|
||||||
|
raise))))
|
||||||
|
|
||||||
|
(deftest ring-test
|
||||||
|
|
||||||
|
(testing "all paths should have a handler"
|
||||||
|
(is (thrown-with-msg?
|
||||||
|
ExceptionInfo
|
||||||
|
#"^path '/ping' doesn't have a :handler defined$"
|
||||||
|
(ring/router ["/ping"]))))
|
||||||
|
|
||||||
|
(testing "ring-handler"
|
||||||
|
(let [api-mw #(mw % :api)
|
||||||
|
handler (fn handle
|
||||||
|
([{:keys [::mw]}]
|
||||||
|
{:status 200 :body (conj mw :ok)})
|
||||||
|
([request respond raise]
|
||||||
|
(respond (handle request))))
|
||||||
|
app (ring/ring-handler
|
||||||
|
(ring/router
|
||||||
|
[["/ping" handler]
|
||||||
|
["/api" {:middleware [api-mw]}
|
||||||
|
["/ping" handler]
|
||||||
|
["/admin" {:middleware [[mw :admin]]}
|
||||||
|
["/ping" handler]]]]))]
|
||||||
|
|
||||||
|
(testing "normal handler"
|
||||||
|
(is (= {:status 200, :body [:ok]}
|
||||||
|
(app {:uri "/ping"}))))
|
||||||
|
|
||||||
|
(testing "with middleware"
|
||||||
|
(is (= {:status 200, :body [:api :ok :api]}
|
||||||
|
(app {:uri "/api/ping"}))))
|
||||||
|
|
||||||
|
(testing "with nested middleware"
|
||||||
|
(is (= {:status 200, :body [:api :admin :ok :admin :api]}
|
||||||
|
(app {:uri "/api/admin/ping"}))))
|
||||||
|
|
||||||
|
(testing "not found"
|
||||||
|
(is (= nil (app {:uri "/favicon.ico"}))))
|
||||||
|
|
||||||
|
(testing "3-arity"
|
||||||
|
(let [result (atom nil)
|
||||||
|
respond (partial reset! result), raise ::not-called]
|
||||||
|
(app {:uri "/api/admin/ping"} respond raise)
|
||||||
|
(is (= {:status 200, :body [:api :admin :ok :admin :api]}
|
||||||
|
@result)))))))
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
(ns reitit.doo-runner
|
(ns reitit.doo-runner
|
||||||
(:require [doo.runner :refer-macros [doo-tests]]
|
(:require [doo.runner :refer-macros [doo-tests]]
|
||||||
reitit.core-test))
|
reitit.core-test
|
||||||
|
reitit.ring-test))
|
||||||
|
|
||||||
(enable-console-print!)
|
(enable-console-print!)
|
||||||
|
|
||||||
(doo-tests 'reitit.core-test)
|
(doo-tests 'reitit.core-test
|
||||||
|
'reitit.ring-test)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue