blanks-0.5.0: test/Test/Blanks/SplitTest.hs
module Test.Blanks.SplitTest
( testSplit
) where
import Blanks (BinderId, SplitResult (..), Tracked, mkTrackedBound, mkTrackedFree)
import Data.Map.Strict (Map)
import qualified Data.Map.Strict as Map
import Test.Blanks.SimpleScope (SimpleScope, sbound, sconst, sflip, sfree, sfree2, sid, spair, svar, swonky, swonky3)
import Test.Blanks.SplitScope (SplitOuterBinder, SplitScope, boundSplit, closureSplit, embedSplit, innerBinderSplit,
outerBinderSplit, simpleSplit, varSplit)
import Test.Tasty (TestTree, testGroup)
import Test.Tasty.HUnit (testCase, (@?=))
data SplitCase = SplitCase
{ splitCaseName :: !String
, splitCaseScopeIn :: !SimpleScope
, splitCaseTrackedOut :: !(Tracked Char)
, splitCaseScopeOut :: !SplitScope
, splitCaseBinders :: !(Map BinderId SplitOuterBinder)
} deriving stock (Eq, Show)
splitCases :: [SplitCase]
splitCases =
let xvar = varSplit 'x'
xbound = boundSplit 0
xpair = embedSplit xvar xbound
in [ SplitCase "var" svar (mkTrackedFree 'x') xvar Map.empty
, SplitCase "bound" sbound (mkTrackedBound 0) xbound Map.empty
, SplitCase "pair" spair (mkTrackedFree 'x' <> mkTrackedBound 0) xpair Map.empty
, let ib = innerBinderSplit 'y' (varSplit 'x')
ob = outerBinderSplit 0 ['x'] ib
in SplitCase "free" sfree mempty (closureSplit 0 []) (Map.singleton 0 ob)
, let ibY = innerBinderSplit 'y' (varSplit 'x')
obY = outerBinderSplit 0 ['x'] ibY
ibZ = innerBinderSplit 'z' (closureSplit 1 [])
obZ = outerBinderSplit 0 ['x'] ibZ
in SplitCase "free2" sfree2 mempty (closureSplit 0 []) (Map.fromList [(0, obZ), (1, obY)])
, let ib = innerBinderSplit 'x' (varSplit 'x')
ob = outerBinderSplit 0 [] ib
in SplitCase "id" sid mempty (closureSplit 0 []) (Map.singleton 0 ob)
, let ib = innerBinderSplit 'x' (boundSplit 0)
ob = outerBinderSplit 1 [] ib
in SplitCase "wonky" swonky (mkTrackedBound 0) (closureSplit 0 [0]) (Map.singleton 0 ob)
, let ibY = innerBinderSplit 'y' (boundSplit 0)
obY = outerBinderSplit 1 [] ibY
ibZ = innerBinderSplit 'x' (closureSplit 1 [0])
obZ = outerBinderSplit 0 [] ibZ
in SplitCase "const" sconst mempty (closureSplit 0 []) (Map.fromList [(0, obZ), (1, obY)])
, let ibY = innerBinderSplit 'y' (varSplit 'y')
obY = outerBinderSplit 0 [] ibY
ibZ = innerBinderSplit 'x' (closureSplit 1 [])
obZ = outerBinderSplit 0 [] ibZ
in SplitCase "flip" sflip mempty (closureSplit 0 []) (Map.fromList [(0, obZ), (1, obY)])
, let ib = innerBinderSplit 'x' (boundSplit 3)
ob = outerBinderSplit 1 [] ib
in SplitCase "wonky3" swonky3 (mkTrackedBound 3) (closureSplit 0 [3]) (Map.singleton 0 ob)
]
runSplitCase :: SplitCase -> IO ()
runSplitCase (SplitCase _ scopeIn trackedOut scopeOut binders) = do
let SplitResult actualTrackedOut actualScopeOut actualBinders = simpleSplit scopeIn
actualTrackedOut @?= trackedOut
actualScopeOut @?= scopeOut
actualBinders @?= binders
testSplitCase :: SplitCase -> TestTree
testSplitCase c = testCase (splitCaseName c) (runSplitCase c)
testSplit :: TestTree
testSplit = testGroup "Split" (fmap testSplitCase splitCases)