relation-0.5.1.0: test/Data/RelationSpec.hs
module Data.RelationSpec
( spec
) where
import Data.Relation.Ops
import HaskellWorks.Hspec.Hedgehog
import Hedgehog
import Test.Hspec
import Control.Monad (replicateM)
import qualified Data.List as L
import qualified Data.Map as M
import qualified Data.Relation as DR
import qualified Data.Relation.Internal as DR
import qualified Data.Relation.Gen as GR
import qualified Data.Set as S
import qualified Hedgehog.Gen as G
import qualified Hedgehog.Range as R
{-# ANN module ("HLint: ignore Redundant do" :: String) #-}
e :: DR.Relation String String
e = DR.fromList
[ ("Rebeca" , "History" )
, ("Rebeca" , "Mathematics" )
, ("Rolando", "Religion" )
, ("Rolando", "Comunication" )
, ("Teresa" , "Religion" )
, ("Teresa" , "Architecture" )
, ("Antonio", "History" )
]
rebecaE :: S.Set String
rebecaE = (S.singleton "Rebeca" |$> DR.ran e) e
takingreligion :: S.Set String
takingreligion = (DR.dom e <$| S.singleton "Religion") e
others :: S.Set String
others = (takingreligion |$> DR.ran e) e
takingreligion2 :: DR.Relation String String
takingreligion2 = e |> S.singleton "Religion"
twoStudents :: DR.Relation String String
twoStudents = (<|) (S.union (S.singleton "Rolando") (S.singleton "Teresa")) e
id1 :: S.Set String -> (Bool, S.Set String)
id1 s = (v1 == v2, v1)
where v1 = (DR.dom e |$> s) e
v2 = DR.ran (e |> s)
id2 :: S.Set String -> (Bool, S.Set String)
id2 s = (v1 == v2, v1)
where v1 = (DR.dom e <$| s) e
v2 = DR.dom (e |> s)
id3 :: S.Set String -> (Bool, S.Set String)
id3 s = (v1 == v2, v1)
where v1 = (s <$| DR.ran e) e
v2 = DR.dom (s <| e)
id4 :: S.Set String -> (Bool, S.Set String)
id4 s = (v1 == v2, v2)
where v1 = (s |$> DR.ran e) e
v2 = DR.ran (s <| e)
religion :: S.Set String
religion = S.singleton "Religion" -- has students
teresa :: S.Set String
teresa = S.singleton "Teresa" -- enrolled
spec :: Spec
spec = describe "Data.RelationSpec" $ do
describe "Unit tests" $ do
it "fromList" $ requireTest $ do
e === DR.Relation
{ DR.domain = M.fromList
[ ("Antonio" , S.fromList ["History" ])
, ("Rebeca" , S.fromList ["History", "Mathematics" ])
, ("Rolando" , S.fromList ["Comunication", "Religion"])
, ("Teresa" , S.fromList ["Architecture", "Religion"])
]
, DR.range = M.fromList
[ ("Architecture" , S.fromList ["Teresa" ])
, ("Comunication" , S.fromList ["Rolando" ])
, ("History" , S.fromList ["Antonio", "Rebeca" ])
, ("Mathematics" , S.fromList ["Rebeca" ])
, ("Religion" , S.fromList ["Rolando", "Teresa" ])
]
}
it "singleton & range" $ requireTest $ do
rebecaE === S.fromList ["History", "Mathematics"]
it "singleton & domain" $ requireTest $ do
takingreligion === S.fromList ["Rolando", "Teresa"]
it "(|$>)" $ requireTest $ do
others === S.fromList ["Architecture", "Comunication", "Religion"]
it "test1" $ requireTest $ do
(takingreligion <$| DR.ran e) e === takingreligion
it "Exploring |>" $ requireTest $ do
takingreligion2 === DR.Relation
{ DR.domain = M.fromList
[ ("Rolando" , S.fromList ["Religion" ])
, ("Teresa" , S.fromList ["Religion" ])
]
, DR.range = M.fromList
[ ("Religion" , S.fromList ["Rolando", "Teresa" ])
]
}
it "twoStudents" $ requireTest $ do
twoStudents === DR.Relation
{ DR.domain = M.fromList
[ ("Rolando" , S.fromList ["Comunication", "Religion"])
, ("Teresa" , S.fromList ["Architecture", "Religion"])
]
, DR.range = M.fromList
[ ("Architecture" , S.fromList ["Teresa" ])
, ("Comunication" , S.fromList ["Rolando" ])
, ("Religion" , S.fromList ["Rolando", "Teresa" ])
]
}
it "test 2" $ requireTest $ do
(|$>) (S.union (S.singleton "Rolando") (S.singleton "Teresa")) (DR.ran e) e === S.fromList ["Architecture", "Comunication", "Religion"]
it "test 3" $ requireTest $ do
id1 religion === (True, S.fromList ["Religion"])
it "test 4" $ requireTest $ do
id2 religion === (True, S.fromList ["Rolando", "Teresa"])
it "test 5" $ requireTest $ do
id3 teresa === (True, S.fromList ["Teresa"])
it "test 6" $ requireTest $ do
id4 teresa === (True, S.fromList ["Architecture", "Religion"])
it "test 7" $ requireTest $ do
(DR.dom e |$> religion) e === DR.ran (e |> religion)
it "test 8" $ requireTest $ do
(DR.dom e <$| religion) e === DR.dom (e |> religion)
it "test 9" $ requireTest $ do
(teresa <$| DR.ran e) e === DR.dom (teresa <| e)
it "test 10" $ requireTest $ do
(teresa |$> DR.ran e) e === DR.ran (teresa <| e)
describe "property tests" $ do
it "List roundtrip" $ require $ property $ do
as <- forAll $ G.list (R.linear 0 10) $ (,)
<$> G.int R.constantBounded
<*> G.alpha
L.sort (DR.toList (DR.fromList as)) === L.sort as
it "Full domain restriction" $ require $ property $ do
as <- forAll $ G.list (R.linear 0 10) $ (,)
<$> G.int R.constantBounded
<*> G.alpha
DR.restrictDom S.empty (DR.fromList as) === DR.empty
it "Full range restriction" $ require $ property $ do
as <- forAll $ G.list (R.linear 0 10) $ (,)
<$> G.int R.constantBounded
<*> G.alpha
DR.restrictRan S.empty (DR.fromList as) === DR.empty
it "No domain restriction" $ require $ property $ do
as <- forAll $ G.list (R.linear 0 10) $ (,)
<$> G.int R.constantBounded
<*> G.alpha
let r = DR.fromList as
DR.restrictDom (DR.dom r) r === r
it "No range restriction" $ require $ property $ do
as <- forAll $ G.list (R.linear 0 10) $ (,)
<$> G.int R.constantBounded
<*> G.alpha
let r = DR.fromList as
DR.restrictRan (DR.ran r) r === r
it "Full domain without" $ require $ property $ do
as <- forAll $ G.list (R.linear 0 10) $ (,)
<$> G.int R.constantBounded
<*> G.alpha
let r = DR.fromList as
DR.withoutDom S.empty r === r
it "Full range without" $ require $ property $ do
as <- forAll $ G.list (R.linear 0 10) $ (,)
<$> G.int R.constantBounded
<*> G.alpha
let r = DR.fromList as
DR.withoutRan S.empty r === r
it "No domain without" $ require $ property $ do
as <- forAll $ G.list (R.linear 0 10) $ (,)
<$> G.int R.constantBounded
<*> G.alpha
let r = DR.fromList as
DR.withoutDom (DR.dom r) r === DR.empty
it "No range without" $ require $ property $ do
as <- forAll $ G.list (R.linear 0 10) $ (,)
<$> G.int R.constantBounded
<*> G.alpha
let r = DR.fromList as
DR.withoutRan (DR.ran r) r === DR.empty
it "Compose associatively" $ require $ property $ do
~[a,b,c] <- forAll $ replicateM 3 $ GR.relation
(R.linear 10 40)
(G.integral (R.linear (1 :: Integer) 10))
(G.integral (R.linear (1 :: Integer) 10))
((a DR.<-< b) DR.<-< c) === (a DR.<-< (b DR.<-< c))