hierarchical-env-0.1.0.0: test/Control/Env/HierarchicalSpec.hs
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}
module Control.Env.HierarchicalSpec where
import Control.Env.Hierarchical
( Has,
Has1,
Root,
deriveEnv,
getL,
runIF,
)
import Control.Env.Hierarchical.Internal (Super)
import Control.Method (Interface (IBase), mapBaseRIO)
import Lens.Micro.TH (makeLenses)
import RIO
( Display (textDisplay),
Generic,
RIO,
Text,
runRIO,
view,
)
import Test.Hspec (Spec, it, shouldReturn)
data Env1 = Env1
{ hoge :: HogeObj Env1,
param1 :: Param1
}
data Env2 = Env2
{ env1 :: Env1,
foo :: FooObj Env2
}
data Env3 env = Env3 env Param2
data HogeObj env = HogeObj
{ _hogeMethod :: Int -> RIO env Text,
_fugaMethod :: Bool -> RIO env Bool
}
data FooObj env = FooObj
{ _fooMethod :: RIO env Text,
_barMethod :: RIO env Bool
}
deriving (Generic)
instance Interface FooObj where
type IBase FooObj = RIO
newtype Param1 = Param1 Int
newtype Param2 = Param2 Int
makeLenses ''HogeObj
makeLenses ''FooObj
deriveEnv ''Env1
deriveEnv ''Env2
deriveEnv ''Env3
type instance Super Env1 = Root
type instance Super Env2 = Env1
type instance Super (Env3 env) = env
example1 :: (Has1 HogeObj env, Has Param1 env) => RIO env Text
example1 = do
Param1 n <- view getL
runIF (\x -> view hogeMethod x n)
example2 :: (Has1 FooObj env) => RIO env Text
example2 = runIF _fooMethod
mkEnv1 :: Env1
mkEnv1 =
Env1
{ hoge = hogeImpl,
param1 = Param1 10
}
mkEnv2 :: Env2
mkEnv2 =
Env2
{ foo = mapBaseRIO mkEnv3 fooImpl,
env1 = mkEnv1
}
mkEnv3 :: env -> Env3 env
mkEnv3 env = Env3 env (Param2 5)
hogeImpl :: HogeObj env
hogeImpl =
HogeObj
{ _hogeMethod = pure . textDisplay,
_fugaMethod = pure . not
}
--
fooImpl :: (Has1 HogeObj env, Has Param2 env) => FooObj env
fooImpl =
FooObj
{ _fooMethod = do
Param2 n <- view getL
runIF (\x -> view hogeMethod x n),
_barMethod = pure True
}
spec :: Spec
spec = do
it "" $ do
runRIO mkEnv1 example1 `shouldReturn` "10"
it "" $ do
runRIO mkEnv2 example2 `shouldReturn` "5"