wireform-derive-0.2.0.0: test/Test/Derive/Modifier.hs
{-# LANGUAGE OverloadedStrings #-}
module Test.Derive.Modifier (tests) where
import Data.Map.Strict qualified as Map
import Test.Syd
import Wireform.Derive.Backend
import Wireform.Derive.Modifier
import Wireform.Derive.ModifierInfo
import Wireform.Derive.NameStyle
tests :: Spec
tests =
describe "Modifier" $
sequence_
[ describe "foldModifiers — happy path" $
sequence_
[ it "empty input gives empty info" $
foldModifiers backendJSON [] `shouldBe` Right (emptyModifierInfo backendJSON)
, it "single rename" $
fmap miRename (foldModifiers backendJSON [rename "name"])
`shouldBe` Right (Just (RenameSpecLiteral "name"))
, it "duplicate identical rename is no conflict" $
fmap
miRename
( foldModifiers
backendJSON
[rename "name", rename "name"]
)
`shouldBe` Right (Just (RenameSpecLiteral "name"))
, it "skip flag" $
fmap miSkip (foldModifiers backendJSON [skip])
`shouldBe` Right True
, it "tag set" $
fmap miTag (foldModifiers backendJSON [tag 7])
`shouldBe` Right (Just 7)
, it "required + only set once" $
fmap miRequired (foldModifiers backendJSON [required])
`shouldBe` Right (Just True)
, it "optional + only set once" $
fmap miRequired (foldModifiers backendJSON [optional])
`shouldBe` Right (Just False)
]
, describe "foldModifiers — conflicts" $
sequence_
[ it "two distinct renames conflict" $ do
let r =
foldModifiers
backendJSON
[rename "a", rename "b"]
case r of
Left ConflictRename {} -> pure ()
other -> expectationFailure ("expected ConflictRename, got " ++ show other)
, it "two distinct tags conflict" $ do
let r = foldModifiers backendJSON [tag 1, tag 2]
case r of
Left ConflictTag {} -> pure ()
other -> expectationFailure ("expected ConflictTag, got " ++ show other)
, it "required + optional conflict" $ do
let r = foldModifiers backendJSON [required, optional]
case r of
Left ConflictRequired {} -> pure ()
other -> expectationFailure ("expected ConflictRequired, got " ++ show other)
, it "flatten + skip conflict" $ do
let r = foldModifiers backendJSON [flatten, skip]
case r of
Left ConflictFlattenSkip -> pure ()
other -> expectationFailure ("expected ConflictFlattenSkip, got " ++ show other)
]
, describe "per-backend overrides" $
sequence_
[ it "backend-only modifier applies for active backend" $
fmap
miRename
( foldModifiers
backendProto
[forBackend backendProto (rename "n")]
)
`shouldBe` Right (Just (RenameSpecLiteral "n"))
, it "backend-only modifier ignored for other backend" $
fmap
miRename
( foldModifiers
backendJSON
[forBackend backendProto (rename "n")]
)
`shouldBe` Right Nothing
, it "per-backend rename shadows global, no conflict" $
fmap
miRename
( foldModifiers
backendProto
[ rename "global"
, forBackend backendProto (rename "scoped")
]
)
`shouldBe` Right (Just (RenameSpecLiteral "scoped"))
, it "per-backend rename does not shadow on other backend" $
fmap
miRename
( foldModifiers
backendJSON
[ rename "global"
, forBackend backendProto (rename "scoped")
]
)
`shouldBe` Right (Just (RenameSpecLiteral "global"))
, it "disableFor on active backend marks skip" $
fmap
miSkip
( foldModifiers
backendCBOR
[disableFor [backendCBOR, backendMsgPack]]
)
`shouldBe` Right True
, it "disableFor on other backend has no effect" $
fmap
miSkip
( foldModifiers
backendJSON
[disableFor [backendCBOR, backendMsgPack]]
)
`shouldBe` Right False
, it "forBackends groups multiple modifiers" $ do
let mi =
foldModifiers
backendProto
[forBackends [backendProto] [rename "p", tag 9]]
fmap miRename mi `shouldBe` Right (Just (RenameSpecLiteral "p"))
fmap miTag mi `shouldBe` Right (Just 9)
, it "forBackends does nothing for unlisted backend" $
fmap
miRename
( foldModifiers
backendJSON
[forBackends [backendProto] [rename "p"]]
)
`shouldBe` Right Nothing
]
, describe "RenameSpec variants" $
sequence_
[ it "rename literal" $
fmap miRename (foldModifiers backendJSON [rename "n"])
`shouldBe` Right (Just (RenameSpecLiteral "n"))
, it "renameStyle preserved" $
fmap
miRename
( foldModifiers
backendJSON
[renameStyle (StripPrefix "person")]
)
`shouldBe` Right (Just (RenameSpecStyle (StripPrefix "person")))
]
, describe "default rename keys" $
sequence_
[ it
"JSON default is camel"
(defaultRenameForBackend backendJSON "person_name" `shouldBe` "personName")
, it
"EDN default is kebab"
(defaultRenameForBackend backendEDN "personName" `shouldBe` "person-name")
, it
"CBOR default is verbatim"
(defaultRenameForBackend backendCBOR "personName" `shouldBe` "personName")
]
, describe "ModCustom accumulation" $
sequence_
[ it "two custom payloads with same tag accumulate" $ do
let mi =
foldModifiers
backendCBOR
[ customModifier "ext.foo" "x"
, customModifier "ext.foo" "y"
]
case mi of
Right info -> do
let xs = Map.findWithDefault [] "ext.foo" (miCustom info)
length xs `shouldBe` 2
Left e -> expectationFailure ("unexpected " ++ show e)
, it "custom payloads with different tags don't conflict" $ do
let mi =
foldModifiers
backendCBOR
[ customModifier "ext.foo" "x"
, customModifier "ext.bar" "y"
]
case mi of
Right info -> do
(Map.member "ext.foo" (miCustom info)) `shouldBe` True
(Map.member "ext.bar" (miCustom info)) `shouldBe` True
Left e -> expectationFailure ("unexpected " ++ show e)
]
]