|
| 1 | +module Test.LambdaBuffers.Compiler.ClassClosure ( |
| 2 | + tests, |
| 3 | +) where |
| 4 | + |
| 5 | +import Control.Lens ((^.)) |
| 6 | +import Data.Foldable (Foldable (toList)) |
| 7 | +import Data.Map qualified as Map |
| 8 | +import Data.Set qualified as Set |
| 9 | +import Data.Text (Text) |
| 10 | +import LambdaBuffers.ProtoCompat qualified as PC |
| 11 | +import Test.LambdaBuffers.ProtoCompat.Utils qualified as U |
| 12 | +import Test.Tasty (TestName, TestTree, testGroup) |
| 13 | +import Test.Tasty.HUnit (testCase, (@?=)) |
| 14 | +import Prelude (Monoid (mconcat), Show (show), zip, ($), (.), (<$>), (<>)) |
| 15 | + |
| 16 | +tests :: TestTree |
| 17 | +tests = |
| 18 | + testGroup |
| 19 | + "LambdaBuffers.Compiler.ClassClosure checks" |
| 20 | + [ testGroup |
| 21 | + "All classes in closure and related rules should be removed" |
| 22 | + [ classClosureTest "test1" [(["Prelude"], "Ord")] [(["Prelude"], "Eq"), (["Prelude"], "Ord")] test1 |
| 23 | + ] |
| 24 | + ] |
| 25 | + |
| 26 | +classClosureTest :: TestName -> [([Text], Text)] -> [([Text], Text)] -> (PC.CompilerInput, PC.CompilerInput) -> TestTree |
| 27 | +classClosureTest title cls clsWant (ciIn, ciWant) = |
| 28 | + let |
| 29 | + classRels = PC.indexClassRelations ciIn |
| 30 | + cls' = Set.fromList [U.qcln' (U.mn mn) clN | (mn, clN) <- cls] |
| 31 | + clsWant' = Set.fromList [U.qcln' (U.mn mn) clN | (mn, clN) <- clsWant] |
| 32 | + cls'' = PC.classClosure classRels cls' |
| 33 | + clsWant'' = PC.classClosure classRels clsWant' |
| 34 | + ciGot = PC.CompilerInput $ PC.filterClassInModule cls'' <$> ciIn ^. #modules |
| 35 | + in |
| 36 | + testGroup |
| 37 | + title |
| 38 | + $ testCase "Class closure should be" (cls'' @?= clsWant'') |
| 39 | + : ( [ testGroup |
| 40 | + (PC.prettyModuleName (mGot' ^. #moduleName)) |
| 41 | + [ testCase "Class definitions should match" $ (mGot' ^. #classDefs) @?= (mWant ^. #classDefs) |
| 42 | + , testCase "Instances should match" $ (mGot' ^. #instances) @?= (mWant ^. #instances) |
| 43 | + , testCase "Derives should match" $ (mGot' ^. #derives) @?= (mWant ^. #derives) |
| 44 | + ] |
| 45 | + | (mWant, mGot') <- zip (toList $ ciWant ^. #modules) (toList $ ciGot ^. #modules) |
| 46 | + ] |
| 47 | + ) |
| 48 | + |
| 49 | +test1 :: (PC.CompilerInput, PC.CompilerInput) |
| 50 | +test1 = |
| 51 | + ( U.ci |
| 52 | + [ U.mod'preludeO |
| 53 | + , U.mod' |
| 54 | + ["Foo"] |
| 55 | + [ U.td |
| 56 | + "Foo" |
| 57 | + ( U.abs ["a", "b", "c"] $ |
| 58 | + U.sum |
| 59 | + [ ("MkFoo", [U.fr ["Prelude"] "Either" U.@ [U.fr ["Prelude"] "Int8", U.tv "a"]]) |
| 60 | + , ("MkBar", [U.fr ["Prelude"] "Maybe" U.@ [U.tv "b"], U.fr ["Prelude"] "List" U.@ [U.tv "b"]]) |
| 61 | + , ("MkBaz", [U.fr ["Prelude"] "Map" U.@ [U.tv "b", U.tv "c"]]) |
| 62 | + ] |
| 63 | + ) |
| 64 | + ] |
| 65 | + [] |
| 66 | + [] |
| 67 | + [ deriveEq (U.lr "Foo" U.@ [U.tv "a", U.tv "b", U.tv "c"]) |
| 68 | + , deriveOrd (U.lr "Foo" U.@ [U.tv "a", U.tv "b", U.tv "c"]) |
| 69 | + ] |
| 70 | + [["Prelude"]] |
| 71 | + ] |
| 72 | + , U.ci |
| 73 | + [ U.mod'preludeO {PC.classDefs = Map.empty, PC.instances = []} |
| 74 | + , U.mod' |
| 75 | + ["Foo"] |
| 76 | + [ U.td |
| 77 | + "Foo" |
| 78 | + ( U.abs ["a", "b", "c"] $ |
| 79 | + U.sum |
| 80 | + [ ("MkFoo", [U.fr ["Prelude"] "Either" U.@ [U.fr ["Prelude"] "Int8", U.tv "a"]]) |
| 81 | + , ("MkBar", [U.fr ["Prelude"] "Maybe" U.@ [U.tv "b"], U.fr ["Prelude"] "List" U.@ [U.tv "b"]]) |
| 82 | + , ("MkBaz", [U.fr ["Prelude"] "Map" U.@ [U.tv "b", U.tv "c"]]) |
| 83 | + ] |
| 84 | + ) |
| 85 | + ] |
| 86 | + [] |
| 87 | + [] |
| 88 | + [deriveEq (U.lr "Foo" U.@ [U.tv "a", U.tv "b", U.tv "c"])] |
| 89 | + [["Prelude"]] |
| 90 | + ] |
| 91 | + ) |
| 92 | + |
| 93 | +deriveEq :: PC.Ty -> PC.Derive |
| 94 | +deriveEq = U.drv . eqCstr |
| 95 | + |
| 96 | +eqCstr :: PC.Ty -> PC.Constraint |
| 97 | +eqCstr = U.cstr (U.fcr ["Prelude"] "Eq") |
| 98 | + |
| 99 | +deriveOrd :: PC.Ty -> PC.Derive |
| 100 | +deriveOrd = U.drv . ordCstr |
| 101 | + |
| 102 | +ordCstr :: PC.Ty -> PC.Constraint |
| 103 | +ordCstr = U.cstr (U.fcr ["Prelude"] "Ord") |
0 commit comments