mirror of
https://github.com/hanzo-ds/sqlparser.git
synced 2026-10-30 20:53:50 +00:00
245 lines
5.8 KiB
Go
245 lines
5.8 KiB
Go
package parser
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestConsumeComment(t *testing.T) {
|
|
comments := []string{
|
|
"-- hello world",
|
|
"-- hello world\n",
|
|
"-- hello world\r\n",
|
|
"-- hello world\r",
|
|
"/* hello world */",
|
|
"/* hello world */\n",
|
|
"/* hello world */\r\n",
|
|
"/* hello world */\r",
|
|
"/* hello world */ /* hello world */",
|
|
"/* hello world */ /* hello world */\n",
|
|
"/* hello world */ /* hello world */\r\n",
|
|
"/* hello world */ /* hello world */\r",
|
|
}
|
|
for _, c := range comments {
|
|
lexer := NewLexer(c)
|
|
err := lexer.consumeToken()
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
}
|
|
|
|
func TestConsumeString(t *testing.T) {
|
|
t.Run("Simple strings", func(t *testing.T) {
|
|
strs := []string{
|
|
"'hello world'",
|
|
"'123'",
|
|
}
|
|
for _, s := range strs {
|
|
lexer := NewLexer(s)
|
|
err := lexer.consumeToken()
|
|
require.NoError(t, err)
|
|
require.Equal(t, TokenKindString, lexer.lastToken.Kind)
|
|
require.Equal(t, strings.Trim(s, "'"), lexer.lastToken.String)
|
|
require.True(t, lexer.isEOF())
|
|
}
|
|
})
|
|
|
|
t.Run("Strings with backslash-escaped quotes", func(t *testing.T) {
|
|
testCases := []struct {
|
|
input string
|
|
expected string
|
|
}{
|
|
{`'hello\'world'`, `hello\'world`},
|
|
{`'test\''`, `test\'`},
|
|
{`'\'abc\''`, `\'abc\'`},
|
|
}
|
|
for _, tc := range testCases {
|
|
lexer := NewLexer(tc.input)
|
|
err := lexer.consumeToken()
|
|
require.NoError(t, err, "Failed to parse: %s", tc.input)
|
|
require.Equal(t, TokenKindString, lexer.lastToken.Kind)
|
|
require.Equal(t, tc.expected, lexer.lastToken.String)
|
|
require.True(t, lexer.isEOF())
|
|
}
|
|
})
|
|
|
|
t.Run("Strings with double single quotes", func(t *testing.T) {
|
|
testCases := []struct {
|
|
input string
|
|
expected string
|
|
}{
|
|
{`'hello''world'`, `hello''world`},
|
|
{`'test''123'`, `test''123`},
|
|
{`'abc''def''ghi'`, `abc''def''ghi`},
|
|
}
|
|
for _, tc := range testCases {
|
|
lexer := NewLexer(tc.input)
|
|
err := lexer.consumeToken()
|
|
require.NoError(t, err, "Failed to parse: %s", tc.input)
|
|
require.Equal(t, TokenKindString, lexer.lastToken.Kind)
|
|
require.Equal(t, tc.expected, lexer.lastToken.String)
|
|
require.True(t, lexer.isEOF())
|
|
}
|
|
})
|
|
|
|
t.Run("Strings with backslash-escaped backslashes", func(t *testing.T) {
|
|
testCases := []struct {
|
|
input string
|
|
expected string
|
|
}{
|
|
{`'a\\b'`, `a\\b`},
|
|
{`'test\\123'`, `test\\123`},
|
|
}
|
|
for _, tc := range testCases {
|
|
lexer := NewLexer(tc.input)
|
|
err := lexer.consumeToken()
|
|
require.NoError(t, err, "Failed to parse: %s", tc.input)
|
|
require.Equal(t, TokenKindString, lexer.lastToken.Kind)
|
|
require.Equal(t, tc.expected, lexer.lastToken.String)
|
|
require.True(t, lexer.isEOF())
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestConsumeNumber(t *testing.T) {
|
|
t.Run("Integer number", func(t *testing.T) {
|
|
integers := []string{
|
|
"123",
|
|
"123e+10",
|
|
"123e-10",
|
|
"123e10",
|
|
"123E10",
|
|
"123E+10",
|
|
"123E-10",
|
|
}
|
|
for _, i := range integers {
|
|
lexer := NewLexer(i)
|
|
err := lexer.consumeToken()
|
|
require.NoError(t, err)
|
|
require.Equal(t, TokenKindInt, lexer.lastToken.Kind)
|
|
require.Equal(t, 10, lexer.lastToken.Base)
|
|
require.Equal(t, i, lexer.lastToken.String)
|
|
require.True(t, lexer.isEOF())
|
|
}
|
|
})
|
|
|
|
t.Run("Hexadecimal number", func(t *testing.T) {
|
|
numbers := []string{
|
|
"0x123",
|
|
"0x1",
|
|
}
|
|
for _, n := range numbers {
|
|
lexer := NewLexer(n)
|
|
err := lexer.consumeToken()
|
|
require.NoError(t, err)
|
|
require.Equal(t, TokenKindInt, lexer.lastToken.Kind)
|
|
require.Equal(t, 16, lexer.lastToken.Base)
|
|
require.Equal(t, n, lexer.lastToken.String)
|
|
require.True(t, lexer.isEOF())
|
|
}
|
|
})
|
|
|
|
t.Run("Invalid number", func(t *testing.T) {
|
|
invalidNumbers := []string{
|
|
"123e",
|
|
"123e+",
|
|
"123e-",
|
|
"123e",
|
|
"123E",
|
|
"123E+",
|
|
"123E-",
|
|
"0x",
|
|
"0xg",
|
|
}
|
|
for _, n := range invalidNumbers {
|
|
lexer := NewLexer(n)
|
|
err := lexer.consumeToken()
|
|
require.Error(t, err)
|
|
}
|
|
})
|
|
|
|
t.Run("Float number", func(t *testing.T) {
|
|
floats := []string{
|
|
"123.456",
|
|
"123.456e+10",
|
|
"123.456e-10",
|
|
"123.456e10",
|
|
"123.456E10",
|
|
"123.456E+10",
|
|
"123.456E-10",
|
|
}
|
|
for _, f := range floats {
|
|
lexer := NewLexer(f)
|
|
err := lexer.consumeToken()
|
|
require.NoError(t, err)
|
|
require.Equal(t, TokenKindFloat, lexer.lastToken.Kind)
|
|
require.Equal(t, f, lexer.lastToken.String)
|
|
require.True(t, lexer.isEOF())
|
|
}
|
|
})
|
|
|
|
t.Run("Invalid float number", func(t *testing.T) {
|
|
invalidFloats := []string{
|
|
"123.456b",
|
|
"123.456e",
|
|
"123.456e+",
|
|
"123.456e-",
|
|
"123.456e+10e",
|
|
"123.456e-10e",
|
|
"123.456e10e",
|
|
"123.456E10e",
|
|
"123.456E+10e",
|
|
"123.456E-10e",
|
|
"123.456e+10e+10",
|
|
}
|
|
for _, f := range invalidFloats {
|
|
lexer := NewLexer(f)
|
|
err := lexer.consumeToken()
|
|
assert.Error(t, err)
|
|
}
|
|
})
|
|
|
|
t.Run("Name", func(t *testing.T) {
|
|
idents := []string{
|
|
"`CASE`",
|
|
"`TEST`",
|
|
"`WHEN`",
|
|
"hello",
|
|
"hello_world",
|
|
"hello123",
|
|
"hello_123",
|
|
"hello_123_world",
|
|
"hello_123_world_456",
|
|
"hello_123_world_456_789",
|
|
"hello_123_world_456_789_abc",
|
|
"hello_123_world_456_789_abc_def",
|
|
"hello_123_world_456_789_abc_def_ghi",
|
|
"hello_123_world_456_789_abc_def_ghi_jkl",
|
|
"hello_123_world_456_789_abc_def_ghi_jkl_mno",
|
|
"hello_123_world_456_789_abc_def_ghi_jkl_mno_pqr",
|
|
}
|
|
for _, i := range idents {
|
|
lexer := NewLexer(i)
|
|
err := lexer.consumeToken()
|
|
require.NoError(t, err)
|
|
require.Equal(t, TokenKindIdent, lexer.lastToken.Kind)
|
|
require.Equal(t, strings.Trim(i, "`"), lexer.lastToken.String)
|
|
require.True(t, lexer.isEOF())
|
|
}
|
|
})
|
|
|
|
t.Run("Keyword", func(t *testing.T) {
|
|
for _, k := range keywords.Members() {
|
|
lexer := NewLexer(k)
|
|
err := lexer.consumeToken()
|
|
require.NoError(t, err)
|
|
require.Equal(t, TokenKindKeyword, lexer.lastToken.Kind)
|
|
require.Equal(t, k, lexer.lastToken.String)
|
|
require.True(t, lexer.isEOF())
|
|
}
|
|
})
|
|
}
|