mirror of
https://github.com/metosin/reitit.git
synced 2025-12-17 16:31:11 +00:00
Merge branch 'CompiledMiddlewareAndSpecCoercion'
This commit is contained in:
commit
ec628bd05e
4 changed files with 145 additions and 2 deletions
|
|
@ -26,6 +26,9 @@
|
|||
[metosin/spec-tools "0.3.3"]
|
||||
[org.clojure/spec.alpha "0.1.123"]
|
||||
|
||||
[expound "0.2.1"]
|
||||
[orchestra "2017.08.13"]
|
||||
|
||||
[criterium "0.4.4"]
|
||||
[org.clojure/test.check "0.9.0"]
|
||||
[org.clojure/tools.namespace "0.2.11"]
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
(expand [_ _]))
|
||||
|
||||
(defn walk [data {:keys [path meta routes expand]
|
||||
:or {path "", meta [], routes [], expand expand}
|
||||
:or {meta [], routes [], expand expand}
|
||||
:as opts}]
|
||||
(letfn
|
||||
[(walk-many [p m r]
|
||||
|
|
@ -100,6 +100,9 @@
|
|||
(match-by-path [this path])
|
||||
(match-by-name [this name] [this name params]))
|
||||
|
||||
(defn router? [x]
|
||||
(satisfies? Router x))
|
||||
|
||||
(defrecord Match [template meta result params path])
|
||||
(defrecord PartialMatch [template meta result params required])
|
||||
|
||||
|
|
@ -242,7 +245,7 @@
|
|||
|
||||
| key | description |
|
||||
| -------------|-------------|
|
||||
| `:path` | Base-path for routes (default `\"\"`)
|
||||
| `:path` | Base-path for routes
|
||||
| `:routes` | Initial resolved routes (default `[]`)
|
||||
| `:meta` | Initial route meta (default `{}`)
|
||||
| `:expand` | Function of `arg opts => meta` to expand route arg to route meta-data (default `reitit.core/expand`)
|
||||
|
|
|
|||
63
src/reitit/spec.cljc
Normal file
63
src/reitit/spec.cljc
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
(ns reitit.spec
|
||||
(:require [clojure.spec.alpha :as s]
|
||||
[clojure.spec.gen.alpha :as gen]
|
||||
[clojure.string :as str]
|
||||
[reitit.core :as reitit]))
|
||||
|
||||
;;
|
||||
;; routes
|
||||
;;
|
||||
|
||||
(s/def ::path (s/with-gen (s/and string? #(str/starts-with? % "/"))
|
||||
#(gen/fmap (fn [s] (str "/" s)) (s/gen string?))))
|
||||
|
||||
(s/def ::arg (s/and any? (complement vector?)))
|
||||
(s/def ::meta (s/map-of keyword? any?))
|
||||
(s/def ::result any?)
|
||||
|
||||
(s/def ::raw-route
|
||||
(s/cat :path ::path
|
||||
:arg (s/? ::arg)
|
||||
:childs (s/* (s/and ::raw-route))))
|
||||
|
||||
(s/def ::raw-routes
|
||||
(s/or :route ::raw-route
|
||||
:routes (s/coll-of ::raw-route :into [])))
|
||||
|
||||
(s/def ::route
|
||||
(s/cat :path ::path
|
||||
:meta ::meta))
|
||||
|
||||
(s/def ::routes
|
||||
(s/or :route ::route
|
||||
:routes (s/coll-of ::route :into [])))
|
||||
|
||||
;;
|
||||
;; router
|
||||
;;
|
||||
|
||||
(s/def ::router reitit/router?)
|
||||
(s/def :reitit.router/path ::path)
|
||||
(s/def :reitit.router/routes ::routes)
|
||||
(s/def :reitit.router/meta ::meta)
|
||||
(s/def :reitit.router/expand fn?)
|
||||
(s/def :reitit.router/coerce fn?)
|
||||
(s/def :reitit.router/compile fn?)
|
||||
(s/def :reitit.router/conflicts fn?)
|
||||
(s/def :reitit.router/router fn?)
|
||||
|
||||
(s/def ::opts
|
||||
(s/nilable
|
||||
(s/keys :opt-un [:reitit.router/path
|
||||
:reitit.router/routes
|
||||
:reitit.router/meta
|
||||
:reitit.router/expand
|
||||
:reitit.router/coerce
|
||||
:reitit.router/compile
|
||||
:reitit.router/conflicts
|
||||
:reitit.router/router])))
|
||||
|
||||
(s/fdef reitit/router
|
||||
:args (s/or :1arity (s/cat :data (s/spec ::raw-routes))
|
||||
:2arity (s/cat :data (s/spec ::raw-routes), :opts ::opts))
|
||||
:ret ::router)
|
||||
74
test/cljc/reitit/spec_test.cljc
Normal file
74
test/cljc/reitit/spec_test.cljc
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
(ns reitit.spec-test
|
||||
(:require [clojure.test :refer [deftest testing is are]]
|
||||
[clojure.spec.test.alpha :as stest]
|
||||
[clojure.spec.alpha :as s]
|
||||
[reitit.core :as reitit]
|
||||
[reitit.spec :as spec])
|
||||
#?(:clj
|
||||
(:import (clojure.lang ExceptionInfo))))
|
||||
|
||||
(stest/instrument `reitit/router)
|
||||
|
||||
(deftest router-spec-test
|
||||
|
||||
(testing "router"
|
||||
|
||||
(testing "route-data"
|
||||
(are [data]
|
||||
(is (= true (reitit/router? (reitit/router data))))
|
||||
|
||||
["/api" {}]
|
||||
|
||||
[["/api" {}]]
|
||||
|
||||
["/api"
|
||||
["/ipa" ::ipa]
|
||||
["/tea"
|
||||
["/room"]]])
|
||||
|
||||
(testing "with invalid routes"
|
||||
(are [data]
|
||||
(is (thrown-with-msg?
|
||||
ExceptionInfo
|
||||
#"Call to #'reitit.core/router did not conform to spec"
|
||||
(reitit/router
|
||||
data)))
|
||||
|
||||
;; missing slash
|
||||
["invalid" {}]
|
||||
|
||||
;; path
|
||||
[:invalid {}]
|
||||
|
||||
;; vector meta
|
||||
["/api" []
|
||||
["/ipa"]])))
|
||||
|
||||
(testing "options"
|
||||
|
||||
(are [opts]
|
||||
(is (= true (reitit/router? (reitit/router ["/api"] opts))))
|
||||
|
||||
{:path "/"}
|
||||
{:meta {}}
|
||||
{:expand (fn [_ _] {})}
|
||||
{:coerce (fn [route _] route)}
|
||||
{:compile (fn [_ _])}
|
||||
{:conflicts (fn [_])}
|
||||
{:router reitit/linear-router})
|
||||
|
||||
(are [opts]
|
||||
(is (thrown-with-msg?
|
||||
ExceptionInfo
|
||||
#"Call to #'reitit.core/router did not conform to spec"
|
||||
(reitit/router
|
||||
["/api"] opts)))
|
||||
|
||||
{:path ""}
|
||||
{:path nil}
|
||||
{:meta nil}
|
||||
{:expand nil}
|
||||
{:coerce nil}
|
||||
{:compile nil}
|
||||
{:conflicts nil}
|
||||
{:router nil}))))
|
||||
Loading…
Reference in a new issue