mirror of
https://github.com/metosin/reitit.git
synced 2025-12-21 18:11:12 +00:00
Merge pull request #188 from metosin/frontend-docs-2
Replace :params with :identity/:parameters
This commit is contained in:
commit
3a8f0cf52d
8 changed files with 166 additions and 67 deletions
15
CHANGELOG.md
15
CHANGELOG.md
|
|
@ -1,3 +1,12 @@
|
||||||
|
## Unreleased
|
||||||
|
|
||||||
|
* Frontend controllers:
|
||||||
|
* Controller `:params` function has been deprecated
|
||||||
|
* Controller `:identity` function works the same as `:params`
|
||||||
|
* New `:parameters` option can be used to declare which parameters
|
||||||
|
controller is interested in, as data, which should cover most
|
||||||
|
use cases: `{:start start-fn, :parameters {:path [:foo-id]}}`
|
||||||
|
|
||||||
## 0.2.13 (2019-01-26)
|
## 0.2.13 (2019-01-26)
|
||||||
|
|
||||||
* Don't throw `StringIndexOutOfBoundsException` with empty path lookup on wildcard paths, fixes [#209](https://github.com/metosin/reitit/issues/209)
|
* Don't throw `StringIndexOutOfBoundsException` with empty path lookup on wildcard paths, fixes [#209](https://github.com/metosin/reitit/issues/209)
|
||||||
|
|
@ -25,7 +34,7 @@
|
||||||
|
|
||||||
* new options `:inject-match?` and `:inject-router?` on `reitit.http/ring-handler` and `reitit.http/routing-interceptor` to optionally not to inject `Router` and `Match` into the request. See [performance guide](https://metosin.github.io/reitit/performance.html#faster!) for details.
|
* new options `:inject-match?` and `:inject-router?` on `reitit.http/ring-handler` and `reitit.http/routing-interceptor` to optionally not to inject `Router` and `Match` into the request. See [performance guide](https://metosin.github.io/reitit/performance.html#faster!) for details.
|
||||||
|
|
||||||
### dependencies
|
### dependencies
|
||||||
|
|
||||||
* updated:
|
* updated:
|
||||||
|
|
||||||
|
|
@ -250,7 +259,7 @@
|
||||||
* Swagger enchancements
|
* Swagger enchancements
|
||||||
* Better spec coercion via `st/coerce` using spec walking & inference: many simple specs (core predicates, `spec-tools.core/spec`, `s/and`, `s/or`, `s/coll-of`, `s/keys`, `s/map-of`, `s/nillable` and `s/every`) can be transformed without needing spec to be wrapped. Fallbacks to old conformed based approach.
|
* Better spec coercion via `st/coerce` using spec walking & inference: many simple specs (core predicates, `spec-tools.core/spec`, `s/and`, `s/or`, `s/coll-of`, `s/keys`, `s/map-of`, `s/nillable` and `s/every`) can be transformed without needing spec to be wrapped. Fallbacks to old conformed based approach.
|
||||||
* [example app](https://github.com/metosin/reitit/blob/master/examples/ring-spec-swagger/src/example/server.clj).
|
* [example app](https://github.com/metosin/reitit/blob/master/examples/ring-spec-swagger/src/example/server.clj).
|
||||||
|
|
||||||
* updated deps:
|
* updated deps:
|
||||||
|
|
||||||
```clj
|
```clj
|
||||||
|
|
@ -396,7 +405,7 @@ Sample apps demonstraing the current status of `reitit`:
|
||||||
* when Keywords are used in place of middleware / interceptor, a lookup is done into Router option `::middleware/registry` (or `::interceptor/registry`) with the key. Fails fast with missing registry entries.
|
* when Keywords are used in place of middleware / interceptor, a lookup is done into Router option `::middleware/registry` (or `::interceptor/registry`) with the key. Fails fast with missing registry entries.
|
||||||
* fixes [#32](https://github.com/metosin/reitit/issues/32).
|
* fixes [#32](https://github.com/metosin/reitit/issues/32).
|
||||||
* full documentation [here](https://metosin.github.io/reitit/ring/middleware_registry.html).
|
* full documentation [here](https://metosin.github.io/reitit/ring/middleware_registry.html).
|
||||||
|
|
||||||
```clj
|
```clj
|
||||||
(require '[reitit.ring :as ring])
|
(require '[reitit.ring :as ring])
|
||||||
(require '[reitit.middleware :as middleware])
|
(require '[reitit.middleware :as middleware])
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,30 @@
|
||||||
# Frontend basics
|
# Frontend basics
|
||||||
|
|
||||||
* https://github.com/metosin/reitit/tree/master/examples/frontend
|
Reitit frontend integration is built from multiple layers:
|
||||||
|
|
||||||
|
- Core functions with some additional browser oriented features
|
||||||
|
- [Browser integration](./browser.md) for attaching Reitit to hash-change or HTML
|
||||||
|
history events
|
||||||
|
- Stateful wrapper for easy use of history integration
|
||||||
|
- Optional [controller extension](./controllers.md)
|
||||||
|
|
||||||
|
## Core functions
|
||||||
|
|
||||||
`reitit.frontend` provides few useful functions wrapping core functions:
|
`reitit.frontend` provides few useful functions wrapping core functions:
|
||||||
|
|
||||||
- `match-by-path` version which parses a URI using JavaScript, including
|
`match-by-path` version which parses a URI using JavaScript, including
|
||||||
query-string, and also coerces the parameters.
|
query-string, and also [coerces the parameters](../coercion/coercion.md).
|
||||||
- `router` which compiles coercers by default
|
Coerced parameters are stored in match `:parameters` property. If coercion
|
||||||
- `match-by-name` and `match-by-name!` with optional `path-paramers` and
|
is not enabled, the original parameters are stored in the same property,
|
||||||
logging errors to `console.warn` instead of throwing errors (to prevent
|
to allow the same code to read parameters regardless if coercion is
|
||||||
React breaking due to errors).
|
enabled.
|
||||||
|
|
||||||
|
`router` which compiles coercers by default.
|
||||||
|
|
||||||
|
`match-by-name` and `match-by-name!` with optional `path-paramers` and
|
||||||
|
logging errors to `console.warn` instead of throwing errors to prevent
|
||||||
|
React breaking due to errors.
|
||||||
|
|
||||||
|
## Next
|
||||||
|
|
||||||
|
[Browser integration](./browser.md)
|
||||||
|
|
|
||||||
|
|
@ -21,5 +21,7 @@ Check examples for simple Ring handler example.
|
||||||
## Easy
|
## Easy
|
||||||
|
|
||||||
Reitit frontend routers require storing the state somewhere and passing it to
|
Reitit frontend routers require storing the state somewhere and passing it to
|
||||||
all the calls. Wrapper (`reitit.frontend.easy`) is provided which manages
|
all the calls. Wrapper `reitit.frontend.easy` is provided which manages
|
||||||
router instance and passes the instance to all calls.
|
a router instance and passes the instance to all calls. This should
|
||||||
|
allow easy use in most applications, as browser anyway can only have single
|
||||||
|
event handler for page change events.
|
||||||
|
|
|
||||||
|
|
@ -9,32 +9,34 @@ Controllers run code when a route is entered and left. This can be useful to:
|
||||||
|
|
||||||
## How controllers work
|
## How controllers work
|
||||||
|
|
||||||
A controller consists of three functions:
|
A controller map can contain these properties:
|
||||||
|
|
||||||
* `params` which takes a Match and returns an arbitrary value.
|
* `identity` function which takes a Match and returns an arbitrary value,
|
||||||
* `start` which takes the result of params and whose return value is discarded.
|
* or `parameters` value, which declares which parameters should affect
|
||||||
* `stop` which takes the result of params and whose return value is discarded.
|
controller identity
|
||||||
|
* `start` & `stop` functions, which are called with controller identity
|
||||||
|
|
||||||
When you navigate to a route that has a controller, `params` gets called first
|
When you navigate to a route that has a controller, controller identity
|
||||||
and then `start` is called with its return value. When you exit that route,
|
is first resolved by calling `identity` function, or by using `parameters`
|
||||||
`stop` is called with the return value of `params.`
|
declaration, or if neither is set, the identity is `nil`. Next controller
|
||||||
|
is initialized by calling `start` is called with the identity value.
|
||||||
|
When you exit that route, `stop` is called with the return value of `params.`
|
||||||
|
|
||||||
If you navigate to the same route with different parameters, `params` gets
|
If you navigate to the same route with different match, identity gets
|
||||||
called again. If the return value changes from the previous return value, `stop`
|
resolved again. If the identity changes from the previous value, controller
|
||||||
and `start` get called again.
|
is reinitialized: `stop` and `start` get called again.
|
||||||
|
|
||||||
You can add controllers to a route by adding them to the route data in the
|
You can add controllers to a route by adding them to the route data in the
|
||||||
`:controllers` vector. For example:
|
`:controllers` vector. For example:
|
||||||
|
|
||||||
```clojure
|
```cljs
|
||||||
["/item/:id"
|
["/item/:id"
|
||||||
{:controllers [{:params (fn [match] (get-in match [:path-params :id]))
|
{:controllers [{:parameters {:path [:id]}
|
||||||
:start (fn [item-id] (js/console.log :start item-id))
|
:start (fn [parameters] (js/console.log :start (-> parameters :path :id)))
|
||||||
:stop (fn [item-id] (js/console.log :stop item-id))}]}]
|
:stop (fn [parameters] (js/console.log :stop (-> parameters :path :id)))}]}]
|
||||||
```
|
```
|
||||||
|
|
||||||
If you leave out `params`, `start` and `stop` get called with `nil`. You can
|
You can leave out `start` or `stop` if you do not need both of them.
|
||||||
leave out `start` or `stop` if you do not need both of them.
|
|
||||||
|
|
||||||
## Enabling controllers
|
## Enabling controllers
|
||||||
|
|
||||||
|
|
@ -44,8 +46,7 @@ call
|
||||||
the URL changes. You can call it from the `on-navigate` callback of
|
the URL changes. You can call it from the `on-navigate` callback of
|
||||||
`reitit.frontend.easy`:
|
`reitit.frontend.easy`:
|
||||||
|
|
||||||
```clojure
|
```cljs
|
||||||
|
|
||||||
(ns frontend.core
|
(ns frontend.core
|
||||||
(:require [reitit.frontend.easy :as rfe]
|
(:require [reitit.frontend.easy :as rfe]
|
||||||
[reitit.frontend.controllers :as rfc]))
|
[reitit.frontend.controllers :as rfc]))
|
||||||
|
|
@ -70,10 +71,10 @@ See also [the full example](https://github.com/metosin/reitit/tree/master/exampl
|
||||||
|
|
||||||
## Nested controllers
|
## Nested controllers
|
||||||
|
|
||||||
When you nest routes in the route tree, the controllers get nested as well.
|
When you nest routes in the route tree, the controllers get concatenated when
|
||||||
Consider this route tree:
|
route data is merged. Consider this route tree:
|
||||||
|
|
||||||
```clojure
|
```cljs
|
||||||
["/" {:controllers [{:start (fn [_] (js/console.log "root start"))}]}
|
["/" {:controllers [{:start (fn [_] (js/console.log "root start"))}]}
|
||||||
["/item/:id"
|
["/item/:id"
|
||||||
{:controllers [{:params (fn [match] (get-in match [:path-params :id]))
|
{:controllers [{:params (fn [match] (get-in match [:path-params :id]))
|
||||||
|
|
@ -90,20 +91,22 @@ Consider this route tree:
|
||||||
started with the parameter `something-else`. The root controller stays on the
|
started with the parameter `something-else`. The root controller stays on the
|
||||||
whole time since its parameters do not change.
|
whole time since its parameters do not change.
|
||||||
|
|
||||||
## Authentication
|
## Tips
|
||||||
|
|
||||||
|
### Authentication
|
||||||
|
|
||||||
Controllers can be used to load resources from a server. If and when your
|
Controllers can be used to load resources from a server. If and when your
|
||||||
API requires authentication you will need to implement logic to prevent controllers
|
API requires authentication you will need to implement logic to prevent controllers
|
||||||
trying to do requests if user isn't authenticated yet.
|
trying to do requests if user isn't authenticated yet.
|
||||||
|
|
||||||
### Run controllers and check authentication
|
#### Run controllers and check authentication
|
||||||
|
|
||||||
If you have both unauthenticated and authenticated resources, you can
|
If you have both unauthenticated and authenticated resources, you can
|
||||||
run the controllers always and then check the authentication status
|
run the controllers always and then check the authentication status
|
||||||
on controller code, or on the code called from controllers (e.g. re-frame event
|
on controller code, or on the code called from controllers (e.g. re-frame event
|
||||||
handler).
|
handler).
|
||||||
|
|
||||||
### Disable controllers until user is authenticated
|
#### Disable controllers until user is authenticated
|
||||||
|
|
||||||
If all your resources require authentication an easy way to prevent bad
|
If all your resources require authentication an easy way to prevent bad
|
||||||
requests is to enable controllers only after authentication is done.
|
requests is to enable controllers only after authentication is done.
|
||||||
|
|
@ -119,7 +122,6 @@ Similar solution could be used to describe required resources as data (maybe
|
||||||
even GraphQL query) per route, and then have code automatically load
|
even GraphQL query) per route, and then have code automatically load
|
||||||
missing resources.
|
missing resources.
|
||||||
|
|
||||||
|
|
||||||
## Controllers elsewhere
|
## Controllers elsewhere
|
||||||
|
|
||||||
* [Controllers in Keechma](https://keechma.com/guides/controllers/)
|
* [Controllers in Keechma](https://keechma.com/guides/controllers/)
|
||||||
|
|
|
||||||
|
|
@ -65,12 +65,11 @@
|
||||||
{:name ::item
|
{:name ::item
|
||||||
:parameters {:path {:id s/Int}
|
:parameters {:path {:id s/Int}
|
||||||
:query {(s/optional-key :foo) s/Keyword}}
|
:query {(s/optional-key :foo) s/Keyword}}
|
||||||
:controllers [{:params (fn [match]
|
:controllers [{:parameters {:path [:id]}
|
||||||
(:path (:parameters match)))
|
:start (fn [{:keys [path]}]
|
||||||
:start (fn [params]
|
(js/console.log "start" "item controller" (:id path)))
|
||||||
(js/console.log "start" "item controller" (:id params)))
|
:stop (fn [{:keys [path]}]
|
||||||
:stop (fn [params]
|
(js/console.log "stop" "item controller" (:id path)))}]}]]]
|
||||||
(js/console.log "stop" "item controller" (:id params)))}]}]]]
|
|
||||||
{:data {:controllers [{:start (log-fn "start" "root-controller")
|
{:data {:controllers [{:start (log-fn "start" "root-controller")
|
||||||
:stop (log-fn "stop" "root controller")}]
|
:stop (log-fn "stop" "root controller")}]
|
||||||
:coercion rsc/coercion}}))
|
:coercion rsc/coercion}}))
|
||||||
|
|
|
||||||
|
|
@ -1,29 +1,56 @@
|
||||||
(ns reitit.frontend.controllers)
|
(ns reitit.frontend.controllers
|
||||||
|
"Provides apply-controllers function")
|
||||||
|
|
||||||
(defn- pad-same-length [a b]
|
(defn- pad-same-length [a b]
|
||||||
(concat a (take (- (count b) (count a)) (repeat nil))))
|
(concat a (take (- (count b) (count a)) (repeat nil))))
|
||||||
|
|
||||||
(defn get-params
|
(def ^:private params-warning
|
||||||
"Get controller parameters given match. If controller provides :params
|
(delay (js/console.warn "Reitit-frontend controller :params is deprecated. Replace with :identity or :parameters option.")))
|
||||||
function that will be called with the match. Default is nil."
|
|
||||||
[controller match]
|
(defn get-identity
|
||||||
(if-let [f (:params controller)]
|
"Get controller identity given controller and match.
|
||||||
(f match)))
|
|
||||||
|
To select interesting properties from Match :parameters option can be set.
|
||||||
|
Value should be param-type => [param-key]
|
||||||
|
Resulting value is map of param-type => param-key => value.
|
||||||
|
|
||||||
|
For other uses, :identity option can be used to provide function from
|
||||||
|
Match to identity.
|
||||||
|
|
||||||
|
Default value is nil, i.e. controller identity doesn't depend on Match."
|
||||||
|
[{:keys [identity parameters params]} match]
|
||||||
|
(assert (not (and identity parameters))
|
||||||
|
"Use either :identity or :parameters for controller, not both.")
|
||||||
|
(when params
|
||||||
|
@params-warning)
|
||||||
|
(cond
|
||||||
|
parameters
|
||||||
|
(into {} (for [[param-type ks] parameters]
|
||||||
|
[param-type (select-keys (get (:parameters match) param-type) ks)]))
|
||||||
|
|
||||||
|
identity
|
||||||
|
(identity match)
|
||||||
|
|
||||||
|
;; Support deprecated :params for transition period. Can be removed later.
|
||||||
|
params
|
||||||
|
(params match)
|
||||||
|
|
||||||
|
:else nil))
|
||||||
|
|
||||||
(defn apply-controller
|
(defn apply-controller
|
||||||
"Run side-effects (:start or :stop) for controller.
|
"Run side-effects (:start or :stop) for controller.
|
||||||
The side-effect function is called with controller params."
|
The side-effect function is called with controller identity value."
|
||||||
[controller method]
|
[controller method]
|
||||||
(when-let [f (get controller method)]
|
(when-let [f (get controller method)]
|
||||||
(f (::params controller))))
|
(f (::identity controller))))
|
||||||
|
|
||||||
(defn apply-controllers
|
(defn apply-controllers
|
||||||
"Applies changes between current controllers and
|
"Applies changes between current controllers and
|
||||||
those previously enabled. Resets controllers whose
|
those previously enabled. Reinitializes controllers whose
|
||||||
parameters have changed."
|
identity has changed."
|
||||||
[old-controllers new-match]
|
[old-controllers new-match]
|
||||||
(let [new-controllers (mapv (fn [controller]
|
(let [new-controllers (mapv (fn [controller]
|
||||||
(assoc controller ::params (get-params controller new-match)))
|
(assoc controller ::identity (get-identity controller new-match)))
|
||||||
(:controllers (:data new-match)))
|
(:controllers (:data new-match)))
|
||||||
changed-controllers (->> (map (fn [old new]
|
changed-controllers (->> (map (fn [old new]
|
||||||
;; different controllers, or params changed
|
;; different controllers, or params changed
|
||||||
|
|
@ -33,7 +60,7 @@
|
||||||
(pad-same-length new-controllers old-controllers))
|
(pad-same-length new-controllers old-controllers))
|
||||||
(keep identity)
|
(keep identity)
|
||||||
vec)]
|
vec)]
|
||||||
(doseq [controller (map :old changed-controllers)]
|
(doseq [controller (reverse (map :old changed-controllers))]
|
||||||
(apply-controller controller :stop))
|
(apply-controller controller :stop))
|
||||||
(doseq [controller (map :new changed-controllers)]
|
(doseq [controller (map :new changed-controllers)]
|
||||||
(apply-controller controller :start))
|
(apply-controller controller :start))
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
(ns reitit.frontend.history
|
(ns reitit.frontend.history
|
||||||
|
"Provides integration to hash-change or HTML5 History
|
||||||
|
events."
|
||||||
(:require [reitit.core :as reitit]
|
(:require [reitit.core :as reitit]
|
||||||
[reitit.core :as r]
|
[reitit.core :as r]
|
||||||
[reitit.frontend :as rf]
|
[reitit.frontend :as rf]
|
||||||
|
|
|
||||||
|
|
@ -15,15 +15,15 @@
|
||||||
:stop (fn [_] (swap! log conj :stop-2))}
|
:stop (fn [_] (swap! log conj :stop-2))}
|
||||||
controller-3 {:start (fn [{:keys [foo]}] (swap! log conj [:start-3 foo]))
|
controller-3 {:start (fn [{:keys [foo]}] (swap! log conj [:start-3 foo]))
|
||||||
:stop (fn [{:keys [foo]}] (swap! log conj [:stop-3 foo]))
|
:stop (fn [{:keys [foo]}] (swap! log conj [:stop-3 foo]))
|
||||||
:params (fn [match]
|
:identity (fn [match]
|
||||||
{:foo (-> match :parameters :path :foo)})}]
|
{:foo (-> match :parameters :path :foo)})}]
|
||||||
|
|
||||||
(testing "single controller started"
|
(testing "single controller started"
|
||||||
(swap! controller-state rfc/apply-controllers
|
(swap! controller-state rfc/apply-controllers
|
||||||
{:data {:controllers [controller-1]}})
|
{:data {:controllers [controller-1]}})
|
||||||
|
|
||||||
(is (= [:start-1] @log))
|
(is (= [:start-1] @log))
|
||||||
(is (= [(assoc controller-1 ::rfc/params nil)] @controller-state))
|
(is (= [(assoc controller-1 ::rfc/identity nil)] @controller-state))
|
||||||
(reset! log []))
|
(reset! log []))
|
||||||
|
|
||||||
(testing "second controller started"
|
(testing "second controller started"
|
||||||
|
|
@ -31,8 +31,8 @@
|
||||||
{:data {:controllers [controller-1 controller-2]}})
|
{:data {:controllers [controller-1 controller-2]}})
|
||||||
|
|
||||||
(is (= [:start-2] @log))
|
(is (= [:start-2] @log))
|
||||||
(is (= [(assoc controller-1 ::rfc/params nil)
|
(is (= [(assoc controller-1 ::rfc/identity nil)
|
||||||
(assoc controller-2 ::rfc/params nil)]
|
(assoc controller-2 ::rfc/identity nil)]
|
||||||
@controller-state))
|
@controller-state))
|
||||||
(reset! log []))
|
(reset! log []))
|
||||||
|
|
||||||
|
|
@ -42,8 +42,8 @@
|
||||||
:parameters {:path {:foo 5}}})
|
:parameters {:path {:foo 5}}})
|
||||||
|
|
||||||
(is (= [:stop-2 [:start-3 5]] @log))
|
(is (= [:stop-2 [:start-3 5]] @log))
|
||||||
(is (= [(assoc controller-1 ::rfc/params nil)
|
(is (= [(assoc controller-1 ::rfc/identity nil)
|
||||||
(assoc controller-3 ::rfc/params {:foo 5})]
|
(assoc controller-3 ::rfc/identity {:foo 5})]
|
||||||
@controller-state))
|
@controller-state))
|
||||||
(reset! log []))
|
(reset! log []))
|
||||||
|
|
||||||
|
|
@ -53,8 +53,8 @@
|
||||||
:parameters {:path {:foo 1}}})
|
:parameters {:path {:foo 1}}})
|
||||||
|
|
||||||
(is (= [[:stop-3 5] [:start-3 1]] @log))
|
(is (= [[:stop-3 5] [:start-3 1]] @log))
|
||||||
(is (= [(assoc controller-1 ::rfc/params nil)
|
(is (= [(assoc controller-1 ::rfc/identity nil)
|
||||||
(assoc controller-3 ::rfc/params {:foo 1})]
|
(assoc controller-3 ::rfc/identity {:foo 1})]
|
||||||
@controller-state))
|
@controller-state))
|
||||||
(reset! log []))
|
(reset! log []))
|
||||||
|
|
||||||
|
|
@ -62,7 +62,47 @@
|
||||||
(swap! controller-state rfc/apply-controllers
|
(swap! controller-state rfc/apply-controllers
|
||||||
{:data {:controllers []}})
|
{:data {:controllers []}})
|
||||||
|
|
||||||
(is (= [:stop-1 [:stop-3 1]] @log))
|
(is (= [[:stop-3 1] :stop-1] @log))
|
||||||
(is (= [] @controller-state))
|
(is (= [] @controller-state))
|
||||||
|
(reset! log []))))
|
||||||
|
|
||||||
|
(deftest controller-data-parameters
|
||||||
|
(let [log (atom [])
|
||||||
|
controller-state (atom [])
|
||||||
|
static {:start (fn [params] (swap! log conj [:start-static]))
|
||||||
|
:stop (fn [params] (swap! log conj [:stop-static]))}
|
||||||
|
controller {:start (fn [params] (swap! log conj [:start params]))
|
||||||
|
:stop (fn [params] (swap! log conj [:stop params]))
|
||||||
|
:parameters {:path [:foo]}}]
|
||||||
|
|
||||||
|
(testing "init"
|
||||||
|
(swap! controller-state rfc/apply-controllers
|
||||||
|
{:data {:controllers [static controller]}
|
||||||
|
:parameters {:path {:foo 1}}})
|
||||||
|
|
||||||
|
(is (= [[:start-static]
|
||||||
|
[:start {:path {:foo 1}}]] @log))
|
||||||
|
(is (= [(assoc static ::rfc/identity nil)
|
||||||
|
(assoc controller ::rfc/identity {:path {:foo 1}})]
|
||||||
|
@controller-state))
|
||||||
(reset! log []))
|
(reset! log []))
|
||||||
))
|
|
||||||
|
(testing "params change"
|
||||||
|
(swap! controller-state rfc/apply-controllers
|
||||||
|
{:data {:controllers [static controller]}
|
||||||
|
:parameters {:path {:foo 5}}})
|
||||||
|
|
||||||
|
(is (= [[:stop {:path {:foo 1}}]
|
||||||
|
[:start {:path {:foo 5}}]] @log))
|
||||||
|
(is (= [(assoc static ::rfc/identity nil)
|
||||||
|
(assoc controller ::rfc/identity {:path {:foo 5}})]
|
||||||
|
@controller-state))
|
||||||
|
(reset! log []))
|
||||||
|
|
||||||
|
(testing "stop"
|
||||||
|
(swap! controller-state rfc/apply-controllers
|
||||||
|
{:data {:controllers []}})
|
||||||
|
|
||||||
|
(is (= [[:stop {:path {:foo 5}}]
|
||||||
|
[:stop-static]] @log))
|
||||||
|
(reset! log []))))
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue