hydra-0.15.0: src/main/haskell/Hydra/Sources/Test/Lib/Sets.hs
{-# LANGUAGE FlexibleContexts #-}
module Hydra.Sources.Test.Lib.Sets where
-- Standard imports for shallow DSL tests
import Hydra.Kernel
import Hydra.Dsl.Meta.Testing as Testing
import Hydra.Dsl.Meta.Terms as Terms
import Hydra.Sources.Kernel.Types.All
import qualified Hydra.Dsl.Meta.Core as Core
import qualified Hydra.Dsl.Meta.Phantoms as Phantoms
import qualified Hydra.Dsl.Meta.Types as T
import qualified Hydra.Sources.Test.TestGraph as TestGraph
import qualified Hydra.Sources.Test.TestTerms as TestTerms
import qualified Hydra.Sources.Test.TestTypes as TestTypes
import qualified Data.List as L
import qualified Data.Map as M
import qualified Data.Set as S
-- Additional imports specific to this file
import Hydra.Testing
import Hydra.Sources.Libraries
import qualified Hydra.Dsl.Meta.Lib.Literals as Literals
import qualified Hydra.Dsl.Meta.Lib.Math as Math
import qualified Hydra.Dsl.Meta.Lib.Sets as Sets
import qualified Hydra.Sources.Kernel.Terms.Show.Core as ShowCore
ns :: Namespace
ns = Namespace "hydra.test.lib.sets"
module_ :: Module
module_ = Module {
moduleNamespace = ns,
moduleDefinitions = definitions,
moduleTermDependencies = [Namespace "hydra.reduction", ShowCore.ns],
moduleTypeDependencies = kernelTypesNamespaces,
moduleDescription = Just "Test cases for hydra.lib.sets primitives"}
where
definitions = [Phantoms.toDefinition allTests]
(#) :: (AsTerm f (a -> b), AsTerm g a) => f -> g -> TTerm b
(#) = (Phantoms.@@)
infixl 1 #
showInt32 :: TTerm (Int -> String)
showInt32 = Phantoms.lambda "n" $ Literals.showInt32 (Phantoms.var "n")
showBool :: TTerm (Bool -> String)
showBool = Phantoms.lambda "b" $ Literals.showBoolean (Phantoms.var "b")
showIntSet :: TTerm (S.Set Int -> String)
showIntSet = Phantoms.lambda "s" $ ShowCore.set_ # showInt32 # Phantoms.var "s"
showIntList :: TTerm ([Int] -> String)
showIntList = Phantoms.lambda "xs" $ ShowCore.list_ # showInt32 # Phantoms.var "xs"
-- Phantom-typed helper for int sets
pIntSet :: [Int] -> TTerm (S.Set Int)
pIntSet xs = Phantoms.set (Phantoms.int32 <$> xs)
-- Test groups for hydra.lib.sets primitives
setsEmpty :: TTerm TestGroup
setsEmpty = subgroup "empty" [
test "empty set" []]
where
test name expected = evalPair name showIntSet
(Sets.empty :: TTerm (S.Set Int))
(pIntSet expected)
setsSingleton :: TTerm TestGroup
setsSingleton = subgroup "singleton" [
test "single element" 42 [42]]
where
test name x result = evalPair name showIntSet
(Sets.singleton (Phantoms.int32 x))
(pIntSet result)
setsFromList :: TTerm TestGroup
setsFromList = subgroup "fromList" [
test "create from list" [1, 2, 3] [1, 2, 3],
test "duplicates removed" [1, 2, 1, 3] [1, 2, 3],
test "empty list" [] []]
where
test name input expected = evalPair name showIntSet
(Sets.fromList (Phantoms.list $ Phantoms.int32 <$> input))
(pIntSet expected)
setsToList :: TTerm TestGroup
setsToList = subgroup "toList" [
test "convert to list" [1, 2, 3] [1, 2, 3],
test "unsorted input" [3, 1, 2] [1, 2, 3],
test "empty set" [] []]
where
test name input expected = evalPair name showIntList
(Sets.toList (pIntSet input))
(Phantoms.list $ Phantoms.int32 <$> expected)
setsInsert :: TTerm TestGroup
setsInsert = subgroup "insert" [
test "insert new element" 4 [1, 2, 3] [1, 2, 3, 4],
test "insert existing element" 2 [1, 2, 3] [1, 2, 3],
test "insert into empty" 1 [] [1]]
where
test name x s result = evalPair name showIntSet
(Sets.insert (Phantoms.int32 x) (pIntSet s))
(pIntSet result)
setsDelete :: TTerm TestGroup
setsDelete = subgroup "delete" [
test "delete existing" 2 [1, 2, 3] [1, 3],
test "delete non-existing" 4 [1, 2, 3] [1, 2, 3],
test "delete from empty" 1 [] []]
where
test name x s result = evalPair name showIntSet
(Sets.delete (Phantoms.int32 x) (pIntSet s))
(pIntSet result)
setsMember :: TTerm TestGroup
setsMember = subgroup "member" [
test "element exists" 2 [1, 2, 3] True,
test "element missing" 4 [1, 2, 3] False,
test "empty set" 1 [] False]
where
test name x s result = evalPair name showBool
(Sets.member (Phantoms.int32 x) (pIntSet s))
(Phantoms.boolean result)
setsSize :: TTerm TestGroup
setsSize = subgroup "size" [
test "three elements" [1, 2, 3] 3,
test "single element" [42] 1,
test "empty set" [] 0]
where
test name s result = evalPair name showInt32
(Sets.size (pIntSet s))
(Phantoms.int32 result)
setsNull :: TTerm TestGroup
setsNull = subgroup "null" [
test "empty set" [] True,
test "non-empty set" [1, 2] False]
where
test name s result = evalPair name showBool
(Sets.null (pIntSet s))
(Phantoms.boolean result)
setsUnion :: TTerm TestGroup
setsUnion = subgroup "union" [
test "union two sets" [1, 2] [2, 3] [1, 2, 3],
test "union with empty" [1, 2] [] [1, 2],
test "empty with non-empty" [] [1, 2] [1, 2]]
where
test name s1 s2 result = evalPair name showIntSet
(Sets.union (pIntSet s1) (pIntSet s2))
(pIntSet result)
setsIntersection :: TTerm TestGroup
setsIntersection = subgroup "intersection" [
test "common elements" [1, 2, 3] [2, 3, 4] [2, 3],
test "no common elements" [1, 2] [3, 4] [],
test "intersection with empty" [1, 2] [] []]
where
test name s1 s2 result = evalPair name showIntSet
(Sets.intersection (pIntSet s1) (pIntSet s2))
(pIntSet result)
setsDifference :: TTerm TestGroup
setsDifference = subgroup "difference" [
test "remove elements" [1, 2, 3] [2, 4] [1, 3],
test "no overlap" [1, 2] [3, 4] [1, 2],
test "difference with empty" [1, 2] [] [1, 2]]
where
test name s1 s2 result = evalPair name showIntSet
(Sets.difference (pIntSet s1) (pIntSet s2))
(pIntSet result)
setsUnions :: TTerm TestGroup
setsUnions = subgroup "unions" [
test "union of multiple sets" [[1, 2], [2, 3], [3, 4]] [1, 2, 3, 4],
test "union with empty sets" [[1, 2], [], [3]] [1, 2, 3],
test "empty list of sets" [] [],
test "single set" [[1, 2, 3]] [1, 2, 3]]
where
test name sets result = evalPair name showIntSet
(Sets.unions (Phantoms.list $ pIntSet <$> sets))
(pIntSet result)
setsMap :: TTerm TestGroup
setsMap = subgroup "map" [
test "map function" [1, 2, 3] [2, 4, 6],
test "map on empty" [] []]
where
test name s result = evalPair name showIntSet
(Sets.map (Phantoms.lambda "x" $ Math.mul (Phantoms.var "x") (Phantoms.int32 2)) (pIntSet s))
(pIntSet result)
allTests :: TTermDefinition TestGroup
allTests = definitionInModule module_ "allTests" $
Phantoms.doc "Test cases for hydra.lib.sets primitives" $
supergroup "hydra.lib.sets primitives" [
setsEmpty,
setsSingleton,
setsFromList,
setsToList,
setsInsert,
setsDelete,
setsMember,
setsSize,
setsNull,
setsUnion,
setsUnions,
setsIntersection,
setsDifference,
setsMap]