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 (coercion/coerce-request (:result match) {:query-params q
:path-params (:path-params match)}) :path-params (:path-params match)})
{:query q {:query q
:path (:param match)})] :path (:path-params match)})]
(assoc match :parameters parameters))))) (assoc match :parameters parameters)))))
(defn match-by-name (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.middleware-test
reitit.ring-test reitit.ring-test
#_reitit.spec-test #_reitit.spec-test
reitit.frontend.core-test)) reitit.frontend.core-test
reitit.frontend.controllers-test))
(enable-console-print!) (enable-console-print!)
@ -16,4 +17,5 @@
'reitit.middleware-test 'reitit.middleware-test
'reitit.ring-test 'reitit.ring-test
#_'reitit.spec-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.frontend :as rf]
[reitit.coercion :as coercion] [reitit.coercion :as coercion]
[schema.core :as s] [schema.core :as s]
[reitit.coercion.schema :as schema])) [reitit.coercion.schema :as schema-coercion]))
(deftest match-by-path-test (deftest match-by-path-test
(testing "simple" (testing "simple"
@ -12,30 +12,42 @@
["" ::frontpage] ["" ::frontpage]
["foo" ::foo] ["foo" ::foo]
["bar" ::bar]])] ["bar" ::bar]])]
(is (= {:template "/" (is (= (r/map->Match
:data {:name ::frontpage} {:template "/"
:path "/"} :data {:name ::frontpage}
:path-params {}
:path "/"
:parameters {:query {}
:path {}}})
(rf/match-by-path router "/"))) (rf/match-by-path router "/")))
(is (= {:template "/foo" (is (= (r/map->Match
:data {:name ::foo} {:template "/foo"
:path "/foo"} :data {:name ::foo}
:path-params {}
:path "/foo"
:parameters {:query {}
:path {}}})
(rf/match-by-path router "/foo"))))) (rf/match-by-path router "/foo")))))
(testing "schema coercion" (testing "schema coercion"
(let [router (r/router ["/" (let [router (r/router ["/"
[":id" [":id" {:name ::foo
{:name ::foo :parameters {:path {:id s/Int}
:parameters {:path {:id s/Int} :query {(s/optional-key :mode) s/Keyword}}}]]
:query {(s/optional-key :mode) s/Keyword}}}]])] {:compile coercion/compile-request-coercers
#_#_ :data {:coercion schema-coercion/coercion}})]
(is (= {:template "/5" (is (= (r/map->Match
:data {:name ::foo} {:template "/:id"
:path "/5" :path-params {:id "5"}
:parameters {:path {:id 5}}} :path "/5"
(rf/match-by-path router "/5"))) :parameters {:query {}
(is (= {:template "/5?mode=foo" :path {:id 5}}})
:data {:name ::foo} (assoc (rf/match-by-path router "/5") :data nil :result nil)))
:path "/5?mode=foo" (is (= (r/map->Match
:parameters {:path {:id 5} {:template "/:id"
:query {:mode :foo}}} :path-params {:id "5"}
(rf/match-by-path router "/5?mode=foo")))))) ;; 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))))))