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