wireform-derive-0.1.0.0: test/Test/Derive/Extension.hs
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeApplications #-}
-- | Round-trip tests for 'Wireform.Derive.Extension'. Two distinct
-- backend-defined modifier types coexist on the same 'Name' and are
-- recovered with full type fidelity.
module Test.Derive.Extension (tests) where
import qualified Data.Map.Strict as Map
import Data.Text (Text)
import qualified Data.Text as T
import Data.Typeable (Typeable)
import GHC.Generics (Generic)
import Test.Tasty (TestTree, testGroup)
import Test.Tasty.HUnit (testCase, (@?=))
import Wireform.Derive.Backend (backendIceberg)
import Wireform.Derive.Extension
( BackendModifier (..)
, extension
, hasExtension
, lookupExtension
, lookupExtensions
)
import Wireform.Derive.Modifier (Modifier)
import Wireform.Derive.ModifierInfo
( ModifierInfo (..)
, emptyModifierInfo
, foldModifiers
)
-- ---------------------------------------------------------------------------
-- Two pretend backend extension vocabularies
-- ---------------------------------------------------------------------------
data IcebergFieldOpt
= PartitionColumn
| OptimisticTransform !Text
deriving stock (Eq, Show, Read, Typeable, Generic)
instance BackendModifier IcebergFieldOpt where
backendModifierTag _ = "wireform-iceberg.field-opt"
data XmlFieldOpt
= AsAttribute
| AsElement
| NamespacedTo !Text
deriving stock (Eq, Show, Read, Typeable, Generic)
instance BackendModifier XmlFieldOpt where
backendModifierTag _ = "wireform-xml.field-opt"
-- ---------------------------------------------------------------------------
-- Tests
-- ---------------------------------------------------------------------------
tests :: TestTree
tests = testGroup "Wireform.Derive.Extension"
[ testCase "round-trip a single typed extension" $ do
let m = extension PartitionColumn
let mi = applyMods [m]
lookupExtension @IcebergFieldOpt mi @?= Just PartitionColumn
hasExtension @IcebergFieldOpt mi @?= True
, testCase "round-trip an extension with a Text payload" $ do
let m = extension (OptimisticTransform (T.pack "year"))
let mi = applyMods [m]
lookupExtension @IcebergFieldOpt mi @?= Just (OptimisticTransform (T.pack "year"))
, testCase "two extensions of the same type are stacked" $ do
let ms =
[ extension PartitionColumn
, extension (OptimisticTransform (T.pack "month"))
]
let mi = applyMods ms
lookupExtensions @IcebergFieldOpt mi @?=
[ PartitionColumn
, OptimisticTransform (T.pack "month")
]
, testCase "two extensions of distinct types coexist" $ do
let ms = [ extension PartitionColumn
, extension AsAttribute
, extension (NamespacedTo (T.pack "ns0"))
]
let mi = applyMods ms
lookupExtension @IcebergFieldOpt mi @?= Just PartitionColumn
lookupExtensions @XmlFieldOpt mi @?=
[AsAttribute, NamespacedTo (T.pack "ns0")]
, testCase "absent extension is Nothing" $ do
let mi = emptyModifierInfo backendIceberg
lookupExtension @IcebergFieldOpt mi @?= Nothing
hasExtension @IcebergFieldOpt mi @?= False
, testCase "miCustom keys match the BackendModifier tag" $ do
let mi = applyMods [extension PartitionColumn, extension AsAttribute]
Map.keys (miCustom mi) @?=
[ "wireform-iceberg.field-opt"
, "wireform-xml.field-opt"
]
]
-- | Fold the given modifiers as if they were attached to a name, so
-- the test mirrors what 'reifyModifierInfoFor' would produce.
applyMods :: [Modifier] -> ModifierInfo
applyMods ms = case foldModifiers backendIceberg ms of
Right mi -> mi
Left err -> error ("test fixture: foldModifiers raised " <> show err)