hydra-0.13.0: src/main/haskell/Hydra/Sources/Test/Lib/Eithers.hs
module Hydra.Sources.Test.Lib.Eithers 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
-- Additional imports specific to this file
import Hydra.Testing
import Hydra.Sources.Libraries
import qualified Hydra.Dsl.Meta.Lib.Logic as Logic
ns :: Namespace
ns = Namespace "hydra.test.lib.eithers"
module_ :: Module
module_ = Module ns elements [] [] $
Just "Test cases for hydra.lib.eithers primitives"
where
elements = [Phantoms.toBinding allTests]
-- Helper to create Left terms
leftInt32 :: Int -> TTerm Term
leftInt32 x = left (int32 x)
-- Helper to create Right terms
rightString :: String -> TTerm Term
rightString s = right (string s)
-- Test groups for hydra.lib.eithers primitives
eithersBind :: TTerm TestGroup
eithersBind = subgroup "bind" [
test "bind Right with success" (rightString "ab") (right (int32 2)),
test "bind Right with failure" (rightString "") (leftInt32 0),
test "bind Left returns Left unchanged" (leftInt32 42) (leftInt32 42)]
where
-- Function: get length of string, fail with 0 if empty
bindFn = lambda "s" (primitive _logic_ifElse
@@ (primitive _strings_null @@ var "s")
@@ (left (int32 0))
@@ (right (primitive _strings_length @@ var "s")))
test name input expected = primCase name _eithers_bind [input, bindFn] expected
eithersBimap :: TTerm TestGroup
eithersBimap = subgroup "bimap" [
test "map left value" (leftInt32 5) (leftInt32 10),
test "map right value" (rightString "ab") (right (int32 2))]
where
test name input expected = primCase name _eithers_bimap [
lambda "x" (primitive _math_mul @@ var "x" @@ int32 2),
lambda "s" (primitive _strings_length @@ var "s"),
input] expected
eithersIsLeft :: TTerm TestGroup
eithersIsLeft = subgroup "isLeft" [
test "left value" (leftInt32 42) true,
test "right value" (rightString "test") false]
where
test name x result = primCase name _eithers_isLeft [x] result
eithersIsRight :: TTerm TestGroup
eithersIsRight = subgroup "isRight" [
test "right value" (rightString "test") true,
test "left value" (leftInt32 42) false]
where
test name x result = primCase name _eithers_isRight [x] result
eithersFromLeft :: TTerm TestGroup
eithersFromLeft = subgroup "fromLeft" [
test "extract left" 99 (leftInt32 42) 42,
test "use default for right" 99 (rightString "test") 99]
where
test name def x result = primCase name _eithers_fromLeft [int32 def, x] (int32 result)
eithersFromRight :: TTerm TestGroup
eithersFromRight = subgroup "fromRight" [
test "extract right" "default" (rightString "test") "test",
test "use default for left" "default" (leftInt32 42) "default"]
where
test name def x result = primCase name _eithers_fromRight [string def, x] (string result)
eithersEither :: TTerm TestGroup
eithersEither = subgroup "either" [
test "apply left function" (leftInt32 5) 10,
test "apply right function" (rightString "ab") 2]
where
test name x result = primCase name _eithers_either [
lambda "x" (primitive _math_mul @@ var "x" @@ int32 2),
lambda "s" (primitive _strings_length @@ var "s"),
x] (int32 result)
eithersLefts :: TTerm TestGroup
eithersLefts = subgroup "lefts" [
test "filter left values" [leftInt32 1, rightString "a", leftInt32 2, rightString "b"] [1, 2],
test "all lefts" [leftInt32 1, leftInt32 2] [1, 2],
test "all rights" [rightString "a", rightString "b"] [],
test "empty list" [] []]
where
test name input expected = primCase name _eithers_lefts [list input] (list $ fmap int32 expected)
eithersRights :: TTerm TestGroup
eithersRights = subgroup "rights" [
test "filter right values" [leftInt32 1, rightString "a", leftInt32 2, rightString "b"] ["a", "b"],
test "all rights" [rightString "a", rightString "b"] ["a", "b"],
test "all lefts" [leftInt32 1, leftInt32 2] [],
test "empty list" [] []]
where
test name input expected = primCase name _eithers_rights [list input] (list $ fmap string expected)
eithersPartitionEithers :: TTerm TestGroup
eithersPartitionEithers = subgroup "partitionEithers" [
test "partition mixed" [leftInt32 1, rightString "a", leftInt32 2, rightString "b"] ([1, 2], ["a", "b"]),
test "all lefts" [leftInt32 1, leftInt32 2] ([1, 2], []),
test "all rights" [rightString "a", rightString "b"] ([], ["a", "b"]),
test "empty list" [] ([], [])]
where
test name input (lefts, rights) = primCase name _eithers_partitionEithers [list input]
(Core.termPair $ Phantoms.pair (list $ fmap int32 lefts) (list $ fmap string rights))
eithersMap :: TTerm TestGroup
eithersMap = subgroup "map" [
test "map right value" (rightInt32 5) (rightInt32 10),
test "preserve left" (leftInt32 99) (leftInt32 99)]
where
rightInt32 x = right (int32 x)
leftInt32 x = left (int32 x)
test name input expected = primCase name _eithers_map [
lambda "x" (primitive _math_mul @@ var "x" @@ int32 2),
input] expected
eithersMapList :: TTerm TestGroup
eithersMapList = subgroup "mapList" [
test "all succeed" [1, 2, 3] (right (list [int32 2, int32 4, int32 6])),
test "first fails" [1, 0, 3] (left (string "zero")),
test "empty list" [] (right (list []))]
where
test name input expected = primCase name _eithers_mapList [
lambda "x" (primitive _logic_ifElse
@@ (primitive _equality_equal @@ var "x" @@ int32 0)
@@ left (string "zero")
@@ right (primitive _math_mul @@ var "x" @@ int32 2)),
list $ fmap int32 input] expected
eithersMapMaybe :: TTerm TestGroup
eithersMapMaybe = subgroup "mapMaybe" [
test "just succeeds" (Core.termMaybe $ just (int32 5)) (right (Core.termMaybe $ just (int32 10))),
test "just fails" (Core.termMaybe $ just (int32 0)) (left (string "zero")),
test "nothing" (Core.termMaybe nothing) (right (Core.termMaybe nothing))]
where
test name input expected = primCase name _eithers_mapMaybe [
lambda "x" (primitive _logic_ifElse
@@ (primitive _equality_equal @@ var "x" @@ int32 0)
@@ left (string "zero")
@@ right (primitive _math_mul @@ var "x" @@ int32 2)),
input] expected
allTests :: TBinding TestGroup
allTests = definitionInModule module_ "allTests" $
Phantoms.doc "Test cases for hydra.lib.eithers primitives" $
supergroup "hydra.lib.eithers primitives" [
eithersBind,
eithersBimap,
eithersIsLeft,
eithersIsRight,
eithersFromLeft,
eithersFromRight,
eithersEither,
eithersLefts,
eithersRights,
eithersPartitionEithers,
eithersMap,
eithersMapList,
eithersMapMaybe]