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 ]