diff --git a/opium/src/router.ml b/opium/src/router.ml index d82b0849..f7281d95 100644 --- a/opium/src/router.ml +++ b/opium/src/router.ml @@ -3,12 +3,14 @@ module Route = struct type t = | Nil + | Full_splat | Literal of string * t | Param of string option * t let rec sexp_of_t (t : t) : Sexplib0.Sexp.t = match t with | Nil -> Atom "Nil" + | Full_splat -> Atom "Full_splat" | Literal (x, y) -> List [ Atom x; sexp_of_t y ] | Param (x, y) -> let x : Sexplib0.Sexp.t = @@ -23,6 +25,7 @@ module Route = struct let rec parse_tokens params tokens = match tokens with + | [ "**" ] -> Full_splat | [] | [ "" ] -> Nil | token :: tokens -> if token = "" @@ -86,6 +89,7 @@ module Params = struct let create route captured = let rec loop acc (route : Route.t) captured = match route, captured with + | Full_splat, _ -> assert false | Nil, [] -> acc | Literal (_, route), _ -> loop acc route captured | Param (None, route), p :: captured -> @@ -159,6 +163,7 @@ let match_url t url = let match_route t route = let rec loop t (route : Route.t) = match route with + | Full_splat -> assert false | Nil -> (match t.data with | None -> [] @@ -190,6 +195,7 @@ let match_route t route = let add_no_check t orig_route a = let rec loop t (route : Route.t) = match route with + | Full_splat -> assert false | Nil -> { empty with data = Some (a, orig_route) } | Literal (lit, route) -> let literal = diff --git a/opium/test/opium_router_tests.ml b/opium/test/opium_router_tests.ml index 5b88edf6..8c282a57 100644 --- a/opium/test/opium_router_tests.ml +++ b/opium/test/opium_router_tests.ml @@ -37,6 +37,16 @@ let%expect_test "duplicate paramters" = [%expect {| [FAIL] invalid route duplicate parameter "bar" |}] ;; +let%expect_test "splat in the middle is wrong" = + valid_route "/foo/**/foo"; + [%expect {| [FAIL] invalid route double splat allowed only in the end |}] +;; + +let%expect_test "splat at the end" = + valid_route "/foo/**"; + [%expect {| [PASS] valid route |}] +;; + let test_match_url router url = match Router.match_url router url with | None -> print_endline "no match" @@ -93,7 +103,7 @@ let%expect_test "ambiguity in routes" = (Failure "duplicate routes") Raised at Stdlib.failwith in file "stdlib.ml", line 29, characters 17-33 Called from Stdlib__list.fold_left in file "list.ml", line 121, characters 24-34 - Called from Opium_tests__Opium_router_tests.(fun) in file "opium/test/opium_router_tests.ml", line 85, characters 2-49 + Called from Opium_tests__Opium_router_tests.(fun) in file "opium/test/opium_router_tests.ml", line 95, characters 2-49 Called from Expect_test_collector.Make.Instance.exec in file "collector/expect_test_collector.ml", line 244, characters 12-19 |}] ;; @@ -109,7 +119,7 @@ let%expect_test "ambiguity in routes 2" = (Failure "duplicate routes") Raised at Stdlib.failwith in file "stdlib.ml", line 29, characters 17-33 Called from Stdlib__list.fold_left in file "list.ml", line 121, characters 24-34 - Called from Opium_tests__Opium_router_tests.(fun) in file "opium/test/opium_router_tests.ml", line 101, characters 2-43 + Called from Opium_tests__Opium_router_tests.(fun) in file "opium/test/opium_router_tests.ml", line 111, characters 2-43 Called from Expect_test_collector.Make.Instance.exec in file "collector/expect_test_collector.ml", line 244, characters 12-19 |}] ;;