module Data.Component.Mock.TH (makeMock) where import Relude import qualified Language.Haskell.TH as Meta import qualified Data.Component.Mock.TH.Gadt as Gadt import qualified Data.Component.Mock.TH.Instance as Instance import qualified Data.Component.Mock.TH.NewFunction as NewFunction {-| Generates all the required things to work with a mock: * A data type representing the component methods (Actions) * The proper instantiation of 'IsAction' for this data type * A 'mock' function to be used instead of 'new'. The only requirement is that all the methods of the component must return something wrapped in a context. -} makeMock :: Meta.Name -> Meta.DecsQ makeMock componentName = do info <- Meta.reify componentName case info of Meta.TyConI (Meta.DataD _ recordName _ _ [Meta.RecC _ fields] _) -> do action <- Gadt.make fields instance' <- Instance.make fields newFunction <- NewFunction.make recordName fields pure $ action <> [instance'] <> newFunction _ -> fail "makeMock only accepts simple records"