git.iko.soy/haskell-servant/servant-elm
on 98097b2 help sign in
.github/workflows/build.yamldeleted−41
since splitsnapshots
unifiedsplit
@@ -1,41 +0,0 @@
1−name: Haskell CI
2−
3−on:
4− push:
5− branches: [ "master" ]
6− pull_request:
7− branches: [ "master" ]
8−
9−permissions:
10− contents: read
11−
12−jobs:
13− build:
14−
15− runs-on: ubuntu-latest
16−
17− steps:
18− - uses: actions/checkout@v3
19−
20− - name: Install Nix
21− uses: cachix/install-nix-action@v20
22− with:
23− nix_path: nixpkgs=channel:nixos-unstable
24−
25− - name: Cache
26− uses: actions/cache@v3
27− env:
28− cache-name: cache-cabal
29− with:
30− path: ~/.stack
31− key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/*.cabal') }}-${{ hashFiles('**/stack.yaml') }}
32− restore-keys: |
33− ${{ runner.os }}-build-${{ env.cache-name }}-
34− ${{ runner.os }}-build-
35− ${{ runner.os }}-
36−
37− - name: Build
38− run: stack build --test --no-run-tests
39−
40− - name: Run tests
41− run: stack test
.gitignore−1
@@ -3,4 +3,3 @@ elm-stuff
3/_test-cache/
3/_test-cache/
4TAGS
4TAGS
5.dir-locals.el
5.dir-locals.el
6−stack.yaml.lock
CHANGELOG.md−20
@@ -1,23 +1,3 @@
1−0.7.2
2−-----
3−
4−* Commit a80f8b41d37d11778d2c27e6b38e881a71e85343. Fix for elm-bridge-0.6.0
5−
6−0.7.1
7−-----
8−
9−* PR #61. Improving support for polymorphic data types
10−
11−0.7.0
12−-----
13−
14−* PR #59. Using the appropriate toString functions for different types
15−
16−0.6.1
17−-----
18−
19−* PR #57. mkUrl: Use urlBase for Dynamic case
20−
210.6.0.2
10.6.0.2
22-------
2-------
23
3
README.md+8
@@ -61,6 +61,7 @@ Let's save this as `example.hs` and run it:
61```
61```
62$ stack runghc example.hs
62$ stack runghc example.hs
63Writing: my-elm-dir/Generated/MyApi.elm
63Writing: my-elm-dir/Generated/MyApi.elm
64+$
64```
65```
65
66
66Here's what was generated:
67Here's what was generated:
@@ -78,6 +79,13 @@ import Http
78import String
79import String
79import Url.Builder
80import Url.Builder
80
81
82+maybeBoolToIntStr : Maybe Bool -> String
83+maybeBoolToIntStr mx =
84+ case mx of
85+ Nothing -> ""
86+ Just True -> "1"
87+ Just False -> "0"
88+
81type alias Book =
89type alias Book =
82 { name: String
90 { name: String
83 }
91 }
examples/books/elm/Generated/BooksApi.elm+7
@@ -10,6 +10,13 @@ import Http
10import String
10import String
11import Url.Builder
11import Url.Builder
12
12
13+maybeBoolToIntStr : Maybe Bool -> String
14+maybeBoolToIntStr mx =
15+ case mx of
16+ Nothing -> ""
17+ Just True -> "1"
18+ Just False -> "0"
19+
13type alias Book =
20type alias Book =
14 { name: String
21 { name: String
15 }
22 }
examples/e2e-tests/elm/Generated/Api.elm+7
@@ -10,6 +10,13 @@ import Http
10import String
10import String
11import Url.Builder
11import Url.Builder
12
12
13+maybeBoolToIntStr : Maybe Bool -> String
14+maybeBoolToIntStr mx =
15+ case mx of
16+ Nothing -> ""
17+ Just True -> "1"
18+ Just False -> "0"
19+
13type alias MessageBody =
20type alias MessageBody =
14 { message: String
21 { message: String
15 }
22 }
examples/giphy/elm/Generated/GiphyApi.elm+7
@@ -10,6 +10,13 @@ import Http
10import String
10import String
11import Url.Builder
11import Url.Builder
12
12
13+maybeBoolToIntStr : Maybe Bool -> String
14+maybeBoolToIntStr mx =
15+ case mx of
16+ Nothing -> ""
17+ Just True -> "1"
18+ Just False -> "0"
19+
13type alias Gif =
20type alias Gif =
14 { data: GifData
21 { data: GifData
15 }
22 }
examples/readme-example/my-elm-dir/Generated/MyApi.elm+7
@@ -10,6 +10,13 @@ import Http
10import String
10import String
11import Url.Builder
11import Url.Builder
12
12
13+maybeBoolToIntStr : Maybe Bool -> String
14+maybeBoolToIntStr mx =
15+ case mx of
16+ Nothing -> ""
17+ Just True -> "1"
18+ Just False -> "0"
19+
13type alias Book =
20type alias Book =
14 { name: String
21 { name: String
15 }
22 }
servant-elm.cabal+2−3
@@ -1,5 +1,5 @@
1name: servant-elm
1name: servant-elm
2−version: 0.7.3
2+version: 0.6.0.2
3synopsis: Automatically derive Elm functions to query servant webservices.
3synopsis: Automatically derive Elm functions to query servant webservices.
4description: Please see README.md
4description: Please see README.md
5homepage: http://github.com/mattjbray/servant-elm#readme
5homepage: http://github.com/mattjbray/servant-elm#readme
@@ -34,7 +34,7 @@ library
34 build-depends: base >= 4.7 && < 5
34 build-depends: base >= 4.7 && < 5
35 , aeson >= 0.9
35 , aeson >= 0.9
36 , directory
36 , directory
37− , elm-bridge >= 0.5.2
37+ , elm-bridge >= 0.4
38 , lens
38 , lens
39 , servant >= 0.8
39 , servant >= 0.8
40 , servant-foreign >= 0.8
40 , servant-foreign >= 0.8
@@ -48,7 +48,6 @@ test-suite servant-elm-test
48 hs-source-dirs: test
48 hs-source-dirs: test
49 main-is: GenerateSpec.hs
49 main-is: GenerateSpec.hs
50 other-modules: Common
50 other-modules: Common
51− , PolymorphicData
52 build-depends:
51 build-depends:
53 Diff
52 Diff
54 , HUnit
53 , HUnit
src/Servant/Elm/Internal/Generate.hs+18−43
@@ -1,4 +1,3 @@
1−{-# LANGUAGE CPP #-}
2{-# LANGUAGE RecordWildCards #-}
1{-# LANGUAGE RecordWildCards #-}
3{-# LANGUAGE FlexibleContexts #-}
2{-# LANGUAGE FlexibleContexts #-}
4{-# LANGUAGE MultiParamTypeClasses #-}
3{-# LANGUAGE MultiParamTypeClasses #-}
@@ -20,11 +19,8 @@ import Elm.Json (jsonParserForType, jsonSerForType)
20import qualified Elm.Module as Elm
19import qualified Elm.Module as Elm
21import Elm.TyRep (ETCon(..), EType(..), ETypeDef(..), toElmType)
20import Elm.TyRep (ETCon(..), EType(..), ETypeDef(..), toElmType)
22import Elm.TyRender (renderElm)
21import Elm.TyRender (renderElm)
23−#if MIN_VERSION_elm_bridge(0,6,0)
24−import Elm.Versions (ElmVersion(Elm0p19))
25−#else
26import Elm.Versions (ElmVersion(Elm0p18))
22import Elm.Versions (ElmVersion(Elm0p18))
27−#endif
23+
28import Servant.Elm.Internal.Foreign (LangElm, getEndpoints)
24import Servant.Elm.Internal.Foreign (LangElm, getEndpoints)
29import qualified Servant.Foreign as F
25import qualified Servant.Foreign as F
30import System.Directory (createDirectoryIfMissing)
26import System.Directory (createDirectoryIfMissing)
@@ -53,22 +49,16 @@ data ElmOptions = ElmOptions
53 argument.
49 argument.
54 -}
50 -}
55 urlPrefix :: UrlPrefix
51 urlPrefix :: UrlPrefix
56− , elmTypeAlterations :: (EType -> EType)
52+ , elmTypeAlterations :: (EType -> EType)
57 -- ^ Alterations to perform on ETypes before code generation.
53 -- ^ Alterations to perform on ETypes before code generation.
58 , elmAlterations :: (ETypeDef -> ETypeDef)
54 , elmAlterations :: (ETypeDef -> ETypeDef)
59 -- ^ Alterations to perform on ETypeDefs before code generation.
55 -- ^ Alterations to perform on ETypeDefs before code generation.
60− , elmToString :: (EType -> Text)
56+ , elmToString :: (EType -> Text)
61 -- ^ Elm functions creating a string from a given type.
57 -- ^ Elm functions creating a string from a given type.
62 , emptyResponseElmTypes :: [EType]
58 , emptyResponseElmTypes :: [EType]
63 -- ^ Types that represent an empty Http response.
59 -- ^ Types that represent an empty Http response.
64 , stringElmTypes :: [EType]
60 , stringElmTypes :: [EType]
65 -- ^ Types that represent a String.
61 -- ^ Types that represent a String.
66− , expectJsonMethod :: Text
67− -- ^ The function to use for JSON responses.
68− , expectStringMethod :: Text
69− -- ^ The function to use for string responses.
70− , httpErrorType :: Text
71− -- ^ The type to use for Http errors.
72 }
62 }
73
63
74
64
@@ -92,9 +82,6 @@ The default options are:
92> , stringElmTypes =
82> , stringElmTypes =
93> [ getType (Proxy :: Proxy String)
83> [ getType (Proxy :: Proxy String)
94> , getType (Proxy :: Proxy T.Text) ]
84> , getType (Proxy :: Proxy T.Text) ]
95−> , expectJsonMethod = "Http.expectJson"
96−> , expectStringMethod = "Http.expectString"
97−> , httpErrorType = "Http.Error"
98> }
85> }
99-}
86-}
100defElmOptions :: ElmOptions
87defElmOptions :: ElmOptions
@@ -110,9 +97,6 @@ defElmOptions = ElmOptions
110 [ toElmType (Proxy :: Proxy String)
97 [ toElmType (Proxy :: Proxy String)
111 , toElmType (Proxy :: Proxy T.Text)
98 , toElmType (Proxy :: Proxy T.Text)
112 ]
99 ]
113− , expectJsonMethod = "Http.expectJson"
114− , expectStringMethod = "Http.expectString"
115− , httpErrorType = "Http.Error"
116 }
100 }
117
101
118
102
@@ -131,7 +115,6 @@ The default required imports are:
131> import Set
115> import Set
132> import Http
116> import Http
133> import String
117> import String
134−> import Url
135> import Url.Builder
118> import Url.Builder
136-}
119-}
137defElmImports :: Text
120defElmImports :: Text
@@ -145,7 +128,6 @@ defElmImports =
145 , "import Set"
128 , "import Set"
146 , "import Http"
129 , "import Http"
147 , "import String"
130 , "import String"
148− , "import Url"
149 , "import Url.Builder"
131 , "import Url.Builder"
150 ]
132 ]
151
133
@@ -167,12 +149,7 @@ generateElmModuleWith ::
167generateElmModuleWith options namespace imports rootDir typeDefs api = do
149generateElmModuleWith options namespace imports rootDir typeDefs api = do
168 let out =
150 let out =
169 T.unlines $
151 T.unlines $
170− [
171−#if MIN_VERSION_elm_bridge(0,6,0)
172− T.pack $ Elm.moduleHeader Elm0p19 moduleName
173−#else
174− T.pack $ Elm.moduleHeader Elm0p18 moduleName
152+ [ T.pack $ Elm.moduleHeader Elm0p18 moduleName
175−#endif
176 , ""
153 , ""
177 , imports
154 , imports
178 , T.pack $ Elm.makeModuleContentWithAlterations (elmAlterations options) typeDefs
155 , T.pack $ Elm.makeModuleContentWithAlterations (elmAlterations options) typeDefs
@@ -259,7 +236,7 @@ generateElmForRequest opts request =
259 fnName =
236 fnName =
260 request ^. F.reqFuncName . to (replace . F.camelCase) . to stext
237 request ^. F.reqFuncName . to (replace . F.camelCase) . to stext
261
238
262− replace = T.replace "-" "" . T.replace "." "" . T.replace " " ""
239+ replace = T.replace "-" "" . T.replace "." ""
263
240
264 typeSignature =
241 typeSignature =
265 mkTypeSignature opts request
242 mkTypeSignature opts request
@@ -321,7 +298,7 @@ mkTypeSignature opts request =
321 toMsgType :: Maybe Doc
298 toMsgType :: Maybe Doc
322 toMsgType = do
299 toMsgType = do
323 result <- fmap elmTypeRef $ request ^. F.reqReturnType
300 result <- fmap elmTypeRef $ request ^. F.reqReturnType
324− Just ("(Result" <+> stext (httpErrorType opts) <+> parens result <+> "-> msg)")
301+ Just ("(Result Http.Error " <+> parens result <+> " -> msg)")
325
302
326 returnType :: Maybe Doc
303 returnType :: Maybe Doc
327 returnType = do
304 returnType = do
@@ -339,7 +316,7 @@ elmCaptureArg segment =
339 "capture_" <>
316 "capture_" <>
340 F.captureArg segment ^. F.argName . to (stext . replace . F.unPathSegment)
317 F.captureArg segment ^. F.argName . to (stext . replace . F.unPathSegment)
341 where
318 where
342− replace = T.replace "-" "_" . T.replace " " "_"
319+ replace = T.replace "-" "_"
343
320
344
321
345elmQueryArg :: F.QueryArg EType -> Doc
322elmQueryArg :: F.QueryArg EType -> Doc
@@ -443,7 +420,7 @@ mkLetParams opts request =
443 , "Just"
420 , "Just"
444 ]
421 ]
445 )
422 )
446−
423+
447 where
424 where
448 elmName = elmQueryArg qarg
425 elmName = elmQueryArg qarg
449 name = qarg ^. F.queryArgName . F.argName . to (stext . F.unPathSegment)
426 name = qarg ^. F.queryArgName . F.argName . to (stext . F.unPathSegment)
@@ -510,14 +487,14 @@ mkRequest opts request =
510 expect =
487 expect =
511 case request ^. F.reqReturnType of
488 case request ^. F.reqReturnType of
512 Just elmTypeExpr
489 Just elmTypeExpr
513− | isEmptyType opts $ (elmTypeAlterations opts) elmTypeExpr
490+ | isEmptyType opts elmTypeExpr
514 -- let elmConstructor = T.pack (renderElm elmTypeExpr)
491 -- let elmConstructor = T.pack (renderElm elmTypeExpr)
515 ->
492 ->
516− stext (expectStringMethod opts) <> line <+> indent i "(\\x -> case x of" <> line <+>
493+ "Http.expectString " <> line <+> indent i "(\\x -> case x of" <> line <+>
517 indent i "Err e -> toMsg (Err e)" <> line <+>
494 indent i "Err e -> toMsg (Err e)" <> line <+>
518 indent i "Ok _ -> toMsg (Ok ()))"
495 indent i "Ok _ -> toMsg (Ok ()))"
519 Just elmTypeExpr ->
496 Just elmTypeExpr ->
520− stext (expectJsonMethod opts) <+> "toMsg" <+> renderDecoderName ((elmTypeAlterations opts) elmTypeExpr)
497+ "Http.expectJson toMsg" <+> renderDecoderName elmTypeExpr
521 Nothing -> error "mkHttpRequest: no reqReturnType?"
498 Nothing -> error "mkHttpRequest: no reqReturnType?"
522 -- case request ^. F.reqReturnType of
499 -- case request ^. F.reqReturnType of
523 -- Just elmTypeExpr | isEmptyType opts elmTypeExpr ->
500 -- Just elmTypeExpr | isEmptyType opts elmTypeExpr ->
@@ -545,8 +522,6 @@ renderDecoderName elmTypeExpr =
545 parens ("Json.Decode.list " <> parens (renderDecoderName t))
522 parens ("Json.Decode.list " <> parens (renderDecoderName t))
546 ETyApp (ETyCon (ETCon "Maybe")) t ->
523 ETyApp (ETyCon (ETCon "Maybe")) t ->
547 parens ("Json.Decode.maybe " <> parens (renderDecoderName t))
524 parens ("Json.Decode.maybe " <> parens (renderDecoderName t))
548− ETyApp x y ->
549− parens (renderDecoderName x <+> renderDecoderName y)
550 ETyCon (ETCon "Int") -> "Json.Decode.int"
525 ETyCon (ETCon "Int") -> "Json.Decode.int"
551 ETyCon (ETCon "String") -> "Json.Decode.string"
526 ETyCon (ETCon "String") -> "Json.Decode.string"
552 _ -> ("jsonDec" <> stext (T.pack (renderElm elmTypeExpr)))
527 _ -> ("jsonDec" <> stext (T.pack (renderElm elmTypeExpr)))
@@ -564,7 +539,7 @@ mkUrl opts segments =
564 where
539 where
565 urlBuilder :: Doc
540 urlBuilder :: Doc
566 urlBuilder = case urlPrefix opts of
541 urlBuilder = case urlPrefix opts of
567− Dynamic -> "Url.Builder.crossOrigin urlBase" :: Doc
542+ Dynamic -> "Url.Builder.absolute" :: Doc
568 Static url -> "Url.Builder.crossOrigin" <+> dquotes (stext url)
543 Static url -> "Url.Builder.crossOrigin" <+> dquotes (stext url)
569
544
570 segmentToDoc :: F.Segment EType -> Doc
545 segmentToDoc :: F.Segment EType -> Doc
@@ -574,10 +549,10 @@ mkUrl opts segments =
574 dquotes (stext (F.unPathSegment path))
549 dquotes (stext (F.unPathSegment path))
575 F.Cap arg ->
550 F.Cap arg ->
576 let
551 let
577− toStringSrc =
552+ toStringSrc =
578− toString opts (elmTypeAlterations opts (maybeOf (arg ^. F.argType)))
553+ toString opts (maybeOf (arg ^. F.argType))
579 in
554 in
580− "Url.percentEncode " <> pipeRight [elmCaptureArg s, toStringSrc]
555+ pipeRight [elmCaptureArg s, toStringSrc]
581
556
582
557
583mkQueryParams
558mkQueryParams
@@ -595,7 +570,7 @@ response body.
595-}
570-}
596isEmptyType :: ElmOptions -> EType -> Bool
571isEmptyType :: ElmOptions -> EType -> Bool
597isEmptyType opts elmTypeExpr =
572isEmptyType opts elmTypeExpr =
598− (elmTypeAlterations opts elmTypeExpr) `elem` emptyResponseElmTypes opts
573+ elmTypeExpr `elem` emptyResponseElmTypes opts
599
574
600
575
601{- | Determines whether we call `toString` on URL captures and query params of
576{- | Determines whether we call `toString` on URL captures and query params of
@@ -603,7 +578,7 @@ this type in Elm.
603-}
578-}
604isElmStringType :: ElmOptions -> EType -> Bool
579isElmStringType :: ElmOptions -> EType -> Bool
605isElmStringType opts elmTypeExpr =
580isElmStringType opts elmTypeExpr =
606− (elmTypeAlterations opts elmTypeExpr) `elem` stringElmTypes opts
581+ elmTypeExpr `elem` stringElmTypes opts
607
582
608{- | Determines whether a type is 'Maybe a' where 'a' is something akin to a 'String'.
583{- | Determines whether a type is 'Maybe a' where 'a' is something akin to a 'String'.
609-}
584-}
@@ -645,7 +620,7 @@ elmListOfMaybes ds = "List.filterMap identity" <$> indent 4 (elmList ds)
645defaultElmToString :: EType -> Text
620defaultElmToString :: EType -> Text
646defaultElmToString argType =
621defaultElmToString argType =
647 case argType of
622 case argType of
648− ETyCon (ETCon "Bool") -> "(\\value -> if value then \"true\" else \"false\")"
623+ ETyCon (ETCon "Bool") -> "(\\value -> if value then \"1\" else \"0\")"
649 ETyCon (ETCon "Float") -> "String.fromFloat"
624 ETyCon (ETCon "Float") -> "String.fromFloat"
650 ETyCon (ETCon "Char") -> "String.fromChar"
625 ETyCon (ETCon "Char") -> "String.fromChar"
651 ETyApp (ETyCon (ETCon "Maybe")) v -> "(Maybe.map " <> defaultElmToString v <> " >> Maybe.withDefault \"\")"
626 ETyApp (ETyCon (ETCon "Maybe")) v -> "(Maybe.map " <> defaultElmToString v <> " >> Maybe.withDefault \"\")"
stack.yaml+29−5
@@ -1,9 +1,33 @@
1+# For more information, see: https://github.com/commercialhaskell/stack/blob/release/doc/yaml_configuration.md
2+
3+# Specifies the GHC version and set of packages available (e.g., lts-3.5, nightly-2015-09-21, ghc-7.10.2)
1−resolver: lts-20.11
4+resolver: lts-13.15
5+
6+# Local packages, usually specified by relative directory name
2packages:
7packages:
3- '.'
8- '.'
9+
10+# Packages to be pulled from upstream that are not in the resolver (e.g., acme-missiles-0.3)
11+extra-deps:
12+- elm-bridge-0.5.1@sha256:e38bfb9dcd1e2cd119a280072f2f99ed718120c21f37f102b8318156645f06da
13+
14+# Override default flag values for local packages and extra-deps
4flags: {}
15flags: {}
16+
17+# Extra package databases containing global packages
5extra-package-dbs: []
18extra-package-dbs: []
6−nix:
19+
7− enable: true
20+# Control whether we use the GHC we find on the path
8− packages:
21+# system-ghc: true
9− - zlib
22+
23+# Require a specific version of stack, using version ranges
24+# require-stack-version: -any # Default
25+# require-stack-version: >= 0.1.4.0
26+
27+# Override the architecture used by stack, especially useful on Windows
28+# arch: i386
29+# arch: x86_64
30+
31+# Extra directories used by stack for building
32+# extra-include-dirs: [/path/to/dir]
33+# extra-lib-dirs: [/path/to/dir]
test/Common.hs+5−7
@@ -5,9 +5,9 @@ module Common where
5
5
6import Data.Proxy (Proxy (Proxy))
6import Data.Proxy (Proxy (Proxy))
7import Data.Text (Text)
7import Data.Text (Text)
8−import Servant.API ((:<|>), (:>), Capture, Get, Header,
8+import Servant.API ((:<|>), (:>), Capture, Get, GetNoContent, Header,
9 Header', Headers, JSON, Post,
9 Header', Headers, JSON, Post,
10− Put, QueryFlag, QueryParam,
10+ PostNoContent, Put, QueryFlag, QueryParam,
11 QueryParam', QueryParams, ReqBody, Required)
11 QueryParam', QueryParams, ReqBody, Required)
12import Servant.Elm (deriveBoth, defaultOptions)
12import Servant.Elm (deriveBoth, defaultOptions)
13
13
@@ -27,7 +27,7 @@ type TestApi =
27 :> Capture "id" Int
27 :> Capture "id" Int
28 :> Get '[JSON] Book
28 :> Get '[JSON] Book
29 :<|> "books"
29 :<|> "books"
30− :> Capture "title space" Text
30+ :> Capture "title" Text
31 :> Get '[JSON] Book
31 :> Get '[JSON] Book
32 :<|> "books"
32 :<|> "books"
33 :> QueryFlag "published"
33 :> QueryFlag "published"
@@ -38,11 +38,9 @@ type TestApi =
38 :> Get '[JSON] [Book]
38 :> Get '[JSON] [Book]
39 :<|> "books"
39 :<|> "books"
40 :> ReqBody '[JSON] Book
40 :> ReqBody '[JSON] Book
41− -- :> PostNoContent '[JSON] ()
41+ :> PostNoContent '[JSON] ()
42− :> Post '[JSON] ()
43 :<|> "nothing"
42 :<|> "nothing"
44− :> Get '[JSON] ()
45− -- :> GetNoContent '[JSON] ()
43+ :> GetNoContent '[JSON] ()
46 :<|> "nothing"
44 :<|> "nothing"
47 :> Put '[JSON] () -- old way to specify no content
45 :> Put '[JSON] () -- old way to specify no content
48 :<|> "with-a-header"
46 :<|> "with-a-header"
test/CompileSpec.hs+1−1
@@ -45,7 +45,7 @@ spec = do
45 api = (Proxy :: Proxy TestApi)
45 api = (Proxy :: Proxy TestApi)
46 let out =
46 let out =
47 T.unlines $
47 T.unlines $
48− [ T.pack $ Elm.moduleHeader Elm0p19 moduleName
48+ [ T.pack $ Elm.moduleHeader Elm0p18 moduleName
49 , ""
49 , ""
50 , imports
50 , imports
51 , ""
51 , ""
test/GenerateSpec.hs+2−27
@@ -18,14 +18,13 @@ import Test.Hspec (Spec, describe, hspec, it)
18import Test.HUnit (Assertion, assertEqual)
18import Test.HUnit (Assertion, assertEqual)
19
19
20import Common (testApi)
20import Common (testApi)
21−import PolymorphicData (SomeRecord(..), PolymorphicData(..))
22
21
23
22
24main :: IO ()
23main :: IO ()
25main = hspec spec
24main = hspec spec
26
25
27spec :: Test.Hspec.Spec
26spec :: Test.Hspec.Spec
28−spec =
27+spec = do
29 describe "encoding a simple api" $
28 describe "encoding a simple api" $
30 do it "does it" $
29 do it "does it" $
31 do expected <-
30 do expected <-
@@ -123,30 +122,6 @@ spec =
123 })
122 })
124 (Proxy :: Proxy ("one" :> Get '[JSON] Int)))
123 (Proxy :: Proxy ("one" :> Get '[JSON] Int)))
125 generated `itemsShouldBe` expected
124 generated `itemsShouldBe` expected
126− it "works with polymorphic data" $
127− do expected <-
128− mapM
129− (\(fpath, header) -> do
130− source <- T.readFile fpath
131− return (fpath, header, source))
132− [ ( "test/elm-sources/getPolymorphicData.elm"
133− , "module GetPolymorphicData exposing (..)\n\n" <>
134− "import Http\n" <>
135− "import Json.Decode exposing (..)\n" <>
136− "import Url.Builder\n\n" <>
137− "type PolymorphicData a b = PolymorphicData a b\n" <>
138− "type SomeRecord = SomeRecord { recordId : Int, recordname : String }\n\n" <>
139− "jsonDecPolymorphicData : Json.Decode.Decoder a -> Json.Decode.Decoder b -> Json.Decode.Decoder (PolymorphicData a b)\n"<>
140− "jsonDecPolymorphicData _ _ = Debug.todo \"finish\"\n\n" <>
141− "jsonDecSomeRecord : Json.Decode.Decoder SomeRecord\n"<>
142− "jsonDecSomeRecord = Debug.todo \"finish\"\n\n\n")]
143− let generated =
144− map
145− (<> "\n")
146− (generateElmForAPIWith
147− defElmOptions
148− (Proxy :: Proxy ( "polymorphicData" :> Get '[JSON] (PolymorphicData [String] SomeRecord))))
149− generated `itemsShouldBe` expected
150
125
151itemsShouldBe :: [Text] -> [(String, Text, Text)] -> IO ()
126itemsShouldBe :: [Text] -> [(String, Text, Text)] -> IO ()
152itemsShouldBe actual expected =
127itemsShouldBe actual expected =
@@ -163,7 +138,7 @@ shouldBeDiff a (fpath,header,b) =
163 (Diff.getGroupedDiff
138 (Diff.getGroupedDiff
164 (lines (T.unpack actual))
139 (lines (T.unpack actual))
165 (lines (T.unpack expected))))
140 (lines (T.unpack expected))))
166− expected actual
141+ actual expected
167 where
142 where
168 actual = T.strip $ header <> a
143 actual = T.strip $ header <> a
169 expected = T.strip b
144 expected = T.strip b
test/PolymorphicData.hsdeleted−15
@@ -1,15 +0,0 @@
1−{-# LANGUAGE TemplateHaskell #-}
2−
3−module PolymorphicData where
4−
5−import Servant.Elm
6−
7−
8−data PolymorphicData a b = PolymorphicData a b deriving (Show, Eq)
9−data SomeRecord = SomeRecord
10− { recordId :: Int
11− , recordName :: String
12− } deriving (Show, Eq)
13−
14−deriveBoth defaultOptions ''PolymorphicData
15−deriveBoth defaultOptions ''SomeRecord
test/elm-sources/getBooksByIdSource.elm+2−3
@@ -8,7 +8,7 @@ type Book = Book
8jsonDecBook : Json.Decode.Decoder Book
8jsonDecBook : Json.Decode.Decoder Book
9jsonDecBook = Debug.todo ""
9jsonDecBook = Debug.todo ""
10
10
11−getBooksById : Int -> (Result Http.Error (Book) -> msg) -> Cmd msg
11+getBooksById : Int -> (Result Http.Error (Book) -> msg) -> Cmd msg
12getBooksById capture_id toMsg =
12getBooksById capture_id toMsg =
13 let
13 let
14 params =
14 params =
@@ -24,8 +24,7 @@ getBooksById capture_id toMsg =
24 , url =
24 , url =
25 Url.Builder.crossOrigin ""
25 Url.Builder.crossOrigin ""
26 [ "books"
26 [ "books"
27− , Url.percentEncode (capture_id
28− |> String.fromInt)
27+ , (capture_id |> String.fromInt)
29 ]
28 ]
30 params
29 params
31 , body =
30 , body =
test/elm-sources/getBooksByTitleSource.elm+3−3
@@ -7,8 +7,8 @@ import Json.Decode as J
7type alias Book = {}
7type alias Book = {}
8jsonDecBook = J.succeed {}
8jsonDecBook = J.succeed {}
9
9
10−getBooksByTitlespace : String -> (Result Http.Error (Book) -> msg) -> Cmd msg
10+getBooksByTitle : String -> (Result Http.Error (Book) -> msg) -> Cmd msg
11−getBooksByTitlespace capture_title_space toMsg =
11+getBooksByTitle capture_title toMsg =
12 let
12 let
13 params =
13 params =
14 List.filterMap identity
14 List.filterMap identity
@@ -23,7 +23,7 @@ getBooksByTitlespace capture_title_space toMsg =
23 , url =
23 , url =
24 Url.Builder.crossOrigin ""
24 Url.Builder.crossOrigin ""
25 [ "books"
25 [ "books"
26− , Url.percentEncode (capture_title_space)
26+ , (capture_title)
27 ]
27 ]
28 params
28 params
29 , body =
29 , body =
test/elm-sources/getBooksSource.elm+2−2
@@ -9,7 +9,7 @@ type alias Book = {}
9
9
10jsonDecBook = J.succeed {}
10jsonDecBook = J.succeed {}
11
11
12−getBooks : Bool -> (Maybe String) -> (Maybe Int) -> String -> (List (Maybe Bool)) -> (Result Http.Error ((List Book)) -> msg) -> Cmd msg
12+getBooks : Bool -> (Maybe String) -> (Maybe Int) -> String -> (List (Maybe Bool)) -> (Result Http.Error ((List Book)) -> msg) -> Cmd msg
13getBooks query_published query_sort query_year query_category query_filters toMsg =
13getBooks query_published query_sort query_year query_category query_filters toMsg =
14 let
14 let
15 params =
15 params =
@@ -27,7 +27,7 @@ getBooks query_published query_sort query_year query_category query_filters toMs
27 , [ Just query_category
27 , [ Just query_category
28 |> Maybe.map (Url.Builder.string "category") ]
28 |> Maybe.map (Url.Builder.string "category") ]
29 , query_filters
29 , query_filters
30− |> List.map ((Maybe.map (\value -> if value then "true" else "false") >> Maybe.withDefault "")
30+ |> List.map ((Maybe.map (\value -> if value then "1" else "0") >> Maybe.withDefault "")
31 >> Url.Builder.string "filters[]"
31 >> Url.Builder.string "filters[]"
32 >> Just)
32 >> Just)
33 ])
33 ])
test/elm-sources/getNothingSource.elm+2−2
@@ -4,7 +4,7 @@ import Http
4import Url.Builder
4import Url.Builder
5
5
6
6
7−getNothing : (Result Http.Error (()) -> msg) -> Cmd msg
7+getNothing : (Result Http.Error (()) -> msg) -> Cmd msg
8getNothing toMsg =
8getNothing toMsg =
9 let
9 let
10 params =
10 params =
@@ -25,7 +25,7 @@ getNothing toMsg =
25 , body =
25 , body =
26 Http.emptyBody
26 Http.emptyBody
27 , expect =
27 , expect =
28− Http.expectString
28+ Http.expectString
29 (\x -> case x of
29 (\x -> case x of
30 Err e -> toMsg (Err e)
30 Err e -> toMsg (Err e)
31 Ok _ -> toMsg (Ok ()))
31 Ok _ -> toMsg (Ok ()))
test/elm-sources/getOneSource.elm+1−1
@@ -5,7 +5,7 @@ import Json.Decode exposing (..)
5import Url.Builder
5import Url.Builder
6
6
7
7
8−getOne : (Result Http.Error (Int) -> msg) -> Cmd msg
8+getOne : (Result Http.Error (Int) -> msg) -> Cmd msg
9getOne toMsg =
9getOne toMsg =
10 let
10 let
11 params =
11 params =
test/elm-sources/getOneWithDynamicUrlSource.elm+2−2
@@ -5,7 +5,7 @@ import Url.Builder
5import Json.Decode exposing (..)
5import Json.Decode exposing (..)
6
6
7
7
8−getOne : String -> (Result Http.Error (Int) -> msg) -> Cmd msg
8+getOne : String -> (Result Http.Error (Int) -> msg) -> Cmd msg
9getOne urlBase toMsg =
9getOne urlBase toMsg =
10 let
10 let
11 params =
11 params =
@@ -19,7 +19,7 @@ getOne urlBase toMsg =
19 , headers =
19 , headers =
20 []
20 []
21 , url =
21 , url =
22− Url.Builder.crossOrigin urlBase
22+ Url.Builder.absolute
23 [ "one"
23 [ "one"
24 ]
24 ]
25 params
25 params
test/elm-sources/getPolymorphicData.elmdeleted−43
@@ -1,43 +0,0 @@
1−module GetPolymorphicData exposing (..)
2−
3−import Http
4−import Json.Decode exposing (..)
5−import Url.Builder
6−
7−type PolymorphicData a b = PolymorphicData a b
8−type SomeRecord = SomeRecord { recordId : Int, recordname : String }
9−
10−jsonDecPolymorphicData : Json.Decode.Decoder a -> Json.Decode.Decoder b -> Json.Decode.Decoder (PolymorphicData a b)
11−jsonDecPolymorphicData _ _ = Debug.todo "finish"
12−
13−jsonDecSomeRecord : Json.Decode.Decoder SomeRecord
14−jsonDecSomeRecord = Debug.todo "finish"
15−
16−
17−getPolymorphicData : (Result Http.Error ((PolymorphicData (List String) SomeRecord)) -> msg) -> Cmd msg
18−getPolymorphicData toMsg =
19− let
20− params =
21− List.filterMap identity
22− (List.concat
23− [])
24− in
25− Http.request
26− { method =
27− "GET"
28− , headers =
29− []
30− , url =
31− Url.Builder.crossOrigin ""
32− [ "polymorphicData"
33− ]
34− params
35− , body =
36− Http.emptyBody
37− , expect =
38− Http.expectJson toMsg ((jsonDecPolymorphicData (Json.Decode.list (Json.Decode.string))) jsonDecSomeRecord)
39− , timeout =
40− Nothing
41− , tracker =
42− Nothing
43− }
test/elm-sources/getWithaheaderSource.elm+1−1
@@ -5,7 +5,7 @@ import Url.Builder
5import Json.Decode exposing (..)
5import Json.Decode exposing (..)
6
6
7
7
8−getWithaheader : (Maybe String) -> (Maybe Int) -> String -> Int -> (Result Http.Error (String) -> msg) -> Cmd msg
8+getWithaheader : (Maybe String) -> (Maybe Int) -> String -> Int -> (Result Http.Error (String) -> msg) -> Cmd msg
9getWithaheader header_myStringHeader header_MyIntHeader header_MyRequiredStringHeader header_MyRequiredIntHeader toMsg =
9getWithaheader header_myStringHeader header_MyIntHeader header_MyRequiredStringHeader header_MyRequiredIntHeader toMsg =
10 let
10 let
11 params =
11 params =
test/elm-sources/getWitharesponseheaderSource.elm+1−1
@@ -5,7 +5,7 @@ import Url.Builder
5import Json.Decode exposing (..)
5import Json.Decode exposing (..)
6
6
7
7
8−getWitharesponseheader : (Result Http.Error (String) -> msg) -> Cmd msg
8+getWitharesponseheader : (Result Http.Error (String) -> msg) -> Cmd msg
9getWitharesponseheader toMsg =
9getWitharesponseheader toMsg =
10 let
10 let
11 params =
11 params =
test/elm-sources/postBooksSource.elm+2−2
@@ -7,7 +7,7 @@ import Json.Encode as Enc
7type alias Book = {}
7type alias Book = {}
8jsonEncBook = \b -> Enc.object []
8jsonEncBook = \b -> Enc.object []
9
9
10−postBooks : Book -> (Result Http.Error (()) -> msg) -> Cmd msg
10+postBooks : Book -> (Result Http.Error (()) -> msg) -> Cmd msg
11postBooks body toMsg =
11postBooks body toMsg =
12 let
12 let
13 params =
13 params =
@@ -28,7 +28,7 @@ postBooks body toMsg =
28 , body =
28 , body =
29 Http.jsonBody (jsonEncBook body)
29 Http.jsonBody (jsonEncBook body)
30 , expect =
30 , expect =
31− Http.expectString
31+ Http.expectString
32 (\x -> case x of
32 (\x -> case x of
33 Err e -> toMsg (Err e)
33 Err e -> toMsg (Err e)
34 Ok _ -> toMsg (Ok ()))
34 Ok _ -> toMsg (Ok ()))
test/elm-sources/postTwoSource.elm+1−1
@@ -6,7 +6,7 @@ import Json.Encode
6import Url.Builder
6import Url.Builder
7
7
8
8
9−postTwo : String -> (Result Http.Error ((Maybe Int)) -> msg) -> Cmd msg
9+postTwo : String -> (Result Http.Error ((Maybe Int)) -> msg) -> Cmd msg
10postTwo body toMsg =
10postTwo body toMsg =
11 let
11 let
12 params =
12 params =
test/elm-sources/putNothingSource.elm+2−2
@@ -4,7 +4,7 @@ import Http
4import Url.Builder
4import Url.Builder
5
5
6
6
7−putNothing : (Result Http.Error (()) -> msg) -> Cmd msg
7+putNothing : (Result Http.Error (()) -> msg) -> Cmd msg
8putNothing toMsg =
8putNothing toMsg =
9 let
9 let
10 params =
10 params =
@@ -25,7 +25,7 @@ putNothing toMsg =
25 , body =
25 , body =
26 Http.emptyBody
26 Http.emptyBody
27 , expect =
27 , expect =
28− Http.expectString
28+ Http.expectString
29 (\x -> case x of
29 (\x -> case x of
30 Err e -> toMsg (Err e)
30 Err e -> toMsg (Err e)
31 Ok _ -> toMsg (Ok ()))
31 Ok _ -> toMsg (Ok ()))