lisp-interpreter/test/TestParser.hs
2025-03-23 10:40:50 -05:00

180 lines
9.2 KiB
Haskell

module TestParser(tests) where
import Test.HUnit
import Lib
testEmptyAST :: Test
testEmptyAST = TestCase (assertEqual
"empty ASTs are recognized"
[]
(recognizeAST []))
testErrorOnMissingRPar :: Test
testErrorOnMissingRPar = TestCase (assertEqual
"error on missing TokRPar"
[AST [ASTErr "Unexpected EOF"]]
(recognizeAST [TokLPar]))
testErrorOnExtraRPar :: Test
testErrorOnExtraRPar = TestCase (assertEqual
"error on extra TokRPar"
[ASTErr "Unexpected ')'"]
(recognizeAST [TokRPar]))
testErrorOnMissingQuotedItem :: Test
testErrorOnMissingQuotedItem = TestCase (assertEqual
"error when EOF reached immediately after quote"
[ASTQuote (ASTErr "Unexpected EOF")]
(recognizeAST [TokQuote]))
testBasicComponentsAreRecognized :: Test
testBasicComponentsAreRecognized = TestCase (assertEqual
"basic components are recognized"
[
ASTLiteralNumber 123,
ASTLiteralString "hello",
ASTLiteralChar 'a',
ASTSymbol "symbol",
ASTQuote (AST [ASTLiteralChar 'b']),
ASTLiteralNumber 456
]
(recognizeAST [
TokNumber 123,
TokStr "hello",
TokCharacter 'a',
TokSymbol "symbol",
TokQuote,
TokLPar,
TokCharacter 'b',
TokRPar,
TokNumber 456
]
))
testParseAProgram :: Test
testParseAProgram = TestCase (assertEqual
"parse a full program"
[
AST [
ASTSymbol "defun",
ASTSymbol "pomodoro-toggle-state",
AST [],
ASTLiteralString
"Restart the pomodoro timer and switch to the other state.",
AST [ASTSymbol "interactive"],
AST [
ASTSymbol "cond",
AST [
AST [
ASTSymbol "equal",
ASTSymbol "pomodoro-state",
ASTQuote (ASTSymbol "working")
],
AST [
ASTSymbol "setq",
ASTSymbol "pomodoro-state",
ASTQuote (ASTSymbol "break")
]
],
AST [
AST [
ASTSymbol "equal",
ASTSymbol "pomodoro-state",
ASTQuote (ASTSymbol "break")
],
AST [
ASTSymbol "setq",
ASTSymbol "pomodoro-state",
ASTQuote (ASTSymbol "working")
]
],
AST [
ASTSymbol "t",
AST [
ASTSymbol "user-error",
ASTLiteralString "Invalid pomodoro state"
]
]
],
AST [
ASTSymbol "setq",
ASTSymbol "pomodoro-start-time",
AST [
ASTSymbol "floor",
AST [
ASTSymbol "float-time"
]
]
]
]
]
(recognizeAST [
Lib.TokLPar,
Lib.TokSymbol "defun",
Lib.TokSymbol "pomodoro-toggle-state",
Lib.TokLPar,
Lib.TokRPar,
Lib.TokStr "Restart the pomodoro timer and switch to the other state.",
Lib.TokLPar,
Lib.TokSymbol "interactive",
Lib.TokRPar,
Lib.TokLPar,
Lib.TokSymbol "cond",
Lib.TokLPar,
Lib.TokLPar,
Lib.TokSymbol "equal",
Lib.TokSymbol "pomodoro-state",
Lib.TokQuote,
Lib.TokSymbol "working",
Lib.TokRPar,
Lib.TokLPar,
Lib.TokSymbol "setq",
Lib.TokSymbol "pomodoro-state",
Lib.TokQuote,
Lib.TokSymbol "break",
Lib.TokRPar,
Lib.TokRPar,
Lib.TokLPar,
Lib.TokLPar,
Lib.TokSymbol "equal",
Lib.TokSymbol "pomodoro-state",
Lib.TokQuote,
Lib.TokSymbol "break",
Lib.TokRPar,
Lib.TokLPar,
Lib.TokSymbol "setq",
Lib.TokSymbol "pomodoro-state",
Lib.TokQuote,
Lib.TokSymbol "working",
Lib.TokRPar,
Lib.TokRPar,
Lib.TokLPar,
Lib.TokSymbol "t",
Lib.TokLPar,
Lib.TokSymbol "user-error",
Lib.TokStr "Invalid pomodoro state",
Lib.TokRPar,
Lib.TokRPar,
Lib.TokRPar,
Lib.TokLPar,
Lib.TokSymbol "setq",
Lib.TokSymbol "pomodoro-start-time",
Lib.TokLPar,
Lib.TokSymbol "floor",
Lib.TokLPar,
Lib.TokSymbol "float-time",
Lib.TokRPar,
Lib.TokRPar,
Lib.TokRPar,
Lib.TokRPar
]))
tests :: Test
tests = TestList [
TestLabel "empty ASTs are recognized" testEmptyAST,
TestLabel "missing TokRPar causes an error" testErrorOnMissingRPar,
TestLabel "extra TokRPar causes an error" testErrorOnExtraRPar,
TestLabel "missing item from quote causes an error" testErrorOnMissingQuotedItem,
TestLabel "all basic components are recognized" testBasicComponentsAreRecognized,
TestLabel "parse a full program" testParseAProgram
]