diff --git a/CHANGELOG.md b/CHANGELOG.md
index e56d2723..b0c351df 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,26 @@
## 0.1.2-SNAPSHOT
+### `reitit-core`
+
+* Better handling of `nil` in route syntax:
+ * explicit `nil` after path string is always handled as `nil` route
+ * `nil` as path string causes the whole route to be `nil`
+ * `nil` as child route is stripped away
+
+```clj
+(testing "nil routes are stripped"
+ (is (= [] (r/routes (r/router nil))))
+ (is (= [] (r/routes (r/router [nil ["/ping"]]))))
+ (is (= [] (r/routes (r/router [nil [nil] [[nil nil nil]]]))))
+ (is (= [] (r/routes (r/router ["/ping" [nil "/pong"]])))))
+```
+### `reitit-ring`
+
+* Use HTTP redirect (302) with index-files in `reitit.ring/create-resource-handler`.
+* `reitit.ring/create-default-handler` now conforms to [RING Spec](https://github.com/ring-clojure/ring/blob/master/SPEC), Fixes [#83](https://github.com/metosin/reitit/issues/83)
+
+https://github.com/metosin/reitit/issues/83
+
### `reitit-schema`
* updated dependencies:
@@ -14,6 +35,8 @@
### `reitit-swagger-ui`
+* Use HTTP redirect (302) with index-files in `reitit.swagger-ui/create-swagger-ui-handler`.
+
* updated dependencies:
```clj
diff --git a/doc/ring/swagger.md b/doc/ring/swagger.md
index 3d282a65..cc6dadc6 100644
--- a/doc/ring/swagger.md
+++ b/doc/ring/swagger.md
@@ -183,7 +183,7 @@ Whole example project is in [`/examples/ring-swagger`](https://github.com/metosi
"application/transit+json"}}}})
(ring/routes
(swagger-ui/create-swagger-ui-handler
- {:path "", :url "/api/swagger.json"})
+ {:path "/", :url "/api/swagger.json"})
(ring/create-default-handler))))
(defn start []
diff --git a/examples/just-coercion-with-ring/project.clj b/examples/just-coercion-with-ring/project.clj
index d14fe645..e3d0513e 100644
--- a/examples/just-coercion-with-ring/project.clj
+++ b/examples/just-coercion-with-ring/project.clj
@@ -3,4 +3,4 @@
:dependencies [[org.clojure/clojure "1.9.0"]
[ring "1.6.3"]
[metosin/muuntaja "0.4.1"]
- [metosin/reitit "0.1.1"]])
+ [metosin/reitit "0.1.2-SNAPSHOT"]])
diff --git a/examples/ring-example/project.clj b/examples/ring-example/project.clj
index 332cb4b8..31429cc4 100644
--- a/examples/ring-example/project.clj
+++ b/examples/ring-example/project.clj
@@ -3,4 +3,4 @@
:dependencies [[org.clojure/clojure "1.9.0"]
[ring "1.6.3"]
[metosin/muuntaja "0.4.1"]
- [metosin/reitit "0.1.1"]])
+ [metosin/reitit "0.1.2-SNAPSHOT"]])
diff --git a/examples/ring-swagger/project.clj b/examples/ring-swagger/project.clj
index dfe97c89..37283a17 100644
--- a/examples/ring-swagger/project.clj
+++ b/examples/ring-swagger/project.clj
@@ -3,5 +3,5 @@
:dependencies [[org.clojure/clojure "1.9.0"]
[ring "1.6.3"]
[metosin/muuntaja "0.5.0"]
- [metosin/reitit "0.1.1"]]
+ [metosin/reitit "0.1.2-SNAPSHOT"]]
:repl-options {:init-ns example.server})
diff --git a/modules/reitit-core/project.clj b/modules/reitit-core/project.clj
index 23099fba..d241b12b 100644
--- a/modules/reitit-core/project.clj
+++ b/modules/reitit-core/project.clj
@@ -1,4 +1,4 @@
-(defproject metosin/reitit-core "0.1.1"
+(defproject metosin/reitit-core "0.1.2-SNAPSHOT"
:description "Snappy data-driven router for Clojure(Script)"
:url "https://github.com/metosin/reitit"
:license {:name "Eclipse Public License"
diff --git a/modules/reitit-core/src/reitit/core.cljc b/modules/reitit-core/src/reitit/core.cljc
index 35d2c87b..b3785447 100644
--- a/modules/reitit-core/src/reitit/core.cljc
+++ b/modules/reitit-core/src/reitit/core.cljc
@@ -39,14 +39,14 @@
(walk-one [pacc macc routes]
(if (vector? (first routes))
(walk-many pacc macc routes)
- (let [[path & [maybe-arg :as args]] routes
- [data childs] (if (vector? maybe-arg)
- [{} args]
- [maybe-arg (rest args)])
- macc (into macc (expand data opts))]
- (if (seq childs)
- (walk-many (str pacc path) macc childs)
- [[(str pacc path) macc]]))))]
+ (when (string? (first routes))
+ (let [[path & [maybe-arg :as args]] routes
+ [data childs] (if (or (vector? maybe-arg) (nil? maybe-arg))
+ [{} args]
+ [maybe-arg (rest args)])
+ macc (into macc (expand data opts))
+ child-routes (walk-many (str pacc path) macc (keep identity childs))]
+ (if (seq childs) (seq child-routes) [[(str pacc path) macc]])))))]
(walk-one path (mapv identity data) raw-routes)))
(defn map-data [f routes]
@@ -87,10 +87,10 @@
(conflicts-str conflicts)
{:conflicts conflicts})))
-(defn name-lookup [[_ {:keys [name]}] opts]
+(defn name-lookup [[_ {:keys [name]}] _]
(if name #{name}))
-(defn find-names [routes opts]
+(defn find-names [routes _]
(into [] (keep #(-> % second :name)) routes))
(defn- compile-route [[p m :as route] {:keys [compile] :as opts}]
diff --git a/modules/reitit-core/src/reitit/spec.cljc b/modules/reitit-core/src/reitit/spec.cljc
index d3361f0d..cf98cf24 100644
--- a/modules/reitit-core/src/reitit/spec.cljc
+++ b/modules/reitit-core/src/reitit/spec.cljc
@@ -9,18 +9,19 @@
(s/def ::path (s/with-gen string? #(gen/fmap (fn [s] (str "/" s)) (s/gen string?))))
-(s/def ::arg (s/and any? (complement vector?)))
+(s/def ::arg (s/and some? (complement vector?)))
(s/def ::data (s/map-of keyword? any?))
(s/def ::result any?)
(s/def ::raw-route
- (s/cat :path ::path
- :arg (s/? ::arg)
- :childs (s/* (s/and (s/nilable ::raw-route)))))
+ (s/nilable
+ (s/cat :path ::path
+ :arg (s/? ::arg)
+ :childs (s/* (s/and (s/nilable ::raw-routes))))))
(s/def ::raw-routes
(s/or :route ::raw-route
- :routes (s/coll-of ::raw-route :into [])))
+ :routes (s/coll-of ::raw-routes :into [])))
(s/def ::route
(s/cat :path ::path
diff --git a/modules/reitit-ring/project.clj b/modules/reitit-ring/project.clj
index 71be148e..fbb913c1 100644
--- a/modules/reitit-ring/project.clj
+++ b/modules/reitit-ring/project.clj
@@ -1,4 +1,4 @@
-(defproject metosin/reitit-ring "0.1.1"
+(defproject metosin/reitit-ring "0.1.2-SNAPSHOT"
:description "Reitit: Ring routing"
:url "https://github.com/metosin/reitit"
:license {:name "Eclipse Public License"
diff --git a/modules/reitit-ring/src/reitit/ring.cljc b/modules/reitit-ring/src/reitit/ring.cljc
index 020ed15d..1c03e4f0 100644
--- a/modules/reitit-ring/src/reitit/ring.cljc
+++ b/modules/reitit-ring/src/reitit/ring.cljc
@@ -46,9 +46,9 @@
| `:not-acceptable` | 406, handler returned `nil`"
([]
(create-default-handler
- {:not-found (constantly {:status 404, :body ""})
- :method-not-allowed (constantly {:status 405, :body ""})
- :not-acceptable (constantly {:status 406, :body ""})}))
+ {:not-found (constantly {:status 404, :body "", :headers {}})
+ :method-not-allowed (constantly {:status 405, :body "", :headers {}})
+ :not-acceptable (constantly {:status 406, :body "", :headers {}})}))
([{:keys [not-found method-not-allowed not-acceptable]}]
(fn
([request]
@@ -96,24 +96,30 @@
(fn
([request] (handler request))
([request respond _] (respond (handler request)))))
+ join-paths (fn [& paths]
+ (str/replace (str/replace (str/join "/" paths) #"([/]+)" "/") #"/$" ""))
resource-response (fn [path]
- (if-let [response (or (paths path) (response/resource-response path options))]
+ (if-let [response (or (paths (join-paths "/" path))
+ (response/resource-response path options))]
(response/content-type response (mime-type/ext-mime-type path))))
- path-or-index-response (fn [path]
+ path-or-index-response (fn [path uri]
(or (resource-response path)
- (let [separator (if-not (str/ends-with? path "/") "/")]
- (loop [[file & files] index-files]
- (if file
- (or (resource-response (str path separator file))
- (recur files)))))))
+ (loop [[file & files] index-files]
+ (if file
+ (if (resource-response (join-paths path file))
+ (response/redirect (join-paths uri file))
+ (recur files))))))
handler (if path
(fn [request]
(let [uri (:uri request)]
(if-let [path (if (>= (count uri) path-size) (subs uri path-size))]
- (path-or-index-response path))))
+ (path-or-index-response path uri))))
(fn [request]
- (let [path (-> request :path-params parameter)]
- (or (path-or-index-response path) {:status 404}))))]
+ (let [uri (:uri request)
+ path (-> request :path-params parameter)]
+ (or (path-or-index-response path uri)
+ ;; TODO: use generic not-found handler
+ {:status 404}))))]
(create handler)))))
(defn ring-handler
@@ -129,7 +135,7 @@
(fn
([request]
(if-let [match (r/match-by-path router (:uri request))]
- (let [method (:request-method request :any)
+ (let [method (:request-method request)
path-params (:path-params match)
result (:result match)
handler (-> result method :handler (or default-handler))
@@ -141,7 +147,7 @@
(default-handler request)))
([request respond raise]
(if-let [match (r/match-by-path router (:uri request))]
- (let [method (:request-method request :any)
+ (let [method (:request-method request)
path-params (:path-params match)
result (:result match)
handler (-> result method :handler (or default-handler))
diff --git a/modules/reitit-schema/project.clj b/modules/reitit-schema/project.clj
index 0663c72b..d107bada 100644
--- a/modules/reitit-schema/project.clj
+++ b/modules/reitit-schema/project.clj
@@ -1,4 +1,4 @@
-(defproject metosin/reitit-schema "0.1.1"
+(defproject metosin/reitit-schema "0.1.2-SNAPSHOT"
:description "Reitit: Plumatic Schema coercion"
:url "https://github.com/metosin/reitit"
:license {:name "Eclipse Public License"
diff --git a/modules/reitit-spec/project.clj b/modules/reitit-spec/project.clj
index f217ae61..9ad9b343 100644
--- a/modules/reitit-spec/project.clj
+++ b/modules/reitit-spec/project.clj
@@ -1,4 +1,4 @@
-(defproject metosin/reitit-spec "0.1.1"
+(defproject metosin/reitit-spec "0.1.2-SNAPSHOT"
:description "Reitit: clojure.spec coercion"
:url "https://github.com/metosin/reitit"
:license {:name "Eclipse Public License"
diff --git a/modules/reitit-swagger-ui/project.clj b/modules/reitit-swagger-ui/project.clj
index 5d530067..528791cd 100644
--- a/modules/reitit-swagger-ui/project.clj
+++ b/modules/reitit-swagger-ui/project.clj
@@ -1,4 +1,4 @@
-(defproject metosin/reitit-swagger-ui "0.1.1"
+(defproject metosin/reitit-swagger-ui "0.1.2-SNAPSHOT"
:description "Reitit: Swagger-ui support"
:url "https://github.com/metosin/reitit"
:license {:name "Eclipse Public License"
diff --git a/modules/reitit-swagger-ui/src/reitit/swagger_ui.cljc b/modules/reitit-swagger-ui/src/reitit/swagger_ui.cljc
index 202556a8..137dbcb5 100644
--- a/modules/reitit-swagger-ui/src/reitit/swagger_ui.cljc
+++ b/modules/reitit-swagger-ui/src/reitit/swagger_ui.cljc
@@ -26,7 +26,7 @@
;; with path and url set, swagger validator disabled
(swagger-ui/create-swagger-ui-handler
- {:path \"\"
+ {:path \"/\"
:url \"/api/swagger.json\"
:config {:validator-url nil})"
([]
@@ -42,11 +42,11 @@
(update $ :root (fnil identity "swagger-ui"))
(update $ :url (fnil identity "/swagger.json"))
(update $ :config #(->> % (map mixed-case-key) (into {})))
- (assoc $ :paths {"conf.js" {:headers {"Content-Type" "application/javascript"}
- :status 200
- :body (conf-js $)}
- "config.json" {:headers {"Content-Type" "application/json"}
- :status 200
- :body (config-json $)}}))]
+ (assoc $ :paths {"/conf.js" {:headers {"Content-Type" "application/javascript"}
+ :status 200
+ :body (conf-js $)}
+ "/config.json" {:headers {"Content-Type" "application/json"}
+ :status 200
+ :body (config-json $)}}))]
(ring/routes
(ring/create-resource-handler options))))))
diff --git a/modules/reitit-swagger/project.clj b/modules/reitit-swagger/project.clj
index 0339c0cc..e301f223 100644
--- a/modules/reitit-swagger/project.clj
+++ b/modules/reitit-swagger/project.clj
@@ -1,4 +1,4 @@
-(defproject metosin/reitit-swagger "0.1.1"
+(defproject metosin/reitit-swagger "0.1.2-SNAPSHOT"
:description "Reitit: Swagger-support"
:url "https://github.com/metosin/reitit"
:license {:name "Eclipse Public License"
diff --git a/modules/reitit/project.clj b/modules/reitit/project.clj
index 51aec6d4..6d1fffa5 100644
--- a/modules/reitit/project.clj
+++ b/modules/reitit/project.clj
@@ -1,4 +1,4 @@
-(defproject metosin/reitit "0.1.1"
+(defproject metosin/reitit "0.1.2-SNAPSHOT"
:description "Snappy data-driven router for Clojure(Script)"
:url "https://github.com/metosin/reitit"
:license {:name "Eclipse Public License"
diff --git a/perf-test/clj/reitit/bide_perf_test.clj b/perf-test/clj/reitit/bide_perf_test.clj
index 9e3aecf8..be26dcde 100644
--- a/perf-test/clj/reitit/bide_perf_test.clj
+++ b/perf-test/clj/reitit/bide_perf_test.clj
@@ -10,7 +10,8 @@
[io.pedestal.http.route.definition.table :as table]
[io.pedestal.http.route.map-tree :as map-tree]
[io.pedestal.http.route.router :as pedestal]
- [io.pedestal.http.route :as route]))
+ [io.pedestal.http.route :as route]
+ [reitit.ring :as ring]))
;;
;; start repl with `lein perf repl`
@@ -62,6 +63,26 @@
["/auth/recovery/token/:token" :auth/recovery]
["/workspace/:project/:page" :workspace/page]]))
+(def ring-app
+ (ring/ring-handler
+ (ring/router
+ [["/auth/login" {:get identity}]
+ ["/auth/recovery/token/:token" {:get identity}]
+ ["/workspace/:project/:page" {:get identity}]])))
+
+(comment
+
+ (ring-app {:request-method :get, :uri "/auth/login"})
+
+ ;; 213ns
+ ;; 204ns (remove if)
+ ;; 163ns (inline fast-assoc)
+ ;; 156ns (don't inline fast-assoc)
+ ;; 128ns (single method dispatch)
+ ;; 80ns --> (don't inject router & match)
+ (cc/quick-bench
+ (ring-app {:request-method :post, :uri "/auth/login"})))
+
(defn routing-test1 []
(suite "static route")
diff --git a/perf-test/clj/reitit/json_perf.cljc b/perf-test/clj/reitit/json_perf.cljc
new file mode 100644
index 00000000..b9d81dfd
--- /dev/null
+++ b/perf-test/clj/reitit/json_perf.cljc
@@ -0,0 +1,109 @@
+(ns reitit.json-perf
+ (:require [criterium.core :as cc]
+ [reitit.perf-utils :refer :all]
+
+ ;; reitit
+ [reitit.ring :as ring]
+ [muuntaja.middleware :as mm]
+
+ ;; bidi-yada
+ [yada.yada :as yada]
+ [bidi.ring :as bidi-ring]
+ [byte-streams :as bs]
+
+ ;; defaults
+ [ring.middleware.defaults :as defaults]
+ [compojure.core :as compojure]
+ [clojure.string :as str]))
+
+;;
+;; start repl with `lein perf repl`
+;; perf measured with the following setup:
+;;
+;; Model Name: MacBook Pro
+;; Model Identifier: MacBookPro113
+;; Processor Name: Intel Core i7
+;; Processor Speed: 2,5 GHz
+;; Number of Processors: 1
+;; Total Number of Cores: 4
+;; L2 Cache (per Core): 256 KB
+;; L3 Cache: 6 MB
+;; Memory: 16 GB
+;;
+
+;; TODO: naive implementation
+(defn- with-security-headers [response]
+ (update
+ response
+ :headers
+ (fn [headers]
+ (-> headers
+ (assoc "x-frame-options" "SAMEORIGIN")
+ (assoc "x-xss-protection" "1; mode=block")
+ (assoc "x-content-type-options" "nosniff")))))
+
+(def security-middleware
+ {:name ::security
+ :wrap (fn [handler]
+ (fn [request]
+ (with-security-headers (handler request))))})
+
+(def reitit-app
+ (ring/ring-handler
+ (ring/router
+ ["/api/ping"
+ {:get {:handler (fn [_] {:status 200, :body {:ping "pong"}})}}]
+ {:data {:middleware [mm/wrap-format
+ security-middleware]}})))
+
+(def bidi-yada-app
+ (bidi-ring/make-handler
+ ["/api/ping"
+ (yada/resource
+ {:produces {:media-type "application/json"}
+ :methods {:get {:response (fn [_] {:ping "pong"})}}})]))
+
+(def defaults-app
+ (defaults/wrap-defaults
+ (mm/wrap-format
+ (compojure/GET "/api/ping" [] {:status 200, :body {:ping "pong"}}))
+ defaults/site-defaults))
+
+(def request {:request-method :get, :uri "/api/ping"})
+
+(comment
+ (defaults-app request)
+ @(bidi-yada-app request)
+ (reitit-app request))
+
+(comment
+ (slurp (:body (defaults-app request)))
+ (slurp (:body (reitit-app request)))
+ (bs/to-string (:body @(bidi-yada-app request))))
+
+
+(defn expect! [body]
+ (assert (str/starts-with? body "{\"ping\":\"pong\"}")))
+
+(defn perf-test []
+
+ ;; 176µs
+ (title "compojure + ring-defaults")
+ (let [f (fn [] (defaults-app request))]
+ (expect! (-> (f) :body slurp))
+ (cc/quick-bench (f)))
+
+ ;; 60µs
+ (title "bidi + yada")
+ (let [f (fn [] (bidi-yada-app request))]
+ (expect! (-> (f) deref :body bs/to-string))
+ (cc/quick-bench (f)))
+
+ ;; 5.0µs
+ (title "reitit-ring")
+ (let [f (fn [] (reitit-app request))]
+ (expect! (-> (f) :body slurp))
+ (cc/quick-bench (f))))
+
+(comment
+ (perf-test))
diff --git a/perf-test/clj/reitit/middleware_interceptor_perf.clj b/perf-test/clj/reitit/middleware_interceptor_perf.clj
index d769ec61..1079533d 100644
--- a/perf-test/clj/reitit/middleware_interceptor_perf.clj
+++ b/perf-test/clj/reitit/middleware_interceptor_perf.clj
@@ -31,7 +31,7 @@
(defrecord RequestOrContext [values queue stack])
-(def +items+ 100)
+(def +items+ 10)
(defn expected! [x]
(assert (= (range +items+) (:values x))))
@@ -47,18 +47,19 @@
map-request {}
record-request (map->RequestOrContext map-request)]
- ;; 10.8 µs
+ ;; 1000ns
(title "middleware - map")
(expected! (app map-request))
(cc/quick-bench
(app map-request))
- ;; 4.7 µs
+ ;; 365ns
(title "middleware - record")
(expected! (app record-request))
(cc/quick-bench
(app record-request))
+ ;; 6900ns
(title "middleware - dynamic")
(expected! ((middleware/chain mw identity) record-request))
(cc/quick-bench
@@ -110,21 +111,21 @@
{:enter (interceptor value)}) (range +items+)))
ctx (io.pedestal.interceptor.chain/enqueue nil is)]
- ;; 78 µs
+ ;; 8400ns
(title "pedestal")
(cc/quick-bench
(io.pedestal.interceptor.chain/execute ctx))))
-(defn pedestal-tuned-chain-text []
- (let [is (map io.pedestal.interceptor/interceptor
- (map (fn [value]
- {:enter (interceptor value)}) (range +items+)))
- ctx (reitit.chain/map->Context (reitit.chain/enqueue nil is))]
+#_(defn pedestal-tuned-chain-text []
+ (let [is (map io.pedestal.interceptor/interceptor
+ (map (fn [value]
+ {:enter (interceptor value)}) (range +items+)))
+ ctx (reitit.chain/map->Context (reitit.chain/enqueue nil is))]
- ;; 67 µs
- (title "pedestal - tuned")
- (cc/quick-bench
- (reitit.chain/execute ctx))))
+ ;; 67 µs
+ (title "pedestal - tuned")
+ (cc/quick-bench
+ (reitit.chain/execute ctx))))
;;
;; Naive chain
@@ -140,17 +141,17 @@
(defn interceptor-test []
(let [interceptors (map (fn [value] [interceptor value]) (range +items+))
- app (executor-reduce (interceptor/chain interceptors identity))
+ app (executor-reduce (interceptor/chain interceptors identity {}))
map-request {}
record-request (map->RequestOrContext map-request)]
- ;; 13.5 µs (Map)
+ ;; 1900ns
(title "interceptors - map")
(expected! (app map-request))
(cc/quick-bench
(app map-request))
- ;; 7.2 µs (Record)
+ ;; 1300ns
(title "interceptors - record")
(expected! (app record-request))
(cc/quick-bench
@@ -212,24 +213,24 @@
(defn interceptor-chain-test []
(let [interceptors (map (fn [value] [interceptor value]) (range +items+))
- app-reduce (executor-reduce (interceptor/chain interceptors identity))
- app-queue (executor-queue (interceptor/chain interceptors identity))
- app-ctx-queue (executor-ctx-queue (interceptor/chain interceptors identity))
+ app-reduce (executor-reduce (interceptor/chain interceptors identity {}))
+ app-queue (executor-queue (interceptor/chain interceptors identity {}))
+ app-ctx-queue (executor-ctx-queue (interceptor/chain interceptors identity {}))
request {}]
- ;; 14.2 µs
+ ;; 2000ns
(title "interceptors - reduce")
(expected! (app-reduce request))
(cc/quick-bench
(app-reduce request))
- ;; 19.4 µs
+ ;; 2500ns
(title "interceptors - queue")
(expected! (app-queue request))
(cc/quick-bench
(app-queue request))
- ;; 30.9 µs
+ ;; 3200ns
(title "interceptors - ctx-queue")
(expected! (app-ctx-queue request))
(cc/quick-bench
diff --git a/project.clj b/project.clj
index 7a682cc8..bbe85707 100644
--- a/project.clj
+++ b/project.clj
@@ -1,4 +1,4 @@
-(defproject metosin/reitit-parent "0.1.1"
+(defproject metosin/reitit-parent "0.1.2-SNAPSHOT"
:description "Snappy data-driven router for Clojure(Script)"
:url "https://github.com/metosin/reitit"
:license {:name "Eclipse Public License"
@@ -9,13 +9,13 @@
:source-uri "https://github.com/metosin/reitit/{version}/{filepath}#L{line}"
:metadata {:doc/format :markdown}}
- :managed-dependencies [[metosin/reitit "0.1.1"]
- [metosin/reitit-core "0.1.1"]
- [metosin/reitit-ring "0.1.1"]
- [metosin/reitit-spec "0.1.1"]
- [metosin/reitit-schema "0.1.1"]
- [metosin/reitit-swagger "0.1.1"]
- [metosin/reitit-swagger-ui "0.1.1"]
+ :managed-dependencies [[metosin/reitit "0.1.2-SNAPSHOT"]
+ [metosin/reitit-core "0.1.2-SNAPSHOT"]
+ [metosin/reitit-ring "0.1.2-SNAPSHOT"]
+ [metosin/reitit-spec "0.1.2-SNAPSHOT"]
+ [metosin/reitit-schema "0.1.2-SNAPSHOT"]
+ [metosin/reitit-swagger "0.1.2-SNAPSHOT"]
+ [metosin/reitit-swagger-ui "0.1.2-SNAPSHOT"]
[meta-merge "1.0.0"]
[ring/ring-core "1.6.3"]
@@ -53,7 +53,7 @@
[ring "1.6.3"]
[ikitommi/immutant-web "3.0.0-alpha1"]
- [metosin/muuntaja "0.5.0"]
+ [metosin/muuntaja "0.6.0-SNAPSHOT"]
[metosin/ring-swagger-ui "2.2.10"]
[metosin/jsonista "0.2.1"]
@@ -70,6 +70,8 @@
[ikitommi/immutant-web "3.0.0-alpha1"]
[io.pedestal/pedestal.route "0.5.3"]
[org.clojure/core.async "0.4.474"]
+ [yada "1.2.13"]
+ [ring/ring-defaults "0.3.1"]
[ataraxy "0.4.0"]
[bidi "2.1.3"]]}
:analyze {:jvm-opts ^:replace ["-server"
diff --git a/test/cljc/reitit/core_test.cljc b/test/cljc/reitit/core_test.cljc
index e8144e75..f8233888 100644
--- a/test/cljc/reitit/core_test.cljc
+++ b/test/cljc/reitit/core_test.cljc
@@ -108,6 +108,12 @@
r/segment-router :segment-router
r/mixed-router :mixed-router))
+ (testing "nil routes are stripped"
+ (is (= [] (r/routes (r/router nil))))
+ (is (= [] (r/routes (r/router [nil ["/ping"]]))))
+ (is (= [] (r/routes (r/router [nil [nil] [[nil nil nil]]]))))
+ (is (= [] (r/routes (r/router ["/ping" [nil "/pong"]])))))
+
(testing "route coercion & compilation"
(testing "custom compile"
diff --git a/test/cljc/reitit/ring_test.cljc b/test/cljc/reitit/ring_test.cljc
index 27a5ad83..5fb6d3d1 100644
--- a/test/cljc/reitit/ring_test.cljc
+++ b/test/cljc/reitit/ring_test.cljc
@@ -267,56 +267,154 @@
#?(:clj
(deftest resource-handler-test
- (doseq [[test app] [["inside a router"
- (ring/ring-handler
- (ring/router
- [["/ping" (constantly {:status 200, :body "pong"})]
- ["/files/*" (ring/create-resource-handler)]
- ["/*" (ring/create-resource-handler)]]
- {:conflicts (constantly nil)})
- (ring/create-default-handler))]
+ (let [redirect (fn [uri] {:status 302, :body "", :headers {"Location" uri}})
+ request (fn [uri] {:uri uri, :request-method :get})]
+ (testing "inside a router"
- ["outside of a router"
- (ring/ring-handler
- (ring/router
- ["/ping" (constantly {:status 200, :body "pong"})])
- (ring/routes
- (ring/create-resource-handler {:path "/files"})
- (ring/create-resource-handler {:path "/"})
- (ring/create-default-handler)))]]
- prefix ["" "/" "/files" "/files/"]
- :let [request (fn [uri] {:uri (str prefix uri), :request-method :get})]]
+ (testing "from root"
+ (let [app (ring/ring-handler
+ (ring/router
+ ["/*" (ring/create-resource-handler)])
+ (ring/create-default-handler))]
+ (testing test
+ (testing "different file-types"
+ (let [response (app (request "/hello.json"))]
+ (is (= "application/json" (get-in response [:headers "Content-Type"])))
+ (is (get-in response [:headers "Last-Modified"]))
+ (is (= "{\"hello\": \"file\"}" (slurp (:body response)))))
+ (let [response (app (request "/hello.xml"))]
+ (is (= "text/xml" (get-in response [:headers "Content-Type"])))
+ (is (get-in response [:headers "Last-Modified"]))
+ (is (= "