registry-0.3.0.8: test/Test/Data/Registry/RegistrySpec.hs
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# OPTIONS_GHC -fno-warn-deprecations #-}
{-# OPTIONS_GHC -fno-warn-missing-signatures #-}
module Test.Data.Registry.RegistrySpec where
import Data.IORef
import Data.Registry
import Protolude as P
import Test.Tasty.Extensions
test_create_value_with_no_args_constructor = prop "no args constructors are considered as functions" $ do
ref <- liftIO $ newIORef ("" :: Text)
let registry' = funTo @IO refLogger +: funTo @IO ref +: registry
Logger {..} <- liftIO $ make @(IO Logger) registry'
liftIO $ info "hey"
result <- liftIO $ readIORef ref
result === "hey"
test_append_values = test "2 values can be appended together" $ do
let r = val (1 :: Int) <: val (2 :: Int)
make @Int r === 1
let r2 = val (1 :: Int) <+ val (2 :: Int)
make @Int r2 === 1
test_append_value_to_registry = test "a value can be appended to a registry" $ do
let r = (val (1 :: Int) <: val (2 :: Int)) <: val (3 :: Int)
make @Int r === 1
let r2 = (val (1 :: Int) <+ val (2 :: Int)) <+ val (3 :: Int)
make @Int r2 === 1
test_prepend_value_to_registry = test "a value can be prepended to a registry" $ do
let r = val (1 :: Int) <: (val (2 :: Int) <: val (3 :: Int))
make @Int r === 1
let r2 = val (1 :: Int) <+ (val (2 :: Int) <+ val (3 :: Int))
make @Int r2 === 1
-- *
newtype Logger = Logger {info :: Text -> IO ()}
newLogger :: IO Logger
newLogger = pure (Logger print)
refLogger :: IORef Text -> Logger
refLogger ref = Logger (writeIORef ref)
registry =
fun newLogger
+: end
-- * COMPILATION CHECK WITH THE <: operator
registry1 :: Registry '[] '[Int, Text]
registry1 =
normalize $
val (1 :: Int)
<: (val ("t" :: Text) +: end)
<: (val ("t" :: Text) +: end)
<: val ("t" :: Text)
registry2 :: Registry '[] [Text, Text]
registry2 =
val ("t" :: Text)
<: val ("t" :: Text)
registry3 :: Registry '[] '[Int] =
val (10 :: Int)
<+ end
-- * COMPILATION CHECK LIFTING (see #7)
a :: Int -> Int -> IO Int
a _ _ = pure 0
b :: Int -> Int -> RIO Int
b = outTo @RIO liftIO a
c :: RIO Int -> RIO Int -> RIO Int
c = allTo @RIO b
-- here the result of outTo needs to be explicit
-- otherwise the type of d is RIO (Int -> Int -> RIO Int)
d :: RIO Int -> RIO Int -> RIO Int
d = allTo @RIO (outTo @RIO liftIO a :: Int -> Int -> RIO Int)
-- to avoid the issue with type inference above, we can use argsTo
e :: RIO Int -> RIO Int -> RIO Int
e = argsTo @RIO (outTo @RIO liftIO a)