diff --git a/src/Saturn/Application.fs b/src/Saturn/Application.fs index 72d539c3..01091f4b 100644 --- a/src/Saturn/Application.fs +++ b/src/Saturn/Application.fs @@ -224,9 +224,14 @@ module Application = ) ///Defines top-level router used for the application + /// + ///This can only be called once, and not after `no_router`! [] member __.Router(state, handler) = - {state with Router = Some handler} + match state.NoRouter, state.Router with + | false, None -> {state with Router = Some handler} + | true, _ -> failwith "Cannot add a router, after `no_router` was set!" + | _, Some _ -> failwith "Cannot add a second router!" ///Defines top-level endpoint router used for the application [] @@ -234,9 +239,13 @@ module Application = {state with EndpointRouter = Some routes} ///Disable warning message about lack of `router` definition. Should be used for channels-only or gRPC applications. + /// + ///This cannot be called after `use_router`! [] member __.NoRouter(state) = - {state with NoRouter = true} + match state.Router with + | Some _ -> failwith "Cannot set `no_router` after a router with `use_router` has been set!" + | _ -> {state with NoRouter = true} ///Disables any configuration of webhost. Could be used for generic `IHostBuilder` applications not using Kestrel/IIS [] diff --git a/tests/Saturn.UnitTests/SimpleTests.fs b/tests/Saturn.UnitTests/SimpleTests.fs index 159058aa..a61bf913 100644 --- a/tests/Saturn.UnitTests/SimpleTests.fs +++ b/tests/Saturn.UnitTests/SimpleTests.fs @@ -41,3 +41,37 @@ let tests = Expect.equal (getBody ctx) """{"id":"myId","links":["myLink1","myLink2"]}""" "Result should be equal" ] + +//---------------------------`Application only takes one router` tests---------------------------------------- + +[] +let routerTests = + testList "Application only takes one router" [ + testCase "Second router throws" (fun _ -> + let app () = + application { + use_router (text "") + use_router (text "") + } + + Expect.throws (app >> ignore) "Application did not fail on second router!" + ) + testCase "Adding a router after `no_router` throws" (fun _ -> + let app () = + application { + no_router + use_router (text "") + } + + Expect.throws (app >> ignore) "Application did not fail on router after no_router!" + ) + testCase "Adding a `no_router after `use_router` throws" (fun _ -> + let app () = + application { + use_router (text "") + no_router + } + + Expect.throws (app >> ignore) "Application did not fail on no_router after use_router!" + ) + ]