wireform-derive-0.2.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 Data.Map.Strict qualified as Map
import Data.Text (Text)
import Data.Text qualified as T
import Data.Typeable (Typeable)
import GHC.Generics (Generic)
import Test.Syd
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 :: Spec
tests =
describe "Wireform.Derive.Extension" $
sequence_
[ it "round-trip a single typed extension" $ do
let m = extension PartitionColumn
let mi = applyMods [m]
lookupExtension @IcebergFieldOpt mi `shouldBe` Just PartitionColumn
hasExtension @IcebergFieldOpt mi `shouldBe` True
, it "round-trip an extension with a Text payload" $ do
let m = extension (OptimisticTransform (T.pack "year"))
let mi = applyMods [m]
lookupExtension @IcebergFieldOpt mi `shouldBe` Just (OptimisticTransform (T.pack "year"))
, it "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
`shouldBe` [ PartitionColumn
, OptimisticTransform (T.pack "month")
]
, it "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 `shouldBe` Just PartitionColumn
lookupExtensions @XmlFieldOpt mi
`shouldBe` [AsAttribute, NamespacedTo (T.pack "ns0")]
, it "absent extension is Nothing" $ do
let mi = emptyModifierInfo backendIceberg
lookupExtension @IcebergFieldOpt mi `shouldBe` Nothing
hasExtension @IcebergFieldOpt mi `shouldBe` False
, it "miCustom keys match the BackendModifier tag" $ do
let mi = applyMods [extension PartitionColumn, extension AsAttribute]
Map.keys (miCustom mi)
`shouldBe` [ "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)