Files
2026-07-13 12:32:14 +08:00

203 lines
4.7 KiB
Go

package tokenizer
import (
"reflect"
"testing"
)
func TestTokenizer_NextTokenType(t *testing.T) {
type Case struct {
input string
expected TokenType
}
cases := []Case{
{input: "SELECT", expected: Select},
{input: "FROM", expected: From},
{input: "WHERE", expected: Where},
{input: "AS", expected: As},
{input: "OR", expected: Or},
{input: "AND", expected: And},
{input: "NOT", expected: Not},
{input: "IN", expected: In},
{input: "IS", expected: Is},
{input: "LIKE", expected: Like},
{input: "RLIKE", expected: RLike},
{input: "foo", expected: Identifier},
{input: "(", expected: OpenParen},
{input: ")", expected: CloseParen},
{input: ",", expected: Comma},
{input: "-", expected: Hyphen},
{input: "=", expected: Equals},
{input: "<>", expected: NotEquals},
{input: "<", expected: LessThan},
{input: "<=", expected: LessThanEquals},
{input: ">", expected: GreaterThan},
{input: ">=", expected: GreaterThanEquals},
}
for _, c := range cases {
actual := NewTokenizer(c.input).Next()
expected := &Token{Type: c.expected, Raw: c.input}
if !reflect.DeepEqual(actual, expected) {
t.Fatalf("\nExpected: %v\n Got: %v", expected, actual)
}
}
}
func TestTokenizer_NextRaw(t *testing.T) {
type Case struct {
input string
expected string
}
// TODO: Fix the last 2 cases, they're currently hanging.
cases := []Case{
{input: "foo", expected: "foo"},
{input: " foo ", expected: "foo"},
{input: "\" foo \"", expected: " foo "},
{input: "' foo '", expected: " foo "},
{input: "` foo `", expected: " foo "},
// Case{input: "\"foo'bar\"", expected: "foo'bar"},
// Case{input: "\"()\"", expected: "()"},
}
for _, c := range cases {
actual := NewTokenizer(c.input).Next()
expected := &Token{Type: Identifier, Raw: c.expected}
if !reflect.DeepEqual(actual, expected) {
t.Fatalf("\nExpected: %v\n Got: %v", expected, actual)
}
}
}
func TestTokenizer_AllSimple(t *testing.T) {
input := `
SELECT
name, size
FROM
~/Desktop
WHERE
name LIKE %go
`
actual := NewTokenizer(input).All()
expected := []Token{
{Type: Select, Raw: "SELECT"},
{Type: Identifier, Raw: "name"},
{Type: Comma, Raw: ","},
{Type: Identifier, Raw: "size"},
{Type: From, Raw: "FROM"},
{Type: Identifier, Raw: "~/Desktop"},
{Type: Where, Raw: "WHERE"},
{Type: Identifier, Raw: "name"},
{Type: Like, Raw: "LIKE"},
{Type: Identifier, Raw: "%go"},
}
for i := range expected {
if !reflect.DeepEqual(actual[i], expected[i]) {
t.Fatalf("\nExpected: %v\n Got: %v", expected[i], actual[i])
}
}
}
func TestTokenizer_AllSubquery(t *testing.T) {
input := `
SELECT
name, size
FROM
~/Desktop
WHERE
name LIKE %go OR
name IN (
SELECT
name
FROM
$GOPATH/src/github.com
WHERE
name RLIKE .*_test\.go)
`
actual := NewTokenizer(input).All()
expected := []Token{
{Type: Select, Raw: "SELECT"},
{Type: Identifier, Raw: "name"},
{Type: Comma, Raw: ","},
{Type: Identifier, Raw: "size"},
{Type: From, Raw: "FROM"},
{Type: Identifier, Raw: "~/Desktop"},
{Type: Where, Raw: "WHERE"},
{Type: Identifier, Raw: "name"},
{Type: Like, Raw: "LIKE"},
{Type: Identifier, Raw: "%go"},
{Type: Or, Raw: "OR"},
{Type: Identifier, Raw: "name"},
{Type: In, Raw: "IN"},
{Type: OpenParen, Raw: "("},
{Type: Subquery, Raw: "SELECT name FROM $GOPATH/src/github.com WHERE name RLIKE .*_test\\.go"},
{Type: CloseParen, Raw: ")"},
}
for i := range expected {
if !reflect.DeepEqual(actual[i], expected[i]) {
t.Fatalf("\nExpected: %v\n Got: %v", expected[i], actual[i])
}
}
}
func TestTokenizer_ReadWord(t *testing.T) {
type Case struct {
input string
expected string
}
cases := []Case{
{input: "foo", expected: "foo"},
{input: "foo bar", expected: "foo"},
{input: "", expected: ""},
}
for _, c := range cases {
actual := NewTokenizer(c.input).readWord()
if !reflect.DeepEqual(actual, c.expected) {
t.Fatalf("\nExpected: %v\n Got: %v", c.expected, actual)
}
}
}
func TestTokenizer_ReadQuery(t *testing.T) {
type Case struct {
input string
expected string
}
// TODO: Complete these cases.
cases := []Case{}
for _, c := range cases {
actual := NewTokenizer(c.input).readQuery()
if !reflect.DeepEqual(actual, c.expected) {
t.Fatalf("\nExpected: %v\n Got: %v", c.expected, actual)
}
}
}
func TestTokenizer_ReadUntil(t *testing.T) {
type Case struct {
input string
until []rune
expected string
}
// TODO: Complete these cases.
cases := []Case{}
for _, c := range cases {
actual := NewTokenizer(c.input).readUntil(c.until...)
if !reflect.DeepEqual(actual, c.expected) {
t.Fatalf("\nExpected: %v\n Got: %v", c.expected, actual)
}
}
}