yvbolt/lexer/lexer_test.go

126 lines
2.5 KiB
Go

package lexer
import (
"reflect"
"testing"
)
func TestLexer(t *testing.T) {
type testCase struct {
input string
expect []string
expectErr bool
}
cases := []testCase{
testCase{
input: "foo bar baz",
expect: []string{"foo", "bar", "baz"},
expectErr: false,
},
// Quotes
testCase{
input: `foo "bar" baz`,
expect: []string{"foo", `"bar"`, "baz"},
expectErr: false,
},
testCase{
input: `foo "bar baz" quux`,
expect: []string{"foo", `"bar baz"`, "quux"},
expectErr: false,
},
testCase{
input: `foo 'bar baz' quux`,
expect: []string{"foo", `'bar baz'`, "quux"},
expectErr: false,
},
// Escape characters
testCase{
input: `foo 'bar \n baz' quux`,
expect: []string{"foo", `'bar \n baz'`, "quux"},
expectErr: false,
},
testCase{
input: `foo "bar\"" baz`,
expect: []string{"foo", `"bar\""`, "baz"},
expectErr: false,
},
// Collapsing whitespace
testCase{
input: " foo bar \r\t\n baz\n",
expect: []string{"foo", "bar", "baz"},
expectErr: false,
},
// Special characters lexed as separate tokens, but only at top level
testCase{
input: `3+5*(2.3/6);`,
expect: []string{"3", `+`, "5", "*", "(", "2.3", "/", "6", ")", ";"},
expectErr: false,
},
testCase{
input: `SELECT "3+5*(2.3/6)" AS expression;`,
expect: []string{"SELECT", `"3+5*(2.3/6)"`, "AS", "expression", ";"},
expectErr: false,
},
testCase{
input: `INSERT INTO foo (bar, baz) VALUES (?, ?);`,
expect: []string{"INSERT", "INTO", "foo", "(", "bar", ",", "baz", ")", "VALUES", "(", "?", ",", "?", ")", ";"},
expectErr: false,
},
// Errors
testCase{
input: `foo "bar`,
expect: nil,
expectErr: true, // mismatched quotes
},
testCase{
input: `foo 'bar`,
expect: nil,
expectErr: true, // mismatched quotes
},
testCase{
input: `foo \"bar"`,
expect: nil,
expectErr: true, // invalid top-level escape
},
testCase{
input: `foo "bar\ "`,
expect: nil,
expectErr: true, // escaping nothing
},
}
for _, tc := range cases {
out, err := Fields(tc.input)
if err != nil {
if !tc.expectErr {
t.Errorf("Test %q got error %v, expected nil", tc.input, err)
}
} else {
if tc.expectErr {
t.Errorf("Test %q got error <nil>, expected error", tc.input)
continue
}
if !reflect.DeepEqual(out, tc.expect) {
t.Errorf("Test %q\n- got: %#v\n- expected %#v", tc.input, out, tc.expect)
}
}
}
}