aboutsummaryrefslogtreecommitdiff
path: root/parser/parser_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'parser/parser_test.go')
-rw-r--r--parser/parser_test.go91
1 files changed, 91 insertions, 0 deletions
diff --git a/parser/parser_test.go b/parser/parser_test.go
new file mode 100644
index 0000000..8f78c8b
--- /dev/null
+++ b/parser/parser_test.go
@@ -0,0 +1,91 @@
+package parser
+
+import (
+ "testing"
+ "mana/ast"
+ "mana/lexer"
+)
+
+func TestLetStatements(t *testing.T) {
+ const input string = `
+ let x = 5;
+ let y = 10;
+ let foobar = 838383;
+ `
+
+ var l *lexer.Lexer = lexer.New(input)
+ var p *Parser = New(l)
+
+ var program *ast.Program = p.ParseProgram()
+ checkParserErrors(t, p)
+
+ if program == nil {
+ t.Fatalf("ParseProgram() returned nil")
+ }
+
+ if len(program.Statements) != 3 {
+ t.Fatalf("program.Statements does not contain 3 statements. got=%d", len(program.Statements))
+ }
+
+ var tests = []struct {
+ expectedIdentifier string
+ }{
+ {"x"},
+ {"y"},
+ {"foobar"},
+ }
+
+ for i, tt := range tests {
+ var stmt ast.Statement = program.Statements[i]
+
+ if !testLetStatement(t, stmt, tt.expectedIdentifier) {
+ return
+ }
+ }
+}
+
+func checkParserErrors(t *testing.T, p *Parser) {
+ var errors []string = p.Errors()
+
+ if len(errors) == 0 {
+ return
+ }
+
+ t.Errorf("parser has %d errors", len(errors))
+
+ for _, msg := range errors {
+ t.Errorf("parser error: %q", msg)
+ }
+
+ t.FailNow()
+}
+
+func testLetStatement(t *testing.T, s ast.Statement, name string) bool {
+ if s.TokenLiteral() != "let" {
+ t.Errorf("s.TokenLiteral not 'let'. got=%q", s.TokenLiteral())
+
+ return false
+ }
+
+ var letStmt, ok = s.(*ast.LetStatement)
+
+ if !ok {
+ t.Errorf("s not *ast.LetStatement. got=%T", s)
+
+ return false
+ }
+
+ if letStmt.Name.Value != name {
+ t.Errorf("letStmt.Name.Value not '%s'. got=%s", name, letStmt.Name.Value)
+
+ return false
+ }
+
+ if letStmt.Name.TokenLiteral() != name {
+ t.Errorf("letStmt.Name.TokenLiteral() not '%s'. got=%s", name, letStmt.Name.TokenLiteral())
+
+ return false
+ }
+
+ return true
+}