Fix frontend routing tests, add controller ns

This commit is contained in:
Juho Teperi 2018-06-12 13:49:24 +03:00
parent 417f35a318
commit 3611a1bafe
5 changed files with 148 additions and 26 deletions

View file

@ -43,7 +43,7 @@
(coercion/coerce-request (:result match) {:query-params q
:path-params (:path-params match)})
{:query q
:path (:param match)})]
:path (:path-params match)})]
(assoc match :parameters parameters)))))
(defn match-by-name

View file

@ -0,0 +1,40 @@
(ns reitit.frontend.controllers)
(defn- pad-same-length [a b]
(concat a (take (- (count b) (count a)) (repeat nil))))
(defn get-params
"Get controller parameters given match. If controller provides :params
function that will be called with the match. Default is nil."
[controller match]
(if-let [f (:params controller)]
(f match)))
(defn apply-controller
"Run side-effects (:start or :stop) for controller.
The side-effect function is called with controller params."
[controller method]
(when-let [f (get controller method)]
(f (::params controller))))
(defn apply-controllers
"Applies changes between current controllers and
those previously enabled. Resets controllers whose
parameters have changed."
[old-controllers new-match]
(let [new-controllers (map (fn [controller]
(assoc controller ::params (get-params controller new-match)))
(:controllers (:data new-match)))
changed-controllers (->> (map (fn [old new]
;; different controllers, or params changed
(if (not= old new)
{:old old, :new new}))
(pad-same-length old-controllers new-controllers)
(pad-same-length new-controllers old-controllers))
(keep identity)
vec)]
(doseq [controller (map :old changed-controllers)]
(apply-controller controller :stop))
(doseq [controller (map :new changed-controllers)]
(apply-controller controller :start))
new-controllers))

View file

@ -6,7 +6,8 @@
reitit.middleware-test
reitit.ring-test
#_reitit.spec-test
reitit.frontend.core-test))
reitit.frontend.core-test
reitit.frontend.controllers-test))
(enable-console-print!)
@ -16,4 +17,5 @@
'reitit.middleware-test
'reitit.ring-test
#_'reitit.spec-test
'reitit.frontend.core-test)
'reitit.frontend.core-test
'reitit.frontend.controllers-test)

View file

@ -0,0 +1,68 @@
(ns reitit.frontend.controllers-test
(:require [clojure.test :refer [deftest testing is are]]
[reitit.frontend.controllers :as rfc]))
(deftest apply-controller-test
(is (= :ok (rfc/apply-controller {:stop (fn [_] :ok)} :stop)))
(is (= :ok (rfc/apply-controller {:start (fn [_] :ok)} :start))))
(deftest apply-controllers-test
(let [log (atom [])
controller-state (atom [])
controller-1 {:start (fn [_] (swap! log conj :start-1))
:stop (fn [_] (swap! log conj :stop-1))}
controller-2 {:start (fn [_] (swap! log conj :start-2))
:stop (fn [_] (swap! log conj :stop-2))}
controller-3 {:start (fn [{:keys [foo]}] (swap! log conj [:start-3 foo]))
:stop (fn [{:keys [foo]}] (swap! log conj [:stop-3 foo]))
:params (fn [match]
{:foo (-> match :parameters :path :foo)})}]
(testing "single controller started"
(swap! controller-state rfc/apply-controllers
{:data {:controllers [controller-1]}})
(is (= [:start-1] @log))
(is (= [(assoc controller-1 ::rfc/params nil)] @controller-state))
(reset! log []))
(testing "second controller started"
(swap! controller-state rfc/apply-controllers
{:data {:controllers [controller-1 controller-2]}})
(is (= [:start-2] @log))
(is (= [(assoc controller-1 ::rfc/params nil)
(assoc controller-2 ::rfc/params nil)]
@controller-state))
(reset! log []))
(testing "second controller replaced"
(swap! controller-state rfc/apply-controllers
{:data {:controllers [controller-1 controller-3]}
:parameters {:path {:foo 5}}})
(is (= [:stop-2 [:start-3 5]] @log))
(is (= [(assoc controller-1 ::rfc/params nil)
(assoc controller-3 ::rfc/params {:foo 5})]
@controller-state))
(reset! log []))
(testing "controller parameter changed"
(swap! controller-state rfc/apply-controllers
{:data {:controllers [controller-1 controller-3]}
:parameters {:path {:foo 1}}})
(is (= [[:stop-3 5] [:start-3 1]] @log))
(is (= [(assoc controller-1 ::rfc/params nil)
(assoc controller-3 ::rfc/params {:foo 1})]
@controller-state))
(reset! log []))
(testing "all controllers stopped"
(swap! controller-state rfc/apply-controllers
{:data {:controllers []}})
(is (= [:stop-1 [:stop-3 1]] @log))
(is (= [] @controller-state))
(reset! log []))
))

View file

@ -4,7 +4,7 @@
[reitit.frontend :as rf]
[reitit.coercion :as coercion]
[schema.core :as s]
[reitit.coercion.schema :as schema]))
[reitit.coercion.schema :as schema-coercion]))
(deftest match-by-path-test
(testing "simple"
@ -12,30 +12,42 @@
["" ::frontpage]
["foo" ::foo]
["bar" ::bar]])]
(is (= {:template "/"
:data {:name ::frontpage}
:path "/"}
(is (= (r/map->Match
{:template "/"
:data {:name ::frontpage}
:path-params {}
:path "/"
:parameters {:query {}
:path {}}})
(rf/match-by-path router "/")))
(is (= {:template "/foo"
:data {:name ::foo}
:path "/foo"}
(is (= (r/map->Match
{:template "/foo"
:data {:name ::foo}
:path-params {}
:path "/foo"
:parameters {:query {}
:path {}}})
(rf/match-by-path router "/foo")))))
(testing "schema coercion"
(let [router (r/router ["/"
[":id"
{:name ::foo
:parameters {:path {:id s/Int}
:query {(s/optional-key :mode) s/Keyword}}}]])]
#_#_
(is (= {:template "/5"
:data {:name ::foo}
:path "/5"
:parameters {:path {:id 5}}}
(rf/match-by-path router "/5")))
(is (= {:template "/5?mode=foo"
:data {:name ::foo}
:path "/5?mode=foo"
:parameters {:path {:id 5}
:query {:mode :foo}}}
(rf/match-by-path router "/5?mode=foo"))))))
[":id" {:name ::foo
:parameters {:path {:id s/Int}
:query {(s/optional-key :mode) s/Keyword}}}]]
{:compile coercion/compile-request-coercers
:data {:coercion schema-coercion/coercion}})]
(is (= (r/map->Match
{:template "/:id"
:path-params {:id "5"}
:path "/5"
:parameters {:query {}
:path {:id 5}}})
(assoc (rf/match-by-path router "/5") :data nil :result nil)))
(is (= (r/map->Match
{:template "/:id"
:path-params {:id "5"}
;; Note: query not included in path
:path "/5"
:parameters {:path {:id 5}
:query {:mode :foo}}})
(assoc (rf/match-by-path router "/5?mode=foo") :data nil :result nil))))))