mirror of
https://github.com/metosin/reitit.git
synced 2025-12-17 00:11:11 +00:00
Merge branch 'master' into fix/malli-swagger-defs
This commit is contained in:
commit
f237b0942e
26 changed files with 318 additions and 61 deletions
|
|
@ -18,7 +18,9 @@ We use [Break Versioning][breakver]. The version numbers follow a `<major>.<mino
|
|||
* Updated dependencies:
|
||||
|
||||
```clojure
|
||||
[metosin/malli "0.10.4"] is available but we use "0.10.1"
|
||||
[metosin/ring-swagger-ui "4.18.1"] is available but we use "4.15.5"
|
||||
[metosin/malli "0.11.0"] is available but we use "0.10.1"
|
||||
[ring/ring-core "1.10.0"] is available but we use "1.9.6"
|
||||
```
|
||||
|
||||
## 0.6.0 (2023-02-21)
|
||||
|
|
|
|||
|
|
@ -2,8 +2,16 @@
|
|||
|
||||
Reitit includes two browser history integrations.
|
||||
|
||||
Functions follow HTML5 History API: `push-state` to change route, `replace-state`
|
||||
to change route without leaving previous entry in browser history.
|
||||
Main functions are `navigate` and `set-query`. Navigate is used to navigate
|
||||
to named routes, and the options parameter can be used to control all
|
||||
parameters and if `pushState` or `replaceState` should be used to control
|
||||
browser history stack. The `set-query` function can be used to change
|
||||
or modify query parameters for the current route, it takes either map of
|
||||
new query params or function from old params to the new params.
|
||||
|
||||
There are also secondary functions following HTML5 History API:
|
||||
`push-state` to navigate to new route adding entry to the history and
|
||||
`replace-state` to change route without leaving previous entry in browser history.
|
||||
|
||||
## Fragment router
|
||||
|
||||
|
|
|
|||
|
|
@ -19,10 +19,17 @@
|
|||
[:ul
|
||||
[:li [:a {:href (rfe/href ::item {:id 1})} "Item 1"]]
|
||||
[:li [:a {:href (rfe/href ::item {:id 2} {:foo "bar"})} "Item 2"]]]
|
||||
(if id
|
||||
(when id
|
||||
[:h2 "Selected item " id])
|
||||
(if (:foo query)
|
||||
[:p "Optional foo query param: " (:foo query)])]))
|
||||
[:p "Query params: " [:pre (pr-str query)]]
|
||||
[:ul
|
||||
[:li [:a {:on-click #(rfe/set-query {:a 1})} "set a=1"]]
|
||||
[:li [:a {:on-click #(rfe/set-query {:a 2} {:replace true})} "set a=2 and replaceState"]]
|
||||
[:li [:a {:on-click (fn [_] (rfe/set-query #(assoc % :foo "zzz")))} "add foo=zzz"]]]
|
||||
[:button
|
||||
{:on-click #(rfe/navigate ::item {:path-params {:id 3}
|
||||
:query-params {:foo "aaa"}})}
|
||||
"Navigate example, go to item 3"]]))
|
||||
|
||||
(defonce match (r/atom nil))
|
||||
|
||||
|
|
@ -31,9 +38,8 @@
|
|||
[:ul
|
||||
[:li [:a {:href (rfe/href ::frontpage)} "Frontpage"]]
|
||||
[:li
|
||||
[:a {:href (rfe/href ::item-list)} "Item list"]
|
||||
]]
|
||||
(if @match
|
||||
[:a {:href (rfe/href ::item-list)} "Item list"]]]
|
||||
(when @match
|
||||
(let [view (:view (:data @match))]
|
||||
[view @match]))
|
||||
[:pre (with-out-str (fedn/pprint @match))]])
|
||||
|
|
@ -63,7 +69,8 @@
|
|||
["/:id"
|
||||
{:name ::item
|
||||
:parameters {:path {:id s/Int}
|
||||
:query {(s/optional-key :foo) s/Keyword}}
|
||||
:query {(s/optional-key :a) s/Int
|
||||
(s/optional-key :foo) s/Keyword}}
|
||||
:controllers [{:parameters {:path [:id]}
|
||||
:start (fn [{:keys [path]}]
|
||||
(js/console.log "start" "item controller" (:id path)))
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
:scm {:name "git"
|
||||
:url "https://github.com/metosin/reitit"
|
||||
:dir "../.."}
|
||||
:plugins [[lein-parent "0.3.2"]]
|
||||
:plugins [[lein-parent "0.3.9"]]
|
||||
:parent-project {:path "../../project.clj"
|
||||
:inherit [:deploy-repositories :managed-dependencies]}
|
||||
:java-source-paths ["java-src"]
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
:url "http://www.eclipse.org/legal/epl-v10.html"}
|
||||
:scm {:name "git"
|
||||
:url "https://github.com/metosin/reitit"}
|
||||
:plugins [[lein-parent "0.3.2"]]
|
||||
:plugins [[lein-parent "0.3.9"]]
|
||||
:parent-project {:path "../../project.clj"
|
||||
:inherit [:deploy-repositories :managed-dependencies]}
|
||||
:dependencies [[metosin/reitit-core]
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
:scm {:name "git"
|
||||
:url "https://github.com/metosin/reitit"
|
||||
:dir "../.."}
|
||||
:plugins [[lein-parent "0.3.2"]]
|
||||
:plugins [[lein-parent "0.3.9"]]
|
||||
:parent-project {:path "../../project.clj"
|
||||
:inherit [:deploy-repositories :managed-dependencies]}
|
||||
:dependencies [[metosin/reitit-core]])
|
||||
|
|
|
|||
|
|
@ -1,25 +1,41 @@
|
|||
(ns reitit.frontend
|
||||
(:require [clojure.set :as set]
|
||||
[reitit.coercion :as coercion]
|
||||
[reitit.core :as r])
|
||||
(:import goog.Uri
|
||||
goog.Uri.QueryData))
|
||||
[reitit.core :as r]
|
||||
goog.Uri
|
||||
goog.Uri.QueryData))
|
||||
|
||||
(defn- query-param [^QueryData q k]
|
||||
(defn- query-param [^goog.uri.QueryData q k]
|
||||
(let [vs (.getValues q k)]
|
||||
(if (< (alength vs) 2)
|
||||
(aget vs 0)
|
||||
(vec vs))))
|
||||
|
||||
(defn query-params
|
||||
"Given goog.Uri, read query parameters into Clojure map."
|
||||
[^Uri uri]
|
||||
"Given goog.Uri, read query parameters into a Clojure map."
|
||||
[^goog.Uri uri]
|
||||
(let [q (.getQueryData uri)]
|
||||
(->> q
|
||||
(.getKeys)
|
||||
(map (juxt keyword #(query-param q %)))
|
||||
(into {}))))
|
||||
|
||||
(defn set-query-params
|
||||
"Given Reitit-frontend path, update the query params
|
||||
with given function and arguments.
|
||||
|
||||
Note: coercion is not applied to the query params"
|
||||
[path new-query-or-update-fn]
|
||||
(let [^goog.Uri uri (goog.Uri/parse path)
|
||||
new-query (if (fn? new-query-or-update-fn)
|
||||
(new-query-or-update-fn (query-params uri))
|
||||
new-query-or-update-fn)]
|
||||
;; NOTE: Differences to reitit.impl/query-string?
|
||||
;; reitit fn adds "=" even if value is empty string
|
||||
;; reitit encodes " " as "+" while browser and goog.Uri encode as "%20"
|
||||
(.setQueryData uri (goog.Uri.QueryData/createFromMap (clj->js new-query)))
|
||||
(.toString uri)))
|
||||
|
||||
(defn match-by-path
|
||||
"Given routing tree and current path, return match with possibly
|
||||
coerced parameters. Return nil if no match found.
|
||||
|
|
@ -27,7 +43,7 @@
|
|||
:on-coercion-error - a sideeffecting fn of `match exception -> nil`"
|
||||
([router path] (match-by-path router path nil))
|
||||
([router path {:keys [on-coercion-error]}]
|
||||
(let [uri (.parse Uri path)
|
||||
(let [uri (.parse goog.Uri path)
|
||||
coerce! (if on-coercion-error
|
||||
(fn [match]
|
||||
(try (coercion/coerce! match)
|
||||
|
|
|
|||
|
|
@ -101,3 +101,44 @@
|
|||
(rfh/replace-state @history name path-params nil))
|
||||
([name path-params query-params]
|
||||
(rfh/replace-state @history name path-params query-params)))
|
||||
|
||||
;; This duplicates previous two, but the map parameter will be easier way to
|
||||
;; extend the functions, e.g. to work with fragment string. Toggling push vs
|
||||
;; replace can be also simpler with a flag.
|
||||
;; Navigate and set-query are also similer to react-router API.
|
||||
(defn
|
||||
^{:see-also ["reitit.frontend.history/navigate"]}
|
||||
navigate
|
||||
"Updates the browser location and either pushes new entry to the history stack
|
||||
or replaces the latest entry in the the history stack (controlled by
|
||||
`replace` option) using URL built from a route defined by name given
|
||||
parameters.
|
||||
|
||||
Will also trigger on-navigate callback on Reitit frontend History handler.
|
||||
|
||||
Note: currently collections in query-parameters are encoded as field-value
|
||||
pairs separated by &, i.e. \"?a=1&a=2\", if you want to encode them
|
||||
differently, convert the collections to strings first.
|
||||
|
||||
See also:
|
||||
https://developer.mozilla.org/en-US/docs/Web/API/History/pushState
|
||||
https://developer.mozilla.org/en-US/docs/Web/API/History/replaceState"
|
||||
([name]
|
||||
(rfh/navigate @history name))
|
||||
([name {:keys [path-params query-params replace] :as opts}]
|
||||
(rfh/navigate @history name opts)))
|
||||
|
||||
(defn
|
||||
^{:see-also ["reitit.frontend.history/set-query"]}
|
||||
set-query
|
||||
"Update query parameters for the current route.
|
||||
|
||||
New query params can be given as a map, or a function taking
|
||||
the old params and returning the new modified params.
|
||||
|
||||
Note: The query parameter values aren't coereced, so the
|
||||
update fn will see string values for all query params."
|
||||
([new-query-or-update-fn]
|
||||
(rfh/set-query @history new-query-or-update-fn))
|
||||
([new-query-or-update-fn {:keys [replace] :as opts}]
|
||||
(rfh/set-query @history new-query-or-update-fn opts)))
|
||||
|
|
|
|||
|
|
@ -3,15 +3,15 @@
|
|||
events."
|
||||
(:require [goog.events :as gevents]
|
||||
[reitit.core :as reitit]
|
||||
[reitit.frontend :as rf])
|
||||
(:import goog.Uri))
|
||||
[reitit.frontend :as rf]
|
||||
goog.Uri))
|
||||
|
||||
(defprotocol History
|
||||
(-init [this] "Create event listeners")
|
||||
(-stop [this] "Remove event listeners")
|
||||
(-on-navigate [this path])
|
||||
(-get-path [this])
|
||||
(-href [this path]))
|
||||
(-on-navigate [this path] "Find a match for current routing path and call on-navigate callback")
|
||||
(-get-path [this] "Get the current routing path")
|
||||
(-href [this path] "Converts given routing path to browser location"))
|
||||
|
||||
;; This version listens for both pop-state and hash-change for
|
||||
;; compatibility for old browsers not supporting History API.
|
||||
|
|
@ -78,7 +78,7 @@
|
|||
the page location is updated using History API."
|
||||
[router e el uri]
|
||||
(let [current-domain (if (exists? js/location)
|
||||
(.getDomain (.parse Uri js/location)))]
|
||||
(.getDomain (.parse goog.Uri js/location)))]
|
||||
(and (or (and (not (.hasScheme uri)) (not (.hasDomain uri)))
|
||||
(= current-domain (.getDomain uri)))
|
||||
(not (.-altKey e))
|
||||
|
|
@ -109,7 +109,7 @@
|
|||
ignore-anchor-click (fn [e]
|
||||
;; Returns the next matching ancestor of event target
|
||||
(when-let [el (closest-by-tag (event-target e) "a")]
|
||||
(let [uri (.parse Uri (.-href el))]
|
||||
(let [uri (.parse goog.Uri (.-href el))]
|
||||
(when (ignore-anchor-click-predicate router e el uri)
|
||||
(.preventDefault e)
|
||||
(let [path (str (.getPath uri)
|
||||
|
|
@ -177,7 +177,9 @@
|
|||
(if history
|
||||
(-stop history)))
|
||||
|
||||
(defn href
|
||||
(defn
|
||||
^{:see-also ["reitit.core/match->path"]}
|
||||
href
|
||||
"Generate a URL for a route defined by name, with given path-params and query-params.
|
||||
|
||||
The URL is formatted using Reitit frontend history handler, so using it with
|
||||
|
|
@ -219,7 +221,9 @@
|
|||
(.pushState js/window.history nil "" (-href history path))
|
||||
(-on-navigate history path))))
|
||||
|
||||
(defn replace-state
|
||||
(defn
|
||||
^{:see-also ["reitit.core/match->path"]}
|
||||
replace-state
|
||||
"Updates the browser location and replaces latest entry in the history stack
|
||||
using URL built from a route defined by name, with given path-params and
|
||||
query-params.
|
||||
|
|
@ -241,3 +245,50 @@
|
|||
path (reitit/match->path match query-params)]
|
||||
(.replaceState js/window.history nil "" (-href history path))
|
||||
(-on-navigate history path))))
|
||||
|
||||
(defn
|
||||
^{:see-also ["reitit.core/match->path"]}
|
||||
navigate
|
||||
"Updates the browser location and either pushes new entry to the history stack
|
||||
or replaces the latest entry in the the history stack (controlled by
|
||||
`replace` option) using URL built from a route defined by name given
|
||||
parameters.
|
||||
|
||||
Will also trigger on-navigate callback on Reitit frontend History handler.
|
||||
|
||||
Note: currently collections in query-parameters are encoded as field-value
|
||||
pairs separated by &, i.e. \"?a=1&a=2\", if you want to encode them
|
||||
differently, convert the collections to strings first.
|
||||
|
||||
See also:
|
||||
https://developer.mozilla.org/en-US/docs/Web/API/History/pushState
|
||||
https://developer.mozilla.org/en-US/docs/Web/API/History/replaceState"
|
||||
([history name]
|
||||
(navigate history name nil))
|
||||
([history name {:keys [path-params query-params replace] :as opts}]
|
||||
(let [match (rf/match-by-name! (:router history) name path-params)
|
||||
path (reitit/match->path match query-params)]
|
||||
(if replace
|
||||
(.replaceState js/window.history nil "" (-href history path))
|
||||
(.pushState js/window.history nil "" (-href history path)))
|
||||
(-on-navigate history path))))
|
||||
|
||||
(defn
|
||||
^{:see-also ["reitit.frontend/set-query-params"]}
|
||||
set-query
|
||||
"Update query parameters for the current route.
|
||||
|
||||
New query params can be given as a map, or a function taking
|
||||
the old params and returning the new modified params.
|
||||
|
||||
Note: The query parameter values aren't coereced, so the
|
||||
update fn will see string values for all query params."
|
||||
([history new-query-or-update-fn]
|
||||
(set-query history new-query-or-update-fn nil))
|
||||
([history new-query-or-update-fn {:keys [replace] :as opts}]
|
||||
(let [current-path (-get-path history)
|
||||
new-path (rf/set-query-params current-path new-query-or-update-fn)]
|
||||
(if replace
|
||||
(.replaceState js/window.history nil "" (-href history new-path))
|
||||
(.pushState js/window.history nil "" (-href history new-path)))
|
||||
(-on-navigate history new-path))))
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
:scm {:name "git"
|
||||
:url "https://github.com/metosin/reitit"
|
||||
:dir "../.."}
|
||||
:plugins [[lein-parent "0.3.2"]]
|
||||
:plugins [[lein-parent "0.3.9"]]
|
||||
:parent-project {:path "../../project.clj"
|
||||
:inherit [:deploy-repositories :managed-dependencies]}
|
||||
:dependencies [[metosin/reitit-core]
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
:scm {:name "git"
|
||||
:url "https://github.com/metosin/reitit"
|
||||
:dir "../.."}
|
||||
:plugins [[lein-parent "0.3.2"]]
|
||||
:plugins [[lein-parent "0.3.9"]]
|
||||
:parent-project {:path "../../project.clj"
|
||||
:inherit [:deploy-repositories :managed-dependencies]}
|
||||
:dependencies [[metosin/reitit-ring]
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
:scm {:name "git"
|
||||
:url "https://github.com/metosin/reitit"
|
||||
:dir "../.."}
|
||||
:plugins [[lein-parent "0.3.2"]]
|
||||
:plugins [[lein-parent "0.3.9"]]
|
||||
:parent-project {:path "../../project.clj"
|
||||
:inherit [:deploy-repositories :managed-dependencies]}
|
||||
:dependencies [[metosin/reitit-core]
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
:scm {:name "git"
|
||||
:url "https://github.com/metosin/reitit"
|
||||
:scm "../.."}
|
||||
:plugins [[lein-parent "0.3.2"]]
|
||||
:plugins [[lein-parent "0.3.9"]]
|
||||
:parent-project {:path "../../project.clj"
|
||||
:inherit [:deploy-repositories :managed-dependencies]}
|
||||
:dependencies [[metosin/reitit-ring]
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
:scm {:name "git"
|
||||
:url "https://github.com/metosin/reitit"
|
||||
:dir "../.."}
|
||||
:plugins [[lein-parent "0.3.8"]]
|
||||
:plugins [[lein-parent "0.3.9"]]
|
||||
:parent-project {:path "../../project.clj"
|
||||
:inherit [:deploy-repositories :managed-dependencies]}
|
||||
:dependencies [[metosin/reitit-core]])
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
:scm {:name "git"
|
||||
:url "https://github.com/metosin/reitit"
|
||||
:dir "../.."}
|
||||
:plugins [[lein-parent "0.3.2"]]
|
||||
:plugins [[lein-parent "0.3.9"]]
|
||||
:parent-project {:path "../../project.clj"
|
||||
:inherit [:deploy-repositories :managed-dependencies]}
|
||||
:dependencies [[io.pedestal/pedestal.service]
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
:scm {:name "git"
|
||||
:url "https://github.com/metosin/reitit"
|
||||
:dir "../.."}
|
||||
:plugins [[lein-parent "0.3.2"]]
|
||||
:plugins [[lein-parent "0.3.9"]]
|
||||
:parent-project {:path "../../project.clj"
|
||||
:inherit [:deploy-repositories :managed-dependencies]}
|
||||
:dependencies [[metosin/reitit-core]
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
:scm {:name "git"
|
||||
:url "https://github.com/metosin/reitit"
|
||||
:dir "../.."}
|
||||
:plugins [[lein-parent "0.3.2"]]
|
||||
:plugins [[lein-parent "0.3.9"]]
|
||||
:parent-project {:path "../../project.clj"
|
||||
:inherit [:deploy-repositories :managed-dependencies]}
|
||||
:dependencies [[metosin/reitit-core]
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
:scm {:name "git"
|
||||
:url "https://github.com/metosin/reitit"
|
||||
:dir "../.."}
|
||||
:plugins [[lein-parent "0.3.2"]]
|
||||
:plugins [[lein-parent "0.3.9"]]
|
||||
:parent-project {:path "../../project.clj"
|
||||
:inherit [:deploy-repositories :managed-dependencies]}
|
||||
:dependencies [[metosin/reitit-core]
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
:scm {:name "git"
|
||||
:url "https://github.com/metosin/reitit"
|
||||
:dir "../.."}
|
||||
:plugins [[lein-parent "0.3.2"]]
|
||||
:plugins [[lein-parent "0.3.9"]]
|
||||
:parent-project {:path "../../project.clj"
|
||||
:inherit [:deploy-repositories :managed-dependencies]}
|
||||
:dependencies [[metosin/reitit-core]
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
:scm {:name "git"
|
||||
:url "https://github.com/metosin/reitit"
|
||||
:dir "../.."}
|
||||
:plugins [[lein-parent "0.3.2"]]
|
||||
:plugins [[lein-parent "0.3.9"]]
|
||||
:parent-project {:path "../../project.clj"
|
||||
:inherit [:deploy-repositories :managed-dependencies]}
|
||||
:dependencies [[metosin/reitit-ring]
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
:scm {:name "git"
|
||||
:url "https://github.com/metosin/reitit"
|
||||
:dir "../.."}
|
||||
:plugins [[lein-parent "0.3.2"]]
|
||||
:plugins [[lein-parent "0.3.9"]]
|
||||
:parent-project {:path "../../project.clj"
|
||||
:inherit [:deploy-repositories :managed-dependencies]}
|
||||
:dependencies [[metosin/reitit-core]])
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
:scm {:name "git"
|
||||
:url "https://github.com/metosin/reitit"
|
||||
:dir "../.."}
|
||||
:plugins [[lein-parent "0.3.2"]]
|
||||
:plugins [[lein-parent "0.3.9"]]
|
||||
:parent-project {:path "../../project.clj"
|
||||
:inherit [:deploy-repositories :managed-dependencies]}
|
||||
:dependencies [[metosin/reitit-core]
|
||||
|
|
|
|||
19
project.clj
19
project.clj
|
|
@ -31,13 +31,13 @@
|
|||
[metosin/reitit-frontend "0.6.0"]
|
||||
[metosin/reitit-sieppari "0.6.0"]
|
||||
[metosin/reitit-pedestal "0.6.0"]
|
||||
[metosin/ring-swagger-ui "4.15.5"]
|
||||
[metosin/ring-swagger-ui "4.18.1"]
|
||||
[metosin/spec-tools "0.10.5"]
|
||||
[metosin/schema-tools "0.13.0"]
|
||||
[metosin/muuntaja "0.6.8"]
|
||||
[metosin/jsonista "0.3.7"]
|
||||
[metosin/sieppari "0.0.0-alpha13"]
|
||||
[metosin/malli "0.10.4"]
|
||||
[metosin/malli "0.11.0"]
|
||||
|
||||
;; https://clojureverse.org/t/depending-on-the-right-versions-of-jackson-libraries/5111
|
||||
[com.fasterxml.jackson.core/jackson-core "2.14.2"]
|
||||
|
|
@ -48,12 +48,13 @@
|
|||
[expound "0.9.0"]
|
||||
[lambdaisland/deep-diff "0.0-47"]
|
||||
[com.bhauman/spell-spec "0.1.2"]
|
||||
[ring/ring-core "1.9.6"]
|
||||
[ring/ring-core "1.10.0"]
|
||||
|
||||
[io.pedestal/pedestal.service "0.5.10"]]
|
||||
|
||||
:plugins [[jonase/eastwood "1.3.0"]
|
||||
;[lein-virgil "0.1.7"]
|
||||
[lein-ancient "1.0.0-RC3"]
|
||||
[lein-doo "0.1.11"]
|
||||
[lein-cljsbuild "1.1.8"]
|
||||
[lein-cloverage "1.2.4"]
|
||||
|
|
@ -91,7 +92,7 @@
|
|||
[metosin/muuntaja "0.6.8"]
|
||||
[metosin/sieppari "0.0.0-alpha13"]
|
||||
[metosin/jsonista "0.3.7"]
|
||||
[metosin/malli "0.10.4"]
|
||||
[metosin/malli "0.11.0"]
|
||||
[lambdaisland/deep-diff "0.0-47"]
|
||||
[meta-merge "1.0.0"]
|
||||
[com.bhauman/spell-spec "0.1.2"]
|
||||
|
|
@ -100,21 +101,21 @@
|
|||
|
||||
[orchestra "2021.01.01-1"]
|
||||
|
||||
[ring "1.9.6"]
|
||||
[ring "1.10.0"]
|
||||
[ikitommi/immutant-web "3.0.0-alpha1"]
|
||||
[metosin/ring-http-response "0.9.3"]
|
||||
[metosin/ring-swagger-ui "4.15.5"]
|
||||
[metosin/ring-swagger-ui "4.18.1"]
|
||||
|
||||
[criterium "0.4.6"]
|
||||
[org.clojure/test.check "1.1.1"]
|
||||
[org.clojure/tools.namespace "1.4.4"]
|
||||
[com.gfredericks/test.chuck "0.2.14"]
|
||||
[nubank/matcher-combinators "3.8.4"]
|
||||
[nubank/matcher-combinators "3.8.5"]
|
||||
|
||||
[io.pedestal/pedestal.service "0.5.10"]
|
||||
|
||||
[org.clojure/core.async "1.6.673"]
|
||||
[manifold "0.3.0"]
|
||||
[manifold "0.4.0"]
|
||||
[funcool/promesa "10.0.594"]
|
||||
|
||||
[com.clojure-goes-fast/clj-async-profiler "1.0.3"]
|
||||
|
|
@ -133,7 +134,7 @@
|
|||
[io.pedestal/pedestal.jetty "0.5.10"]
|
||||
[calfpath "0.8.1"]
|
||||
[org.clojure/core.async "1.6.673"]
|
||||
[manifold "0.3.0"]
|
||||
[manifold "0.4.0"]
|
||||
[funcool/promesa "10.0.594"]
|
||||
[metosin/sieppari]
|
||||
[yada "1.2.16"]
|
||||
|
|
|
|||
|
|
@ -614,3 +614,59 @@
|
|||
keys))))
|
||||
(testing "spec is valid"
|
||||
(is (nil? (validate spec))))))))))
|
||||
|
||||
(deftest recursive-test
|
||||
;; Recursive schemas only properly supported for malli
|
||||
;; See https://github.com/metosin/schema-tools/issues/41
|
||||
(let [app (ring/ring-handler
|
||||
(ring/router
|
||||
[["/parameters"
|
||||
{:post {:description "parameters"
|
||||
:coercion malli/coercion
|
||||
:parameters {:request
|
||||
{:body
|
||||
[:schema
|
||||
{:registry {"friend" [:map
|
||||
[:age int?]
|
||||
[:pet [:ref "pet"]]]
|
||||
"pet" [:map
|
||||
[:name :string]
|
||||
[:friends [:vector [:ref "friend"]]]]}}
|
||||
"friend"]}}
|
||||
:handler (fn [req]
|
||||
{:status 200
|
||||
:body (-> req :parameters :request)})}}]
|
||||
["/openapi.json"
|
||||
{:get {:handler (openapi/create-openapi-handler)
|
||||
:openapi {:info {:title "" :version "0.0.1"}}
|
||||
:no-doc true}}]]
|
||||
{:validate reitit.ring.spec/validate
|
||||
:data {:middleware [openapi/openapi-feature
|
||||
rrc/coerce-request-middleware
|
||||
rrc/coerce-response-middleware]}}))
|
||||
spec (-> {:request-method :get
|
||||
:uri "/openapi.json"}
|
||||
app
|
||||
:body)]
|
||||
(is (= {:info {:title "" :version "0.0.1"}
|
||||
:openapi "3.1.0"
|
||||
:x-id #{:reitit.openapi/default}
|
||||
:paths {"/parameters"
|
||||
{:post
|
||||
{:description "parameters"
|
||||
:requestBody
|
||||
{:content
|
||||
{"application/json"
|
||||
{:schema {:$ref "#/definitions/friend"
|
||||
:definitions {"friend" {:properties {:age {:type "integer"}
|
||||
:pet {:$ref "#/definitions/pet"}}
|
||||
:required [:age :pet]
|
||||
:type "object"}
|
||||
"pet" {:properties {:friends {:items {:$ref "#/definitions/friend"}
|
||||
:type "array"}
|
||||
:name {:type "string"}}
|
||||
:required [:name :friends]
|
||||
:type "object"}}}}}}}}}}
|
||||
spec))
|
||||
(testing "spec is valid"
|
||||
(is (nil? (validate spec))))))
|
||||
|
|
|
|||
|
|
@ -6,7 +6,21 @@
|
|||
[schema.core :as s]
|
||||
[reitit.coercion.schema :as rcs]
|
||||
[reitit.coercion.malli :as rcm]
|
||||
[reitit.frontend.test-utils :refer [capture-console]]))
|
||||
[reitit.frontend.test-utils :refer [capture-console]]
|
||||
[reitit.impl :as impl]))
|
||||
|
||||
(deftest query-params-test
|
||||
(is (= {:foo "1"}
|
||||
(rf/query-params (.parse goog.Uri "?foo=1"))))
|
||||
|
||||
(is (= {:foo "1" :bar "aaa"}
|
||||
(rf/query-params (.parse goog.Uri "?foo=1&bar=aaa"))))
|
||||
|
||||
(is (= {:foo ""}
|
||||
(rf/query-params (.parse goog.Uri "?foo="))))
|
||||
|
||||
(is (= {:foo ""}
|
||||
(rf/query-params (.parse goog.Uri "?foo")))))
|
||||
|
||||
(defn m [x]
|
||||
(assoc x :data nil :result nil))
|
||||
|
|
@ -227,3 +241,44 @@
|
|||
:token_type "bearer"
|
||||
:expires_in 3600}}})
|
||||
(m (rf/match-by-path router "/5?mode=foo#access_token=foo&refresh_token=bar&provider_token=baz&token_type=bearer&expires_in=3600"))))))))
|
||||
|
||||
(deftest set-query-params-test
|
||||
(is (= "foo?bar=1"
|
||||
(rf/set-query-params "foo" {:bar 1})
|
||||
(rf/set-query-params "foo" #(assoc % :bar 1))
|
||||
;; Also compare to reitit.impl version which is used by match->path (and history fns)
|
||||
(str "foo?" (impl/query-string {:bar 1}))))
|
||||
|
||||
(testing "Encoding"
|
||||
(is (= "foo?bar=foo%20bar"
|
||||
(rf/set-query-params "foo" {:bar "foo bar"})
|
||||
(rf/set-query-params "foo" #(assoc % :bar "foo bar"))
|
||||
;; FIXME: Reitit.impl encodes space as "+"
|
||||
; (str "foo?" (impl/query-string {:bar "foo bar"}))
|
||||
)))
|
||||
|
||||
(testing "Keep fragment"
|
||||
(is (= "foo?bar=1&zzz=2#aaa"
|
||||
(rf/set-query-params "foo?bar=1#aaa" #(assoc % :zzz 2)))))
|
||||
|
||||
(is (= "foo?asd=1&bar=1"
|
||||
(rf/set-query-params "foo?asd=1" #(assoc % :bar 1))))
|
||||
|
||||
(is (= "foo?bar=1"
|
||||
(rf/set-query-params "foo?asd=1&bar=1" #(dissoc % :asd))))
|
||||
|
||||
(is (= "foo?bar"
|
||||
(rf/set-query-params "foo?asd=1&bar" #(dissoc % :asd))))
|
||||
|
||||
(is (= "foo?bar"
|
||||
(rf/set-query-params "foo" #(assoc % :bar ""))
|
||||
;; FIXME: Reitit.impl adds "=" for empty string values
|
||||
; (str "foo?" (impl/query-string {:bar ""}))
|
||||
))
|
||||
|
||||
(is (= "foo"
|
||||
(rf/set-query-params "foo?asd=1" #(dissoc % :asd))))
|
||||
|
||||
(testing "Need to coerce current values manually"
|
||||
(is (= "foo?foo=2"
|
||||
(rf/set-query-params "foo?foo=1" (fn [q] (update q :foo #(inc (js/parseInt %)))))))))
|
||||
|
|
|
|||
|
|
@ -30,33 +30,53 @@
|
|||
(is (= "/" url)
|
||||
"start at root")
|
||||
(rfe/push-state ::foo))
|
||||
;; 0. /
|
||||
;; 1. /foo
|
||||
2 (do (is (= "/foo" url)
|
||||
"push-state")
|
||||
(.back js/window.history))
|
||||
;; 0. /
|
||||
3 (do (is (= "/" url)
|
||||
"go back")
|
||||
(rfe/push-state ::bar {:id 1}))
|
||||
(rfe/navigate ::bar {:path-params {:id 1}}))
|
||||
;; 0. /
|
||||
;; 1. /bar/1
|
||||
4 (do (is (= "/bar/1" url)
|
||||
"push-state 2")
|
||||
(rfe/replace-state ::bar {:id 2}))
|
||||
;; 0. /
|
||||
;; 1. /bar/2
|
||||
5 (do (is (= "/bar/2" url)
|
||||
"replace-state")
|
||||
(.back js/window.history))
|
||||
6 (do (is (= "/" url)
|
||||
"go back after replace state")
|
||||
(rfe/set-query {:a 1}))
|
||||
;; 0. /
|
||||
;; 1. /bar/2
|
||||
;; 2. /bar/2?a=1
|
||||
6 (do (is (= "/bar/2?a=1" url)
|
||||
"update-query with map")
|
||||
(rfe/set-query #(assoc % :b "foo") {:replace true}))
|
||||
;; 0. /
|
||||
;; 1. /bar/2
|
||||
;; 2. /bar/2?a=1&b=foo
|
||||
7 (do (is (= "/bar/2?a=1&b=foo" url)
|
||||
"update-query with fn")
|
||||
(.go js/window.history -2))
|
||||
;; 0. /
|
||||
8 (do (is (= "/" url)
|
||||
"go back two events")
|
||||
|
||||
;; Reset to ensure old event listeners aren't called
|
||||
(rfe/start! router
|
||||
(fn on-navigate [match history]
|
||||
(let [url (rfh/-get-path history)]
|
||||
(case (swap! n inc)
|
||||
7 (do (is (= "/" url)
|
||||
9 (do (is (= "/" url)
|
||||
"start at root")
|
||||
(rfe/push-state ::foo))
|
||||
8 (do (is (= "/foo" url)
|
||||
"push-state")
|
||||
(rfh/stop! @rfe/history)
|
||||
(done))
|
||||
10 (do (is (= "/foo" url)
|
||||
"push-state")
|
||||
(rfh/stop! @rfe/history)
|
||||
(done))
|
||||
(do
|
||||
(is false (str "extra event 2" {:n @n, :url url}))
|
||||
(done)))))
|
||||
|
|
|
|||
Loading…
Reference in a new issue