VictoriaMetrics/app/vmselect/graphiteql/lexer_test.go

152 lines
3.7 KiB
Go
Raw Normal View History

package graphiteql
import (
"reflect"
"strings"
"testing"
)
func TestScanStringSuccess(t *testing.T) {
f := func(s, sExpected string) {
t.Helper()
result, err := scanString(s)
if err != nil {
t.Fatalf("unexpected error in scanString(%s): %s", s, err)
}
if result != sExpected {
t.Fatalf("unexpected string scanned from %s; got %s; want %s", s, result, sExpected)
}
if !strings.HasPrefix(s, result) {
t.Fatalf("invalid prefix for scanne string %s: %s", s, result)
}
}
f(`""`, `""`)
f(`''`, `''`)
f(`""tail`, `""`)
f(`''tail`, `''`)
f(`"foo", bar`, `"foo"`)
f(`'foo', bar`, `'foo'`)
f(`"foo\.bar"`, `"foo\.bar"`)
f(`"foo\"bar\1"\"`, `"foo\"bar\1"`)
f(`"foo\\"bar\1"\"`, `"foo\\"`)
f(`'foo\\'bar\1"\"`, `'foo\\'`)
}
func TestScanStringFailure(t *testing.T) {
f := func(s string) {
t.Helper()
result, err := scanString(s)
if err == nil {
t.Fatalf("expecting non-nil error for scanString(%s)", s)
}
if result != "" {
t.Fatalf("expecting empty result for scanString(%s); got %s", s, result)
}
}
f(``)
f(`"foo`)
f(`'bar`)
}
func TestAppendEscapedIdent(t *testing.T) {
f := func(s, resultExpected string) {
t.Helper()
result := appendEscapedIdent(nil, s)
if string(result) != resultExpected {
t.Fatalf("unexpected result; got\n%s\nwant\n%s", result, resultExpected)
}
}
f("", "")
f("a", "a")
f("fo_o.$b-ar.b[a]*z{aa,bb}", "fo_o.$b-ar.b[a]*z{aa,bb}")
f("a(b =C)", `a\(b\ \=C\)`)
}
func TestLexerSuccess(t *testing.T) {
f := func(s string, tokensExpected []string) {
t.Helper()
var lex lexer
var tokens []string
lex.Init(s)
for {
if err := lex.Next(); err != nil {
t.Fatalf("unexpected error: %s", err)
}
if isEOF(lex.Token) {
break
}
tokens = append(tokens, lex.Token)
}
if !reflect.DeepEqual(tokens, tokensExpected) {
t.Fatalf("unexpected tokens; got\n%q\nwant\n%q", tokens, tokensExpected)
}
}
f("", nil)
f("a", []string{"a"})
f("*", []string{"*"})
f("*.a", []string{"*.a"})
f("[a-z]zx", []string{"[a-z]zx"})
f("fo_o.$ba-r", []string{"fo_o.$ba-r"})
f("{foo,bar}", []string{"{foo,bar}"})
f("[a-z]", []string{"[a-z]"})
f("fo*.bar10[s-z]as{aaa,bb}.ss{aa*ss,DS[c-D],ss}ss", []string{"fo*.bar10[s-z]as{aaa,bb}.ss{aa*ss,DS[c-D],ss}ss"})
f("FOO.bar:avg", []string{"FOO.bar:avg"})
f("FOO.bar\\:avg", []string{"FOO.bar\\:avg"})
f(`foo.Bar|aaa(b,cd,e=aa)`, []string{"foo.Bar", "|", "aaa", "(", "b", ",", "cd", ",", "e", "=", "aa", ")"})
f(`foo.Bar\|aaa\(b\,cd\,e\=aa\)`, []string{`foo.Bar\|aaa\(b\,cd\,e\=aa\)`})
f(`123`, []string{`123`})
f(`12.34`, []string{`12.34`})
f(`12.34e4`, []string{`12.34e4`})
f(`12.34e-4`, []string{`12.34e-4`})
f(`12E+45`, []string{`12E+45`})
f(`+12.34`, []string{`+`, `12.34`})
f("0xABcd", []string{`0xABcd`})
f("f(0o765,0b1101,0734,12.34)", []string{"f", "(", "0o765", ",", "0b1101", ",", "0734", ",", "12.34", ")"})
f(`f ( foo, -.54e6,bar)`, []string{"f", "(", "foo", ",", "-", ".54e6", ",", "bar", ")"})
f(`"foo(b'ar:baz)"`, []string{`"foo(b'ar:baz)"`})
f(`'a"bc'`, []string{`'a"bc'`})
f(`"f\"oo\\b"`, []string{`"f\"oo\\b"`})
f(`a("b,c", 'de')`, []string{`a`, `(`, `"b,c"`, `,`, `'de'`, `)`})
}
func TestLexerError(t *testing.T) {
f := func(s string) {
t.Helper()
var lex lexer
lex.Init(s)
for {
if err := lex.Next(); err != nil {
// Make sure lex.Next() consistently returns the error.
if err1 := lex.Next(); err1 != err {
t.Fatalf("unexpected error returned; got %v; want %v", err1, err)
}
return
}
if isEOF(lex.Token) {
t.Fatalf("expecting non-nil error when parsing %q", s)
}
}
}
// Invalid identifier
f("foo\\")
f(`foo[bar`)
f(`foo{bar`)
f("~")
f(",~")
// Invalid string
f(`"`)
f(`"foo`)
f(`'aa`)
// Invalid number
f(`0x`)
f(`0o`)
f(`-0b`)
f(`13.`)
f(`1e`)
f(`1E+`)
f(`1.3e`)
}