mirror of
https://github.com/metosin/reitit.git
synced 2025-12-18 08:51:12 +00:00
parent
18f8bdfbec
commit
4e22fd2f53
8 changed files with 197 additions and 88 deletions
16
README.md
16
README.md
|
|
@ -114,7 +114,7 @@ Route names:
|
||||||
; #Match{:template "/api/user/:id"
|
; #Match{:template "/api/user/:id"
|
||||||
; :meta {:name :user/user}
|
; :meta {:name :user/user}
|
||||||
; :path "/api/user/1"
|
; :path "/api/user/1"
|
||||||
; :handler nil
|
; :result nil
|
||||||
; :params {:id "1"}}
|
; :params {:id "1"}}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -124,7 +124,7 @@ Route names:
|
||||||
(reitit/match-by-name router ::user)
|
(reitit/match-by-name router ::user)
|
||||||
; #PartialMatch{:template "/api/user/:id",
|
; #PartialMatch{:template "/api/user/:id",
|
||||||
; :meta {:name :user/user},
|
; :meta {:name :user/user},
|
||||||
; :handler nil,
|
; :result nil,
|
||||||
; :params nil,
|
; :params nil,
|
||||||
; :required #{:id}}
|
; :required #{:id}}
|
||||||
|
|
||||||
|
|
@ -139,7 +139,7 @@ Only a partial match. Let's provide the path-parameters:
|
||||||
; #Match{:template "/api/user/:id"
|
; #Match{:template "/api/user/:id"
|
||||||
; :meta {:name :user/user}
|
; :meta {:name :user/user}
|
||||||
; :path "/api/user/1"
|
; :path "/api/user/1"
|
||||||
; :handler nil
|
; :result nil
|
||||||
; :params {:id "1"}}
|
; :params {:id "1"}}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -201,13 +201,13 @@ Path-based routing:
|
||||||
; :interceptors [::api ::admin]
|
; :interceptors [::api ::admin]
|
||||||
; :roles #{:root}}
|
; :roles #{:root}}
|
||||||
; :path "/api/admin/root"
|
; :path "/api/admin/root"
|
||||||
; :handler nil
|
; :result nil
|
||||||
; :params {}}
|
; :params {}}
|
||||||
```
|
```
|
||||||
|
|
||||||
On match, route meta-data is returned and can interpreted by the application.
|
On match, route meta-data is returned and can interpreted by the application.
|
||||||
|
|
||||||
Routers also support meta-data compilation enabling things like fast [Ring](https://github.com/ring-clojure/ring) or [Pedestal](http://pedestal.io/) -style handlers. Compilation results are found under `:handler` in the match. See [configuring routers](#configuring-routers) for details.
|
Routers also support meta-data compilation enabling things like fast [Ring](https://github.com/ring-clojure/ring) or [Pedestal](http://pedestal.io/) -style handlers. Compilation results are found under `:result` in the match. See [configuring routers](#configuring-routers) for details.
|
||||||
|
|
||||||
## Route conflicts
|
## Route conflicts
|
||||||
|
|
||||||
|
|
@ -225,10 +225,10 @@ Route trees should not have multiple routes that match to a single (request) pat
|
||||||
; /:user-id/orders
|
; /:user-id/orders
|
||||||
; -> /public/*path
|
; -> /public/*path
|
||||||
; -> /bulk/:bulk-id
|
; -> /bulk/:bulk-id
|
||||||
;
|
;
|
||||||
; /bulk/:bulk-id
|
; /bulk/:bulk-id
|
||||||
; -> /:version/status
|
; -> /:version/status
|
||||||
;
|
;
|
||||||
; /public/*path
|
; /public/*path
|
||||||
; -> /:version/status
|
; -> /:version/status
|
||||||
;
|
;
|
||||||
|
|
@ -424,7 +424,7 @@ Routers can be configured via options. Options allow things like [`clojure.spec`
|
||||||
| `:meta` | Initial expanded route-meta vector (default `[]`)
|
| `:meta` | Initial expanded route-meta vector (default `[]`)
|
||||||
| `:expand` | Function of `arg opts => meta` to expand route arg to route meta-data (default `reitit.core/expand`)
|
| `:expand` | Function of `arg opts => meta` to expand route arg to route meta-data (default `reitit.core/expand`)
|
||||||
| `:coerce` | Function of `route opts => route` to coerce resolved route, can throw or return `nil`
|
| `:coerce` | Function of `route opts => route` to coerce resolved route, can throw or return `nil`
|
||||||
| `:compile` | Function of `route opts => handler` to compile a route handler
|
| `:compile` | Function of `route opts => result` to compile a route handler
|
||||||
| `:conflicts` | Function of `{route #{route}} => side-effect` to handle conflicting routes (default `reitit.core/throw-on-conflicts!`)
|
| `:conflicts` | Function of `{route #{route}} => side-effect` to handle conflicting routes (default `reitit.core/throw-on-conflicts!`)
|
||||||
| `:router` | Function of `routes opts => router` to override the actual router implementation
|
| `:router` | Function of `routes opts => router` to override the actual router implementation
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@
|
||||||
(if (seq childs)
|
(if (seq childs)
|
||||||
(walk-many (str pacc path) macc childs)
|
(walk-many (str pacc path) macc childs)
|
||||||
[[(str pacc path) macc]]))))]
|
[[(str pacc path) macc]]))))]
|
||||||
(walk-one path meta data)))
|
(walk-one path (mapv identity meta) data)))
|
||||||
|
|
||||||
(defn map-meta [f routes]
|
(defn map-meta [f routes]
|
||||||
(mapv #(update % 1 f) routes))
|
(mapv #(update % 1 f) routes))
|
||||||
|
|
@ -100,8 +100,8 @@
|
||||||
(match-by-path [this path])
|
(match-by-path [this path])
|
||||||
(match-by-name [this name] [this name params]))
|
(match-by-name [this name] [this name params]))
|
||||||
|
|
||||||
(defrecord Match [template meta handler params path])
|
(defrecord Match [template meta result params path])
|
||||||
(defrecord PartialMatch [template meta handler params required])
|
(defrecord PartialMatch [template meta result params required])
|
||||||
|
|
||||||
(defn partial-match? [x]
|
(defn partial-match? [x]
|
||||||
(instance? PartialMatch x))
|
(instance? PartialMatch x))
|
||||||
|
|
@ -132,11 +132,11 @@
|
||||||
(let [compiled (map #(compile-route % opts) routes)
|
(let [compiled (map #(compile-route % opts) routes)
|
||||||
names (find-names routes opts)
|
names (find-names routes opts)
|
||||||
[data lookup] (reduce
|
[data lookup] (reduce
|
||||||
(fn [[data lookup] [p {:keys [name] :as meta} handler]]
|
(fn [[data lookup] [p {:keys [name] :as meta} result]]
|
||||||
(let [{:keys [params] :as route} (impl/create [p meta handler])
|
(let [{:keys [params] :as route} (impl/create [p meta result])
|
||||||
f #(if-let [path (impl/path-for route %)]
|
f #(if-let [path (impl/path-for route %)]
|
||||||
(->Match p meta handler % path)
|
(->Match p meta result % path)
|
||||||
(->PartialMatch p meta handler % params))]
|
(->PartialMatch p meta result % params))]
|
||||||
[(conj data route)
|
[(conj data route)
|
||||||
(if name (assoc lookup name f) lookup)]))
|
(if name (assoc lookup name f) lookup)]))
|
||||||
[[] {}] compiled)
|
[[] {}] compiled)
|
||||||
|
|
@ -155,7 +155,7 @@
|
||||||
(reduce
|
(reduce
|
||||||
(fn [acc ^Route route]
|
(fn [acc ^Route route]
|
||||||
(if-let [params ((:matcher route) path)]
|
(if-let [params ((:matcher route) path)]
|
||||||
(reduced (->Match (:path route) (:meta route) (:handler route) params path))))
|
(reduced (->Match (:path route) (:meta route) (:result route) params path))))
|
||||||
nil data))
|
nil data))
|
||||||
(match-by-name [_ name]
|
(match-by-name [_ name]
|
||||||
(if-let [match (impl/fast-get lookup name)]
|
(if-let [match (impl/fast-get lookup name)]
|
||||||
|
|
@ -179,10 +179,10 @@
|
||||||
(let [compiled (map #(compile-route % opts) routes)
|
(let [compiled (map #(compile-route % opts) routes)
|
||||||
names (find-names routes opts)
|
names (find-names routes opts)
|
||||||
[data lookup] (reduce
|
[data lookup] (reduce
|
||||||
(fn [[data lookup] [p {:keys [name] :as meta} handler]]
|
(fn [[data lookup] [p {:keys [name] :as meta} result]]
|
||||||
[(assoc data p (->Match p meta handler {} p))
|
[(assoc data p (->Match p meta result {} p))
|
||||||
(if name
|
(if name
|
||||||
(assoc lookup name #(->Match p meta handler % p))
|
(assoc lookup name #(->Match p meta result % p))
|
||||||
lookup)]) [{} {}] compiled)
|
lookup)]) [{} {}] compiled)
|
||||||
data (impl/fast-map data)
|
data (impl/fast-map data)
|
||||||
lookup (impl/fast-map lookup)]
|
lookup (impl/fast-map lookup)]
|
||||||
|
|
@ -244,10 +244,10 @@
|
||||||
| -------------|-------------|
|
| -------------|-------------|
|
||||||
| `:path` | Base-path for routes (default `\"\"`)
|
| `:path` | Base-path for routes (default `\"\"`)
|
||||||
| `:routes` | Initial resolved routes (default `[]`)
|
| `:routes` | Initial resolved routes (default `[]`)
|
||||||
| `:meta` | Initial expanded route-meta vector (default `[]`)
|
| `:meta` | Initial route meta (default `{}`)
|
||||||
| `:expand` | Function of `arg opts => meta` to expand route arg to route meta-data (default `reitit.core/expand`)
|
| `:expand` | Function of `arg opts => meta` to expand route arg to route meta-data (default `reitit.core/expand`)
|
||||||
| `:coerce` | Function of `route opts => route` to coerce resolved route, can throw or return `nil`
|
| `:coerce` | Function of `route opts => route` to coerce resolved route, can throw or return `nil`
|
||||||
| `:compile` | Function of `route opts => handler` to compile a route handler
|
| `:compile` | Function of `route opts => result` to compile a route handler
|
||||||
| `:conflicts` | Function of `{route #{route}} => side-effect` to handle conflicting routes (default `reitit.core/throw-on-conflicts!`)
|
| `:conflicts` | Function of `{route #{route}} => side-effect` to handle conflicting routes (default `reitit.core/throw-on-conflicts!`)
|
||||||
| `:router` | Function of `routes opts => router` to override the actual router implementation"
|
| `:router` | Function of `routes opts => router` to override the actual router implementation"
|
||||||
([data]
|
([data]
|
||||||
|
|
|
||||||
|
|
@ -101,15 +101,15 @@
|
||||||
;; Routing (c) Metosin
|
;; Routing (c) Metosin
|
||||||
;;
|
;;
|
||||||
|
|
||||||
(defrecord Route [path matcher parts params meta handler])
|
(defrecord Route [path matcher parts params meta result])
|
||||||
|
|
||||||
(defn create [[path meta handler]]
|
(defn create [[path meta result]]
|
||||||
(if (contains-wilds? path)
|
(if (contains-wilds? path)
|
||||||
(as-> (parse-path path) $
|
(as-> (parse-path path) $
|
||||||
(assoc $ :path-re (path-regex $))
|
(assoc $ :path-re (path-regex $))
|
||||||
(merge $ {:path path
|
(merge $ {:path path
|
||||||
:matcher (path-matcher $)
|
:matcher (path-matcher $)
|
||||||
:handler handler
|
:result result
|
||||||
:meta meta})
|
:meta meta})
|
||||||
(dissoc $ :path-re :path-constraints)
|
(dissoc $ :path-re :path-constraints)
|
||||||
(update $ :path-params set)
|
(update $ :path-params set)
|
||||||
|
|
@ -119,7 +119,7 @@
|
||||||
(map->Route {:path path
|
(map->Route {:path path
|
||||||
:meta meta
|
:meta meta
|
||||||
:matcher #(if (= path %) {})
|
:matcher #(if (= path %) {})
|
||||||
:handler handler})))
|
:result result})))
|
||||||
|
|
||||||
(defn segments [path]
|
(defn segments [path]
|
||||||
(let [ss (-> (str/split path #"/") rest vec)]
|
(let [ss (-> (str/split path #"/") rest vec)]
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,45 @@
|
||||||
(ns reitit.middleware
|
(ns reitit.middleware
|
||||||
(:require [meta-merge.core :refer [meta-merge]]
|
(:require [meta-merge.core :refer [meta-merge]]
|
||||||
[reitit.core :as reitit]))
|
[reitit.core :as reitit])
|
||||||
|
#?(:clj
|
||||||
|
(:import (clojure.lang IFn AFn))))
|
||||||
|
|
||||||
(defprotocol ExpandMiddleware
|
(defprotocol ExpandMiddleware
|
||||||
(expand-middleware [this opts]))
|
(expand-middleware [this meta opts]))
|
||||||
|
|
||||||
|
(defrecord MiddlewareGenerator [f args]
|
||||||
|
IFn
|
||||||
|
(invoke [_]
|
||||||
|
(f nil nil))
|
||||||
|
(invoke [_ meta]
|
||||||
|
(f meta nil))
|
||||||
|
(invoke [_ meta opts]
|
||||||
|
(f meta opts))
|
||||||
|
#?(:clj
|
||||||
|
(applyTo [this args]
|
||||||
|
(AFn/applyToHelper this args))))
|
||||||
|
|
||||||
(extend-protocol ExpandMiddleware
|
(extend-protocol ExpandMiddleware
|
||||||
|
|
||||||
#?(:clj clojure.lang.APersistentVector
|
#?(:clj clojure.lang.APersistentVector
|
||||||
:cljs cljs.core.PersistentVector)
|
:cljs cljs.core.PersistentVector)
|
||||||
(expand-middleware [[f & args] _]
|
(expand-middleware [[f & args] meta opts]
|
||||||
(fn [handler]
|
(if-let [mw (expand-middleware f meta opts)]
|
||||||
(apply f handler args)))
|
(fn [handler]
|
||||||
|
(apply mw handler args))))
|
||||||
|
|
||||||
#?(:clj clojure.lang.Fn
|
#?(:clj clojure.lang.Fn
|
||||||
:cljs function)
|
:cljs function)
|
||||||
(expand-middleware [this _] this)
|
(expand-middleware [this _ _] this)
|
||||||
|
|
||||||
|
MiddlewareGenerator
|
||||||
|
(expand-middleware [this meta opts]
|
||||||
|
(if-let [mw (this meta opts)]
|
||||||
|
(fn [handler & args]
|
||||||
|
(apply mw handler args))))
|
||||||
|
|
||||||
nil
|
nil
|
||||||
(expand-middleware [_ _]))
|
(expand-middleware [_ _ _]))
|
||||||
|
|
||||||
(defn- ensure-handler! [path meta scope]
|
(defn- ensure-handler! [path meta scope]
|
||||||
(when-not (:handler meta)
|
(when-not (:handler meta)
|
||||||
|
|
@ -28,18 +49,22 @@
|
||||||
(merge {:path path, :meta meta}
|
(merge {:path path, :meta meta}
|
||||||
(if scope {:scope scope}))))))
|
(if scope {:scope scope}))))))
|
||||||
|
|
||||||
(defn compose-middleware [middleware opts]
|
(defn compose-middleware [middleware meta opts]
|
||||||
(->> middleware
|
(->> middleware
|
||||||
(keep identity)
|
(keep identity)
|
||||||
(map #(expand-middleware % opts))
|
(map #(expand-middleware % meta opts))
|
||||||
|
(keep identity)
|
||||||
(apply comp identity)))
|
(apply comp identity)))
|
||||||
|
|
||||||
|
(defn gen [f & args]
|
||||||
|
(->MiddlewareGenerator f args))
|
||||||
|
|
||||||
(defn compile-handler
|
(defn compile-handler
|
||||||
([route opts]
|
([route opts]
|
||||||
(compile-handler route opts nil))
|
(compile-handler route opts nil))
|
||||||
([[path {:keys [middleware handler] :as meta}] opts scope]
|
([[path {:keys [middleware handler] :as meta}] opts scope]
|
||||||
(ensure-handler! path meta scope)
|
(ensure-handler! path meta scope)
|
||||||
((compose-middleware middleware opts) handler)))
|
((compose-middleware middleware meta opts) handler)))
|
||||||
|
|
||||||
(defn router
|
(defn router
|
||||||
([data]
|
([data]
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,5 @@
|
||||||
([data]
|
([data]
|
||||||
(router data nil))
|
(router data nil))
|
||||||
([data opts]
|
([data opts]
|
||||||
(let [opts (meta-merge {:coerce coerce-handler
|
(let [opts (meta-merge {:coerce coerce-handler, :compile compile-handler} opts)]
|
||||||
:compile compile-handler} opts)]
|
|
||||||
(reitit/router data opts))))
|
(reitit/router data opts))))
|
||||||
|
|
|
||||||
|
|
@ -96,15 +96,15 @@
|
||||||
(reitit/routes router))))
|
(reitit/routes router))))
|
||||||
(testing "route match contains compiled handler"
|
(testing "route match contains compiled handler"
|
||||||
(is (= 2 @compile-times))
|
(is (= 2 @compile-times))
|
||||||
(let [{:keys [handler]} (reitit/match-by-path router "/api/pong")]
|
(let [{:keys [result]} (reitit/match-by-path router "/api/pong")]
|
||||||
(is handler)
|
(is result)
|
||||||
(is (= "/api/pong" (handler)))
|
(is (= "/api/pong" (result)))
|
||||||
(is (= 2 @compile-times))))))
|
(is (= 2 @compile-times))))))
|
||||||
(testing "default compile"
|
(testing "default compile"
|
||||||
(let [router (reitit/router ["/ping" (constantly "ok")])]
|
(let [router (reitit/router ["/ping" (constantly "ok")])]
|
||||||
(let [{:keys [handler]} (reitit/match-by-path router "/ping")]
|
(let [{:keys [result]} (reitit/match-by-path router "/ping")]
|
||||||
(is handler)
|
(is result)
|
||||||
(is (= "ok" (handler)))))))
|
(is (= "ok" (result)))))))
|
||||||
|
|
||||||
(testing "custom router"
|
(testing "custom router"
|
||||||
(let [router (reitit/router ["/ping"] {:router (fn [_ _]
|
(let [router (reitit/router ["/ping"] {:router (fn [_ _]
|
||||||
|
|
|
||||||
129
test/cljc/reitit/middleware_test.cljc
Normal file
129
test/cljc/reitit/middleware_test.cljc
Normal file
|
|
@ -0,0 +1,129 @@
|
||||||
|
(ns reitit.middleware-test
|
||||||
|
(:require [clojure.test :refer [deftest testing is]]
|
||||||
|
[reitit.middleware :as middleware]
|
||||||
|
[clojure.set :as set]
|
||||||
|
[reitit.core :as reitit])
|
||||||
|
#?(: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))))
|
||||||
|
|
||||||
|
(defn handler
|
||||||
|
([{:keys [::mw]}]
|
||||||
|
{:status 200 :body (conj mw :ok)})
|
||||||
|
([request respond raise]
|
||||||
|
(respond (handler request))))
|
||||||
|
|
||||||
|
(deftest expand-middleware-test
|
||||||
|
(testing "middleware generators"
|
||||||
|
(let [calls (atom 0)]
|
||||||
|
|
||||||
|
(testing "record generator"
|
||||||
|
(reset! calls 0)
|
||||||
|
(let [syntax [(middleware/gen
|
||||||
|
(fn [meta _]
|
||||||
|
(swap! calls inc)
|
||||||
|
(fn [handler value]
|
||||||
|
(swap! calls inc)
|
||||||
|
(fn [request]
|
||||||
|
[meta value request]))))]
|
||||||
|
app ((middleware/compose-middleware syntax :meta {}) identity :value)]
|
||||||
|
(dotimes [_ 10]
|
||||||
|
(is (= [:meta :value :request] (app :request)))
|
||||||
|
(is (= 2 @calls)))))
|
||||||
|
|
||||||
|
(testing "middleware generator as function"
|
||||||
|
(reset! calls 0)
|
||||||
|
(let [syntax (middleware/gen
|
||||||
|
(fn [meta _]
|
||||||
|
(swap! calls inc)
|
||||||
|
(fn [handler value]
|
||||||
|
(swap! calls inc)
|
||||||
|
(fn [request]
|
||||||
|
[meta value request]))))
|
||||||
|
app ((syntax :meta nil) identity :value)]
|
||||||
|
(dotimes [_ 10]
|
||||||
|
(is (= [:meta :value :request] (app :request)))
|
||||||
|
(is (= 2 @calls)))))
|
||||||
|
|
||||||
|
(testing "generator vector"
|
||||||
|
(reset! calls 0)
|
||||||
|
(let [syntax [[(middleware/gen
|
||||||
|
(fn [meta _]
|
||||||
|
(swap! calls inc)
|
||||||
|
(fn [handler value]
|
||||||
|
(swap! calls inc)
|
||||||
|
(fn [request]
|
||||||
|
[meta value request])))) :value]]
|
||||||
|
app ((middleware/compose-middleware syntax :meta {}) identity)]
|
||||||
|
(is (= [:meta :value :request] (app :request)))
|
||||||
|
(dotimes [_ 10]
|
||||||
|
(is (= [:meta :value :request] (app :request)))
|
||||||
|
(is (= 2 @calls)))))
|
||||||
|
|
||||||
|
(testing "generator can return nil"
|
||||||
|
(reset! calls 0)
|
||||||
|
(let [syntax [[(middleware/gen
|
||||||
|
(fn [meta _])) :value]]
|
||||||
|
app ((middleware/compose-middleware syntax :meta {}) identity)]
|
||||||
|
(is (= :request (app :request)))
|
||||||
|
(dotimes [_ 10]
|
||||||
|
(is (= :request (app :request)))))))))
|
||||||
|
|
||||||
|
|
||||||
|
(deftest middleware-router-test
|
||||||
|
|
||||||
|
(testing "all paths should have a handler"
|
||||||
|
(is (thrown-with-msg?
|
||||||
|
ExceptionInfo
|
||||||
|
#"path \"/ping\" doesn't have a :handler defined"
|
||||||
|
(middleware/router ["/ping"]))))
|
||||||
|
|
||||||
|
(testing "ring-handler"
|
||||||
|
(let [api-mw #(mw % :api)
|
||||||
|
router (middleware/router
|
||||||
|
[["/ping" handler]
|
||||||
|
["/api" {:middleware [api-mw]}
|
||||||
|
["/ping" handler]
|
||||||
|
["/admin" {:middleware [[mw :admin]]}
|
||||||
|
["/ping" handler]]]])
|
||||||
|
app (fn
|
||||||
|
([{:keys [uri] :as request}]
|
||||||
|
(if-let [handler (:result (reitit/match-by-path router uri))]
|
||||||
|
(handler request)))
|
||||||
|
([{:keys [uri] :as request} respond raise]
|
||||||
|
(if-let [handler (:result (reitit/match-by-path router uri))]
|
||||||
|
(handler request respond raise))))]
|
||||||
|
|
||||||
|
(testing "not found"
|
||||||
|
(is (= nil (app {:uri "/favicon.ico"}))))
|
||||||
|
|
||||||
|
(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 "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)))))))
|
||||||
|
|
@ -26,50 +26,6 @@
|
||||||
([request respond raise]
|
([request respond raise]
|
||||||
(respond (handler request))))
|
(respond (handler request))))
|
||||||
|
|
||||||
(deftest middleware-router-test
|
|
||||||
|
|
||||||
(testing "all paths should have a handler"
|
|
||||||
(is (thrown-with-msg?
|
|
||||||
ExceptionInfo
|
|
||||||
#"path \"/ping\" doesn't have a :handler defined"
|
|
||||||
(middleware/router ["/ping"]))))
|
|
||||||
|
|
||||||
(testing "ring-handler"
|
|
||||||
(let [api-mw #(mw % :api)
|
|
||||||
router (middleware/router
|
|
||||||
[["/ping" handler]
|
|
||||||
["/api" {:middleware [api-mw]}
|
|
||||||
["/ping" handler]
|
|
||||||
["/admin" {:middleware [[mw :admin]]}
|
|
||||||
["/ping" handler]]]])
|
|
||||||
app (ring/ring-handler router)]
|
|
||||||
|
|
||||||
(testing "router can be extracted"
|
|
||||||
(is (= router (ring/get-router app))))
|
|
||||||
|
|
||||||
(testing "not found"
|
|
||||||
(is (= nil (app {:uri "/favicon.ico"}))))
|
|
||||||
|
|
||||||
(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 "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)))))))
|
|
||||||
|
|
||||||
|
|
||||||
(deftest ring-router-test
|
(deftest ring-router-test
|
||||||
|
|
||||||
(testing "all paths should have a handler"
|
(testing "all paths should have a handler"
|
||||||
|
|
@ -142,7 +98,7 @@
|
||||||
|
|
||||||
(testing "only top-level route names are matched"
|
(testing "only top-level route names are matched"
|
||||||
(is (= [::all ::get ::users]
|
(is (= [::all ::get ::users]
|
||||||
(reitit/route-names router))))
|
(reitit/route-names router))))
|
||||||
|
|
||||||
(testing "all named routes can be matched"
|
(testing "all named routes can be matched"
|
||||||
(doseq [name (reitit/route-names router)]
|
(doseq [name (reitit/route-names router)]
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue