summaryrefslogtreecommitdiff
path: root/test/ruuter/core_test.cljc
diff options
context:
space:
mode:
authorAsko Nõmm <asko@nmm.ee>2026-04-11 21:36:24 +0300
committerAsko Nõmm <asko@nmm.ee>2026-04-11 21:36:24 +0300
commit58d7dba6be314bae223e707dc3d045752ef82691 (patch)
tree354d1f03834ee2a7514092382df421a9c86acc50 /test/ruuter/core_test.cljc
parentd07c36e53cf2327d56a9f17c734e08f3511ceb2d (diff)
Validate conflicting trie parameter names
Throw on conflicting param, optional, and wildcard names at the same trie position and add cross-runtime tests to enforce the behavior.
Diffstat (limited to 'test/ruuter/core_test.cljc')
-rw-r--r--test/ruuter/core_test.cljc107
1 files changed, 107 insertions, 0 deletions
diff --git a/test/ruuter/core_test.cljc b/test/ruuter/core_test.cljc
index 9f47212..d9150e6 100644
--- a/test/ruuter/core_test.cljc
+++ b/test/ruuter/core_test.cljc
@@ -348,3 +348,110 @@
(ruuter/route [{:path "/hello" :method :get
:response "just a string"}]
{:uri "/hello" :request-method :get})))))
+
+;; -- Conflicting Parameter Name Tests --
+
+#?(:clj
+ (deftest conflicting-param-names-test
+ (testing "Conflicting :param names — throws exception"
+ (is (thrown? clojure.lang.ExceptionInfo
+ (ruuter/route [{:path "/user/:id" :method :get
+ :response (fn [req] {:status 200 :body "first"})}
+ {:path "/user/:x" :method :get
+ :response (fn [req] {:status 200 :body "second"})}]
+ {:uri "/user/42" :request-method :get}))))
+
+ (testing "Conflicting :param names across methods — throws exception"
+ (is (thrown? clojure.lang.ExceptionInfo
+ (ruuter/route [{:path "/user/:id" :method :get
+ :response (fn [req] {:status 200 :body "get"})}
+ {:path "/user/:x" :method :post
+ :response (fn [req] {:status 200 :body "post"})}]
+ {:uri "/user/42" :request-method :get})))))
+
+ :cljs
+ (deftest conflicting-param-names-test
+ (testing "Conflicting :param names — throws exception"
+ (is (thrown? ExceptionInfo
+ (ruuter/route [{:path "/user/:id" :method :get
+ :response (fn [req] {:status 200 :body "first"})}
+ {:path "/user/:x" :method :get
+ :response (fn [req] {:status 200 :body "second"})}]
+ {:uri "/user/42" :request-method :get}))))
+
+ (testing "Conflicting :param names across methods — throws exception"
+ (is (thrown? ExceptionInfo
+ (ruuter/route [{:path "/user/:id" :method :get
+ :response (fn [req] {:status 200 :body "get"})}
+ {:path "/user/:x" :method :post
+ :response (fn [req] {:status 200 :body "post"})}]
+ {:uri "/user/42" :request-method :get}))))))
+
+#?(:clj
+ (deftest conflicting-optional-names-test
+ (testing "Conflicting :optional names — throws exception"
+ (is (thrown? clojure.lang.ExceptionInfo
+ (ruuter/route [{:path "/search/:q?" :method :get
+ :response (fn [req] {:status 200 :body "first"})}
+ {:path "/search/:query?" :method :get
+ :response (fn [req] {:status 200 :body "second"})}]
+ {:uri "/search/clojure" :request-method :get})))))
+
+ :cljs
+ (deftest conflicting-optional-names-test
+ (testing "Conflicting :optional names — throws exception"
+ (is (thrown? ExceptionInfo
+ (ruuter/route [{:path "/search/:q?" :method :get
+ :response (fn [req] {:status 200 :body "first"})}
+ {:path "/search/:query?" :method :get
+ :response (fn [req] {:status 200 :body "second"})}]
+ {:uri "/search/clojure" :request-method :get}))))))
+
+#?(:clj
+ (deftest conflicting-wildcard-names-test
+ (testing "Conflicting :wildcard names — throws exception"
+ (is (thrown? clojure.lang.ExceptionInfo
+ (ruuter/route [{:path "/files/:path*" :method :get
+ :response (fn [req] {:status 200 :body "first"})}
+ {:path "/files/:glob*" :method :get
+ :response (fn [req] {:status 200 :body "second"})}]
+ {:uri "/files/a/b/c" :request-method :get}))))
+
+ (testing "Same wildcard name with different methods — no conflict"
+ (is (= {:status 200 :body "get-files"}
+ (ruuter/route [{:path "/files/:path*" :method :get
+ :response {:status 200 :body "get-files"}}
+ {:path "/files/:path*" :method :delete
+ :response {:status 200 :body "delete-files"}}]
+ {:uri "/files/a/b/c" :request-method :get})))
+ (is (= {:status 200 :body "delete-files"}
+ (ruuter/route [{:path "/files/:path*" :method :get
+ :response {:status 200 :body "get-files"}}
+ {:path "/files/:path*" :method :delete
+ :response {:status 200 :body "delete-files"}}]
+ {:uri "/files/a/b/c" :request-method :delete})))))
+
+ :cljs
+ (deftest conflicting-wildcard-names-test
+ (testing "Conflicting :wildcard names — throws exception"
+ (is (thrown? ExceptionInfo
+ (ruuter/route [{:path "/files/:path*" :method :get
+ :response (fn [req] {:status 200 :body "first"})}
+ {:path "/files/:glob*" :method :get
+ :response (fn [req] {:status 200 :body "second"})}]
+ {:uri "/files/a/b/c" :request-method :get}))))
+
+ (testing "Same wildcard name with different methods — no conflict"
+ (is (= {:status 200 :body "get-files"}
+ (ruuter/route [{:path "/files/:path*" :method :get
+ :response {:status 200 :body "get-files"}}
+ {:path "/files/:path*" :method :delete
+ :response {:status 200 :body "delete-files"}}]
+ {:uri "/files/a/b/c" :request-method :get})))
+ (is (= {:status 200 :body "delete-files"}
+ (ruuter/route [{:path "/files/:path*" :method :get
+ :response {:status 200 :body "get-files"}}
+ {:path "/files/:path*" :method :delete
+ :response {:status 200 :body "delete-files"}}]
+ {:uri "/files/a/b/c" :request-method :delete}))))))
+