named-sop-0.2.0.0: test/Tests.hs
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE EmptyDataDeriving #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE MonoLocalBinds #-}
{-# LANGUAGE PolyKinds #-}
import Control.Monad
import GHC.Generics
import Test.Tasty
import Test.Tasty.HUnit
import Data.NamedSOP.Generic
import Data.NamedSOP.Map
import Data.NamedSOP.Sum
main :: IO ()
main = defaultMain tests
testGenSpecProd :: ( Generic a
, GenProduct (Rep a)
, Eq a
, Eq (NMap (GProduct (Rep a)))
, Show a
, Show (NMap (GProduct (Rep a)))) =>
[Char] -> a -> NMap (GProduct (Rep a)) -> [TestTree]
testGenSpecProd s a b =
[ testCase ("Generalize " ++ s) $
genProduct a @?= b
, testCase ("Specialize " ++ s) $
specProduct b @?= a
]
testGenSpecSum :: ( Generic a
, GenSum (Rep a)
, Eq a
, Eq (NSum (GSum (Rep a)))
, Show a
, Show (NSum (GSum (Rep a)))) =>
[Char] -> a -> NSum (GSum (Rep a)) -> [TestTree]
testGenSpecSum s a b =
[ testCase ("Generalize " ++ s) $
genSum a @?= b
, testCase ("Specialize " ++ s) $
specSum b @?= a
]
tests :: TestTree
tests = testGroup "Unit tests" [isoTests, unionTests]
data EmptyP = EmptyP
deriving (Eq, Ord, Show, Generic)
data UnaryP a = UnaryP a
deriving (Eq, Ord, Show, Generic)
data Size2P a b = Size2P a b
deriving (Eq, Ord, Show, Generic)
data RecordP = RecordP { recordPA :: Int, recordPB :: String }
deriving (Eq, Ord, Show, Generic)
data EmptyS
deriving (Eq, Ord, Show, Generic)
data UnaryS a = UnaryS a
deriving (Eq, Ord, Show, Generic)
data Size2S a b = Size2SA a
| Size2SB b
deriving (Eq, Ord, Show, Generic)
data RecordS = RecordSA { recordSAA :: Int }
| RecordSB { recordSBA :: Bool, recordSBB :: String }
deriving (Eq, Ord, Show, Generic)
isoTests :: TestTree
isoTests = testGroup "Generic isomorphisms" $ join $
[ testGenSpecProd "empty product"
EmptyP
NMapEmpty
, testGenSpecProd "unary product"
(UnaryP True)
(NMapExt @"_1" True NMapEmpty)
, testGenSpecProd "size-2 product"
(Size2P True "hello")
(NMapExt @"_1" True (NMapExt @"_2" "hello" NMapEmpty))
, testGenSpecProd "record product"
(RecordP { recordPA = 1, recordPB = "hello" })
(NMapExt @"recordPA" 1 (NMapExt @"recordPB" "hello" NMapEmpty))
, testGenSpecSum "empty sum"
(undefined :: EmptyS)
(undefined :: NSum '[])
, testGenSpecSum "unary sum"
(UnaryS True)
(NSumThis @"_UnaryS" (NMapExt @"_1" True NMapEmpty))
, testGenSpecSum "size-2 sum, 1st branch"
(Size2SA True :: Size2S Bool String)
(NSumThis @"_Size2SA" (NMapExt @"_1" True NMapEmpty))
, testGenSpecSum "size-2 sum, 2nd branch"
(Size2SB "hello" :: Size2S Bool String)
(NSumThat (NSumThis @"_Size2SB" (NMapExt @"_1" "hello" NMapEmpty)))
, testGenSpecSum "sum of records, 1st branch"
(RecordSA { recordSAA = 1 })
(NSumThis @"_RecordSA" (NMapExt @"recordSAA" 1 NMapEmpty))
, testGenSpecSum "sum of records, 2nd branch"
(RecordSB { recordSBA = True, recordSBB = "hello" })
(NSumThat (NSumThis @"_RecordSB"
(NMapExt @"recordSBA" True
(NMapExt @"recordSBB" "hello" NMapEmpty))))
]
unionTests :: TestTree
unionTests = testGroup "Union/ununion operations"
[ testCase "Union of products" $
unionMap
((NMapExt @"c" True (NMapExt @"a" "hello" NMapEmpty)),
(NMapExt @"b" "world" (NMapExt @"d" False NMapEmpty)))
@?=
(NMapExt @"a" "hello"
(NMapExt @"b" "world"
(NMapExt @"c" True
(NMapExt @"d" False NMapEmpty))))
, testCase "Product ununion . union == id" $
ununionMap
(unionMap
((NMapExt @"c" True (NMapExt @"a" "hello" NMapEmpty)),
(NMapExt @"b" "world" (NMapExt @"d" False NMapEmpty))))
@?=
((NMapExt @"c" True (NMapExt @"a" "hello" NMapEmpty)),
(NMapExt @"b" "world" (NMapExt @"d" False NMapEmpty)))
, testCase "Union of sums, 1st branch" $
unionSum @_ @'["b" ':-> Bool] @'["a" ':-> Int]
(Left (NSumThis @"b" True))
@?=
(NSumThat (NSumThis @"b" True))
, testCase "Union of sums, 2nd branch" $
unionSum @_ @'["b" ':-> Bool] @'["a" ':-> Int]
(Right (NSumThis @"a" 1))
@?=
(NSumThis @"a" 1)
, testCase "Sum ununion . union == id" $
ununionSum @_ @'["b" ':-> Bool] @'["a" ':-> Int]
(unionSum @_ @'["b" ':-> Bool] @'["a" ':-> Int]
(Left (NSumThis @"b" True)))
@?=
(Left (NSumThis @"b" True))
]