Files
monkey/lexer/lexer_test.go
Chuck Smith 66d5453ecc
Some checks failed
Build / build (push) Successful in 10m20s
Test / build (push) Failing after 16m7s
selectors support for hash
2024-03-21 16:39:31 -04:00

208 lines
4.0 KiB
Go

package lexer
import (
"monkey/token"
"testing"
)
func TestNextToken(t *testing.T) {
input := `#!./monkey-lang
let five = 5;
let ten = 10;
let add = fn(x, y) {
x + y;
};
# this is a comment
let result = add(five, ten);
!-/*5;
5 < 10 > 5;
if (5 < 10) {
return true;
} else {
return false;
}
// this is another comment
10 == 10;
10 != 9;
"foobar"
"foo bar"
[1, 2];
{"foo": "bar"}
d.foo
`
tests := []struct {
expectedType token.TokenType
expectedLiteral string
}{
{token.COMMENT, "!./monkey-lang"},
{token.LET, "let"},
{token.IDENT, "five"},
{token.ASSIGN, "="},
{token.INT, "5"},
{token.SEMICOLON, ";"},
{token.LET, "let"},
{token.IDENT, "ten"},
{token.ASSIGN, "="},
{token.INT, "10"},
{token.SEMICOLON, ";"},
{token.LET, "let"},
{token.IDENT, "add"},
{token.ASSIGN, "="},
{token.FUNCTION, "fn"},
{token.LPAREN, "("},
{token.IDENT, "x"},
{token.COMMA, ","},
{token.IDENT, "y"},
{token.RPAREN, ")"},
{token.LBRACE, "{"},
{token.IDENT, "x"},
{token.PLUS, "+"},
{token.IDENT, "y"},
{token.SEMICOLON, ";"},
{token.RBRACE, "}"},
{token.SEMICOLON, ";"},
{token.COMMENT, " this is a comment"},
{token.LET, "let"},
{token.IDENT, "result"},
{token.ASSIGN, "="},
{token.IDENT, "add"},
{token.LPAREN, "("},
{token.IDENT, "five"},
{token.COMMA, ","},
{token.IDENT, "ten"},
{token.RPAREN, ")"},
{token.SEMICOLON, ";"},
{token.BANG, "!"},
{token.MINUS, "-"},
{token.SLASH, "/"},
{token.ASTERISK, "*"},
{token.INT, "5"},
{token.SEMICOLON, ";"},
{token.INT, "5"},
{token.LT, "<"},
{token.INT, "10"},
{token.GT, ">"},
{token.INT, "5"},
{token.SEMICOLON, ";"},
{token.IF, "if"},
{token.LPAREN, "("},
{token.INT, "5"},
{token.LT, "<"},
{token.INT, "10"},
{token.RPAREN, ")"},
{token.LBRACE, "{"},
{token.RETURN, "return"},
{token.TRUE, "true"},
{token.SEMICOLON, ";"},
{token.RBRACE, "}"},
{token.ELSE, "else"},
{token.LBRACE, "{"},
{token.RETURN, "return"},
{token.FALSE, "false"},
{token.SEMICOLON, ";"},
{token.RBRACE, "}"},
{token.COMMENT, " this is another comment"},
{token.INT, "10"},
{token.EQ, "=="},
{token.INT, "10"},
{token.SEMICOLON, ";"},
{token.INT, "10"},
{token.NOT_EQ, "!="},
{token.INT, "9"},
{token.SEMICOLON, ";"},
{token.STRING, "foobar"},
{token.STRING, "foo bar"},
{token.LBRACKET, "["},
{token.INT, "1"},
{token.COMMA, ","},
{token.INT, "2"},
{token.RBRACKET, "]"},
{token.SEMICOLON, ";"},
{token.LBRACE, "{"},
{token.STRING, "foo"},
{token.COLON, ":"},
{token.STRING, "bar"},
{token.RBRACE, "}"},
{token.IDENT, "d"},
{token.DOT, "."},
{token.IDENT, "foo"},
{token.EOF, ""},
}
l := New(input)
for i, tt := range tests {
tok := l.NextToken()
if tok.Type != tt.expectedType {
t.Fatalf("tests[%d] - tokentype wrong. expected=%q, got=%q",
i, tt.expectedType, tok.Type)
}
if tok.Literal != tt.expectedLiteral {
t.Fatalf("tests[%d] - literal wrong. expected=%q, got=%q",
i, tt.expectedLiteral, tok.Literal)
}
}
}
func TestStringEscapes(t *testing.T) {
input := `#!./monkey-lang
let a = "\"foo\""
let b = "\x00\x0a\x7f"
let c = "\r\n\t"
`
tests := []struct {
expectedType token.TokenType
expectedLiteral string
}{
{token.COMMENT, "!./monkey-lang"},
{token.LET, "let"},
{token.IDENT, "a"},
{token.ASSIGN, "="},
{token.STRING, "\"foo\""},
{token.LET, "let"},
{token.IDENT, "b"},
{token.ASSIGN, "="},
{token.STRING, "\x00\n\u007f"},
{token.LET, "let"},
{token.IDENT, "c"},
{token.ASSIGN, "="},
{token.STRING, "\r\n\t"},
{token.EOF, ""},
}
lexer := New(input)
for i, test := range tests {
token := lexer.NextToken()
if token.Type != test.expectedType {
t.Fatalf("tests[%d] - token type wrong. expected=%q, got=%q",
i, test.expectedType, token.Type)
}
if token.Literal != test.expectedLiteral {
t.Fatalf("tests[%d] - literal wrong. expected=%q, got=%q",
i, test.expectedLiteral, token.Literal)
}
}
}