mirror of
https://github.com/metosin/reitit.git
synced 2025-12-17 16:31:11 +00:00
Validate routes for duplicates (fixes #23)
This commit is contained in:
parent
0befddf72c
commit
851e35ef52
3 changed files with 60 additions and 1 deletions
|
|
@ -60,6 +60,12 @@
|
|||
(cond->> (->> (walk data opts) (map-meta merge-meta))
|
||||
coerce (into [] (keep #(coerce % opts)))))
|
||||
|
||||
(defn first-conflicting-routes [routes]
|
||||
(loop [[r & rest] routes]
|
||||
(if (seq rest)
|
||||
(or (some #(if (impl/conflicting-routes? r %) [r %]) rest)
|
||||
(recur rest)))))
|
||||
|
||||
(defn name-lookup [[_ {:keys [name]}] opts]
|
||||
(if name #{name}))
|
||||
|
||||
|
|
|
|||
|
|
@ -121,6 +121,25 @@
|
|||
:matcher #(if (= path %) {})
|
||||
:handler handler})))
|
||||
|
||||
(defn segments [path]
|
||||
(let [ss (-> (str/split path #"/") rest vec)]
|
||||
(if (str/ends-with? path "/")
|
||||
(conj ss "") ss)))
|
||||
|
||||
(defn- catch-all? [segment]
|
||||
(= \* (first segment)))
|
||||
|
||||
(defn conflicting-routes? [[p1 :as route1] [p2 :as route2]]
|
||||
(loop [[s1 & ss1] (segments p1)
|
||||
[s2 & ss2] (segments p2)]
|
||||
(cond
|
||||
(= s1 s2 nil) true
|
||||
(or (nil? s1) (nil? s2)) false
|
||||
(or (catch-all? s1) (catch-all? s2)) true
|
||||
(or (wild? s1) (wild? s2)) (recur ss1 ss2)
|
||||
(not= s1 s2) false
|
||||
:else (recur ss1 ss2))))
|
||||
|
||||
(defn path-for [^Route route params]
|
||||
(if-let [required (:params route)]
|
||||
(if (every? #(contains? params %) required)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
(ns reitit.core-test
|
||||
(:require [clojure.test :refer [deftest testing is]]
|
||||
(:require [clojure.test :refer [deftest testing is are]]
|
||||
[reitit.core :as reitit #?@(:cljs [:refer [Match]])])
|
||||
#?(:clj
|
||||
(:import (reitit.core Match)
|
||||
|
|
@ -138,3 +138,37 @@
|
|||
:path "/api/user/1/2"
|
||||
:params {:id "1", :sub-id "2"}})
|
||||
(reitit/match-by-path router "/api/user/1/2"))))))
|
||||
|
||||
(deftest first-conflicting-routes-test
|
||||
(are [conflicting? data]
|
||||
(let [routes (reitit/resolve-routes data {})]
|
||||
(= (if conflicting? routes)
|
||||
(reitit/first-conflicting-routes
|
||||
(reitit/resolve-routes routes {}))))
|
||||
|
||||
true [["/a"]
|
||||
["/a"]]
|
||||
|
||||
true [["/a"]
|
||||
["/:b"]]
|
||||
|
||||
true [["/a"]
|
||||
["/*b"]]
|
||||
|
||||
true [["/a/1/2"]
|
||||
["/*b"]]
|
||||
|
||||
false [["/a"]
|
||||
["/a/"]]
|
||||
|
||||
false [["/a"]
|
||||
["/a/1"]]
|
||||
|
||||
false [["/a"]
|
||||
["/a/:b"]]
|
||||
|
||||
false [["/a"]
|
||||
["/a/*b"]]
|
||||
|
||||
true [["/v2/public/messages/dataset/bulk"]
|
||||
["/v2/public/messages/dataset/:dataset-id"]]))
|
||||
|
|
|
|||
Loading…
Reference in a new issue