elm-pages-v3-beta/tests/Pages/RouteParamsTest.elm

261 lines
10 KiB
Elm
Raw Normal View History

2022-09-15 17:45:10 +03:00
module Pages.RouteParamsTest exposing (suite)
2022-09-12 21:59:36 +03:00
import Elm
import Elm.Annotation
import Elm.CodeGen
import Elm.Pretty
import Elm.ToString
import Expect exposing (Expectation)
2023-05-30 01:03:19 +03:00
import FatalError
import Fuzz exposing (Fuzzer)
import Pages.Internal.RoutePattern as RoutePattern
import Pretty
import Test exposing (Test, describe, fuzz, test)
suite : Test
suite =
describe "RouteParams"
[ test "no dynamic segments" <|
\() ->
RoutePattern.fromModuleName [ "No", "Dynamic", "Segments" ]
|> Maybe.map RoutePattern.toRouteParamsRecord
|> Expect.equal
(Just [])
, test "single dynamic segments" <|
\() ->
RoutePattern.fromModuleName [ "User", "Id_" ]
|> Maybe.map RoutePattern.toRouteParamsRecord
|> Expect.equal
(Just
[ ( "id", Elm.Annotation.string )
]
)
, test "two dynamic segments" <|
\() ->
RoutePattern.fromModuleName [ "UserId_", "ProductId_" ]
|> Maybe.map RoutePattern.toRouteParamsRecord
|> Expect.equal
(Just
[ ( "userId", Elm.Annotation.string )
, ( "productId", Elm.Annotation.string )
]
)
, test "splat ending" <|
\() ->
RoutePattern.fromModuleName [ "UserName_", "RepoName_", "Blob", "SPLAT_" ]
|> Maybe.map RoutePattern.toRouteParamsRecord
|> Expect.equal
(Just
[ ( "userName", Elm.Annotation.string )
, ( "repoName", Elm.Annotation.string )
, ( "splat"
, Elm.Annotation.tuple
Elm.Annotation.string
(Elm.Annotation.list Elm.Annotation.string)
)
]
)
, test "optional splat ending" <|
\() ->
RoutePattern.fromModuleName [ "SPLAT__" ]
|> Maybe.map RoutePattern.toRouteParamsRecord
|> Expect.equal
(Just
[ ( "splat", Elm.Annotation.list Elm.Annotation.string )
]
)
, test "ending with optional segment" <|
\() ->
RoutePattern.fromModuleName [ "Docs", "Section__" ]
|> Maybe.map RoutePattern.toRouteParamsRecord
|> Expect.equal
(Just
[ ( "section", Elm.Annotation.maybe Elm.Annotation.string )
]
)
2022-09-12 21:59:36 +03:00
, describe "toRouteVariant"
[ test "root route" <|
\() ->
[]
|> expectRouteDefinition
(Elm.variant "Index")
2022-09-12 21:59:36 +03:00
, test "static-only route" <|
\() ->
RoutePattern.fromModuleName [ "About" ]
|> Maybe.map RoutePattern.toVariant
|> Expect.equal
(Just (Elm.variant "About"))
2022-09-12 22:16:18 +03:00
, test "dynamic param" <|
\() ->
[ "User", "Id_" ]
|> expectRouteDefinition
(Elm.variantWith "User__Id_"
[ Elm.Annotation.record
[ ( "id", Elm.Annotation.string )
2022-09-12 22:16:18 +03:00
]
]
)
, test "required splat" <|
\() ->
[ "Username_", "Repo_", "Blob", "SPLAT_" ]
|> expectRouteDefinition
(Elm.variantWith "Username___Repo___Blob__SPLAT_"
[ Elm.Annotation.record
[ ( "username", Elm.Annotation.string )
, ( "repo", Elm.Annotation.string )
, ( "splat"
, Elm.Annotation.tuple
Elm.Annotation.string
(Elm.Annotation.list Elm.Annotation.string)
)
]
]
2022-09-12 22:16:18 +03:00
)
2022-09-12 23:20:44 +03:00
, test "optional splat" <|
\() ->
[ "SPLAT__" ]
|> expectRouteDefinition
(Elm.variantWith "SPLAT__"
[ Elm.Annotation.record
[ ( "splat"
, Elm.Annotation.list Elm.Annotation.string
)
]
]
)
2022-09-12 23:21:41 +03:00
, test "optional param" <|
\() ->
[ "Docs", "Section__" ]
|> expectRouteDefinition
(Elm.variantWith "Docs__Section__"
[ Elm.Annotation.record
[ ( "section"
, Elm.Annotation.maybe Elm.Annotation.string
)
]
]
)
2022-09-12 21:59:36 +03:00
]
2022-09-13 01:08:11 +03:00
, describe "toCase"
[ test "root route" <|
\() ->
2022-09-13 18:55:41 +03:00
[ "Index" ]
2022-09-13 01:08:11 +03:00
|> testCaseGenerator
[ ( Elm.CodeGen.listPattern []
, Elm.CodeGen.val "Index"
)
]
, test "dynamic segment" <|
\() ->
[ "User", "Id_" ]
|> testCaseGenerator
[ ( Elm.CodeGen.listPattern
[ Elm.CodeGen.stringPattern "user"
, Elm.CodeGen.varPattern "id"
]
, Elm.CodeGen.val "User__Id_ { id = id }"
)
]
2022-09-13 07:24:14 +03:00
, test "optional ending" <|
\() ->
[ "Docs", "Section__" ]
|> testCaseGenerator
[ ( Elm.CodeGen.listPattern
[ Elm.CodeGen.stringPattern "docs"
, Elm.CodeGen.varPattern "section"
]
, Elm.CodeGen.val "Docs__Section__ { section = Just section }"
)
, ( Elm.CodeGen.listPattern
[ Elm.CodeGen.stringPattern "docs"
]
, Elm.CodeGen.val "Docs__Section__ { section = Nothing }"
)
]
, test "required splat" <|
\() ->
[ "Username_", "Repo_", "Blob", "SPLAT_" ]
|> testCaseGenerator
[ ( --Elm. """username :: repo :: "blob" :: splatFirst :: splatRest"""
--( Elm.CodeGen.unConsPattern
unconsPattern
[ Elm.CodeGen.varPattern "username"
, Elm.CodeGen.varPattern "repo"
, Elm.CodeGen.stringPattern "blob"
, Elm.CodeGen.varPattern "splatFirst"
, Elm.CodeGen.varPattern "splatRest"
]
, Elm.CodeGen.val
"Username___Repo___Blob__SPLAT_ { username = username, repo = repo, splat = ( splatFirst, splatRest ) }"
)
]
2022-09-13 01:08:11 +03:00
]
, fuzz routeModuleNameFuzzer "to/from module name" <|
\moduleName ->
moduleName
|> RoutePattern.fromModuleName
|> Maybe.map RoutePattern.toModuleName
|> Expect.equal (Just moduleName)
]
routeModuleNameFuzzer : Fuzzer (List String)
routeModuleNameFuzzer =
Fuzz.oneOf
[ Fuzz.constant [ "Index" ]
, Fuzz.constant [ "User", "Id_" ]
2022-09-15 20:39:22 +03:00
, Fuzz.constant [ "Docs", "Section__" ]
]
unconsPattern : List Elm.CodeGen.Pattern -> Elm.CodeGen.Pattern
unconsPattern list =
case list of
[] ->
2022-09-13 18:50:24 +03:00
Elm.CodeGen.listPattern []
listFirst :: listRest ->
List.foldl
(\soFar item ->
soFar
|> Elm.CodeGen.unConsPattern item
)
listFirst
listRest
testCaseGenerator : List ( Elm.CodeGen.Pattern, Elm.CodeGen.Expression ) -> List String -> Expectation
2022-09-13 01:08:11 +03:00
testCaseGenerator expected moduleName =
RoutePattern.fromModuleName moduleName
|> Maybe.map (RoutePattern.routeToBranch >> List.map toStringCase)
|> Maybe.withDefault [ ( "<ERROR>", "<ERROR>" ) ]
|> Expect.equal (expected |> List.map toStringCase)
2022-09-13 01:08:11 +03:00
toStringCase : ( Elm.CodeGen.Pattern, Elm.CodeGen.Expression ) -> ( String, String )
2022-09-13 01:08:11 +03:00
toStringCase branch =
branch
|> Tuple.mapBoth
(Elm.Pretty.prettyPattern
>> Pretty.pretty 120
)
(Elm.Pretty.prettyExpression
>> Pretty.pretty 120
)
2022-09-13 01:08:11 +03:00
expectRouteDefinition : Elm.Variant -> List String -> Expectation
expectRouteDefinition expected moduleName =
RoutePattern.fromModuleName moduleName
|> Maybe.map (RoutePattern.toVariant >> toString)
|> Maybe.withDefault "<ERROR>"
|> Expect.equal (expected |> toString)
toString : Elm.Variant -> String
toString variants =
Elm.customType "Route" [ variants ]
|> Elm.ToString.declaration
|> .body