Download test/Test/Backend/TermCompiler.hs from Snapkitty/assertica: direct link, hf CLI and curl.
- Browser
- Download file 11.7 kB
-
https://huggingface.co/Snapkitty/assertica/resolve/main/test/Test/Backend/TermCompiler.hs
- Command line
-
hf download hf://Snapkitty/assertica/test/Test/Backend/TermCompiler.hs
-
curl -L -o TermCompiler.hs https://huggingface.co/Snapkitty/assertica/resolve/main/test/Test/Backend/TermCompiler.hs
11.7 kB
| module Test.Backend.TermCompiler | |
| ( tests | |
| ) where | |
| import Test.Tasty | |
| import Test.Tasty.HUnit | |
| import qualified Data.Text as T | |
| import Data.Text (Text) | |
| import qualified Data.Set as Set | |
| import Assertica.Core.AST | |
| import Assertica.Backend.CodeGen (defaultConfig) | |
| import Assertica.Backend.TermCompiler | |
| -- ============================================================================ | |
| -- TEST SUITE | |
| -- ============================================================================ | |
| tests :: TestTree | |
| tests = testGroup "Assertica.Backend.TermCompiler" | |
| [ testGroup "Variable Compilation" | |
| [ testCase "Compile simple variable" testSimpleVariable | |
| , testCase "Variable name preserved" testVariableNamePreserved | |
| ] | |
| , testGroup "Constant Compilation" | |
| [ testCase "Compile integer constant" testIntConstant | |
| , testCase "Compile boolean constant" testBoolConstant | |
| , testCase "Compile unit constant" testUnitConst | |
| ] | |
| , testGroup "Lambda Abstraction" | |
| [ testCase "Compile simple lambda" testSimpleLambda | |
| , testCase "Lambda contains backslash" testLambdaBackslash | |
| , testCase "Nested lambda" testNestedLambda | |
| ] | |
| , testGroup "Function Application" | |
| [ testCase "Simple application" testSimpleApplication | |
| , testCase "Application with multiple args" testMultipleApplication | |
| ] | |
| , testGroup "Data Constructors" | |
| [ testCase "Simple constructor" testSimpleConstructor | |
| , testCase "Constructor with arguments" testConstructorWithArgs | |
| ] | |
| , testGroup "Case Expressions" | |
| [ testCase "Simple case" testSimpleCase | |
| , testCase "Case with default" testCaseWithDefault | |
| ] | |
| , testGroup "Let-Bindings" | |
| [ testCase "Simple let binding" testSimpleLet | |
| , testCase "Let with variable in body" testLetWithVar | |
| ] | |
| , testGroup "Type Annotation" | |
| [ testCase "Annotated term" testAnnotatedTerm | |
| ] | |
| , testGroup "Pattern Matching" | |
| [ testCase "Variable pattern" testPatternVar | |
| , testCase "Constructor pattern" testPatternConstructor | |
| , testCase "Wildcard pattern" testPatternWildcard | |
| ] | |
| , testGroup "Determinism" | |
| [ testCase "Compilation is deterministic" testDeterminism | |
| ] | |
| ] | |
| -- ============================================================================ | |
| -- UNIT TESTS: VARIABLES | |
| -- ============================================================================ | |
| testSimpleVariable :: Assertion | |
| testSimpleVariable = do | |
| let var = Var (Var "x" 0) | |
| result <- case compileTerm defaultConfig var of | |
| Right x -> return x | |
| Left err -> assertFailure $ "Unexpected error: " ++ err | |
| assertEqual "Should be x" "x" result | |
| testVariableNamePreserved :: Assertion | |
| testVariableNamePreserved = do | |
| let var = Var (Var "myVar" 42) -- ID should be ignored in output | |
| result <- case compileTerm defaultConfig var of | |
| Right x -> return x | |
| Left err -> assertFailure $ "Unexpected error: " ++ err | |
| assertEqual "Should be myVar" "myVar" result | |
| -- ============================================================================ | |
| -- UNIT TESTS: CONSTANTS | |
| -- ============================================================================ | |
| testIntConstant :: Assertion | |
| testIntConstant = do | |
| let term = Const (IntLit 123) | |
| result <- case compileTerm defaultConfig term of | |
| Right x -> return x | |
| Left err -> assertFailure $ "Unexpected error: " ++ err | |
| assertEqual "Should be 123" "123" result | |
| testBoolConstant :: Assertion | |
| testBoolConstant = do | |
| let term = Const (BoolLit True) | |
| result <- case compileTerm defaultConfig term of | |
| Right x -> return x | |
| Left err -> assertFailure $ "Unexpected error: " ++ err | |
| assertEqual "Should be True" "True" result | |
| testUnitConst :: Assertion | |
| testUnitConst = do | |
| let term = Const UnitConst | |
| result <- case compileTerm defaultConfig term of | |
| Right x -> return x | |
| Left err -> assertFailure $ "Unexpected error: " ++ err | |
| assertEqual "Should be ()" "()" result | |
| -- ============================================================================ | |
| -- UNIT TESTS: LAMBDA | |
| -- ============================================================================ | |
| testSimpleLambda :: Assertion | |
| testSimpleLambda = do | |
| let lambda = Lam (Binder (Var "x" 0) Nothing) (Var (Var "x" 0)) | |
| result <- case compileTerm defaultConfig lambda of | |
| Right x -> return x | |
| Left err -> assertFailure $ "Unexpected error: " ++ err | |
| assertBool "Should contain backslash" ("\\" `T.isInfixOf` result) | |
| assertBool "Should contain x" ("x" `T.isInfixOf` result) | |
| testLambdaBackslash :: Assertion | |
| testLambdaBackslash = do | |
| let lambda = Lam (Binder (Var "f" 0) Nothing) (Var (Var "f" 0)) | |
| result <- case compileTerm defaultConfig lambda of | |
| Right x -> return x | |
| Left err -> assertFailure $ "Unexpected error: " ++ err | |
| assertBool "Should start with lambda" ("(\\" `T.isInfixOf` result) | |
| testNestedLambda :: Assertion | |
| testNestedLambda = do | |
| let inner = Lam (Binder (Var "y" 0) Nothing) (Var (Var "y" 0)) | |
| let outer = Lam (Binder (Var "x" 0) Nothing) inner | |
| result <- case compileTerm defaultConfig outer of | |
| Right x -> return x | |
| Left err -> assertFailure $ "Unexpected error: " ++ err | |
| assertBool "Should contain x" ("x" `T.isInfixOf` result) | |
| assertBool "Should contain y" ("y" `T.isInfixOf` result) | |
| -- ============================================================================ | |
| -- UNIT TESTS: APPLICATION | |
| -- ============================================================================ | |
| testSimpleApplication :: Assertion | |
| testSimpleApplication = do | |
| let f = Var (Var "f" 0) | |
| let x = Var (Var "x" 0) | |
| let app = App f x | |
| result <- case compileTerm defaultConfig app of | |
| Right x -> return x | |
| Left err -> assertFailure $ "Unexpected error: " ++ err | |
| assertBool "Should contain f" ("f" `T.isInfixOf` result) | |
| assertBool "Should contain x" ("x" `T.isInfixOf` result) | |
| testMultipleApplication :: Assertion | |
| testMultipleApplication = do | |
| let f = Var (Var "f" 0) | |
| let x = Var (Var "x" 0) | |
| let y = Var (Var "y" 0) | |
| let app1 = App f x | |
| let app2 = App app1 y | |
| result <- case compileTerm defaultConfig app2 of | |
| Right x -> return x | |
| Left err -> assertFailure $ "Unexpected error: " ++ err | |
| -- Result should contain all three variables | |
| let hasAll = "f" `T.isInfixOf` result && | |
| "x" `T.isInfixOf` result && | |
| "y" `T.isInfixOf` result | |
| assertBool "Should contain all variables" hasAll | |
| -- ============================================================================ | |
| -- UNIT TESTS: CONSTRUCTORS | |
| -- ============================================================================ | |
| testSimpleConstructor :: Assertion | |
| testSimpleConstructor = do | |
| let ctor = Constr (QName [] "True") [] | |
| result <- case compileTerm defaultConfig ctor of | |
| Right x -> return x | |
| Left err -> assertFailure $ "Unexpected error: " ++ err | |
| assertEqual "Should be True" "True" result | |
| testConstructorWithArgs :: Assertion | |
| testConstructorWithArgs = do | |
| let x = Var (Var "x" 0) | |
| let y = Var (Var "y" 0) | |
| let pair = Constr (QName ["Data", "Tuple"] "Pair") [x, y] | |
| result <- case compileTerm defaultConfig pair of | |
| Right r -> return r | |
| Left err -> assertFailure $ "Unexpected error: " ++ err | |
| assertBool "Should contain Pair" ("Pair" `T.isInfixOf` result) | |
| assertBool "Should contain x" ("x" `T.isInfixOf` result) | |
| assertBool "Should contain y" ("y" `T.isInfixOf` result) | |
| -- ============================================================================ | |
| -- UNIT TESTS: CASE EXPRESSIONS | |
| -- ============================================================================ | |
| testSimpleCase :: Assertion | |
| testSimpleCase = do | |
| let scrutinee = Var (Var "x" 0) | |
| let trueClause = Clause (PatConstr (QName [] "True") []) (Const (IntLit 1)) | |
| let falseClause = Clause (PatConstr (QName [] "False") []) (Const (IntLit 0)) | |
| let caseExpr = Case scrutinee [trueClause, falseClause] Nothing | |
| result <- case compileTerm defaultConfig caseExpr of | |
| Right r -> return r | |
| Left err -> assertFailure $ "Unexpected error: " ++ err | |
| assertBool "Should contain case" ("case" `T.isInfixOf` result) | |
| assertBool "Should contain scrutinee" ("x" `T.isInfixOf` result) | |
| testCaseWithDefault :: Assertion | |
| testCaseWithDefault = do | |
| let scrutinee = Var (Var "x" 0) | |
| let defaultBody = Const (IntLit 42) | |
| let caseExpr = Case scrutinee [] (Just defaultBody) | |
| result <- case compileTerm defaultConfig caseExpr of | |
| Right r -> return r | |
| Left err -> assertFailure $ "Unexpected error: " ++ err | |
| assertBool "Should be valid case" (not (T.null result)) | |
| -- ============================================================================ | |
| -- UNIT TESTS: LET-BINDINGS | |
| -- ============================================================================ | |
| testSimpleLet :: Assertion | |
| testSimpleLet = do | |
| let bindValue = Const (IntLit 5) | |
| let bodyExpr = Var (Var "x" 0) | |
| let letExpr = Let (Binder (Var "x" 0) Nothing) bindValue bodyExpr | |
| result <- case compileTerm defaultConfig letExpr of | |
| Right r -> return r | |
| Left err -> assertFailure $ "Unexpected error: " ++ err | |
| assertBool "Should contain let" ("let" `T.isInfixOf` result) | |
| assertBool "Should contain 5" ("5" `T.isInfixOf` result) | |
| testLetWithVar :: Assertion | |
| testLetWithVar = do | |
| let bindValue = Const (IntLit 10) | |
| let bodyExpr = Var (Var "x" 0) | |
| let letExpr = Let (Binder (Var "x" 0) Nothing) bindValue bodyExpr | |
| result <- case compileTerm defaultConfig letExpr of | |
| Right r -> return r | |
| Left err -> assertFailure $ "Unexpected error: " ++ err | |
| assertBool "Should contain in" ("in" `T.isInfixOf` result) | |
| -- ============================================================================ | |
| -- UNIT TESTS: ANNOTATIONS | |
| -- ============================================================================ | |
| testAnnotatedTerm :: Assertion | |
| testAnnotatedTerm = do | |
| let term = Var (Var "x" 0) | |
| let ty = TyConst (QName [] "Int") [] | |
| let annTerm = Ann term ty | |
| result <- case compileTerm defaultConfig annTerm of | |
| Right r -> return r | |
| Left err -> assertFailure $ "Unexpected error: " ++ err | |
| assertBool "Should contain variable" ("x" `T.isInfixOf` result) | |
| -- ============================================================================ | |
| -- UNIT TESTS: PATTERNS | |
| -- ============================================================================ | |
| testPatternVar :: Assertion | |
| testPatternVar = do | |
| let pat = PatVar (Var "x" 0) | |
| result <- case compilePattern pat of | |
| Right r -> return r | |
| Left err -> assertFailure $ "Unexpected error: " ++ err | |
| assertEqual "Should be x" "x" result | |
| testPatternConstructor :: Assertion | |
| testPatternConstructor = do | |
| let pat = PatConstr (QName [] "Cons") | |
| [ PatVar (Var "x" 0) | |
| , PatVar (Var "xs" 0) | |
| ] | |
| result <- case compilePattern pat of | |
| Right r -> return r | |
| Left err -> assertFailure $ "Unexpected error: " ++ err | |
| assertBool "Should contain Cons" ("Cons" `T.isInfixOf` result) | |
| assertBool "Should contain x" ("x" `T.isInfixOf` result) | |
| testPatternWildcard :: Assertion | |
| testPatternWildcard = do | |
| let pat = PatWildcard | |
| result <- case compilePattern pat of | |
| Right r -> return r | |
| Left err -> assertFailure $ "Unexpected error: " ++ err | |
| assertEqual "Should be wildcard" "_" result | |
| -- ============================================================================ | |
| -- PROPERTY TESTS | |
| -- ============================================================================ | |
| testDeterminism :: Assertion | |
| testDeterminism = do | |
| let term = App (Var (Var "f" 0)) (Const (IntLit 42)) | |
| let result1 = compileTerm defaultConfig term | |
| let result2 = compileTerm defaultConfig term | |
| assertEqual "Compilation should be deterministic" result1 result2 | |