Initial specs for reitit.core

This commit is contained in:
Tommi Reiman 2017-09-01 11:32:08 +03:00
parent 76f7f28591
commit 7d4db18000
4 changed files with 154 additions and 0 deletions

View file

@ -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"]

View file

@ -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])

81
src/reitit/spec.cljc Normal file
View file

@ -0,0 +1,81 @@
(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/spec (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 (s/or :empty #{""} :path ::path))
(s/def :reitit.router/routes ::routes)
(s/def :reitit.router/meta ::meta)
(s/def :reitit.router/expand
(s/fspec :args (s/cat :arg ::arg, :opts ::opts)
:ret ::route))
(s/def :reitit.router/coerce
(s/fspec :args (s/cat :route (s/spec ::route), :opts ::opts)
:ret ::route))
(s/def :reitit.router/compile
(s/fspec :args (s/cat :route (s/spec ::route), :opts ::opts)
:ret ::result))
(s/def :reitit.router/conflicts
(s/fspec :args (s/cat :conflicts (s/map-of ::route (s/coll-of ::route :into #{})))))
(s/def :reitit.router/router
(s/fspec :args (s/cat :routes ::routes, :opts ::opts)
:ret ::router))
;; TODO: fspecs fail..
(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)

View file

@ -0,0 +1,67 @@
(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 {}}
#_{:coerce (fn [_ _] ["/"])}
)
(are [opts]
(is (thrown-with-msg?
ExceptionInfo
#"Call to #'reitit.core/router did not conform to spec"
(reitit/router
["/api"] opts)))
{:meta 1}))))