mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2024-12-22 16:36:27 +01:00
152 lines
3.7 KiB
Go
152 lines
3.7 KiB
Go
|
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`)
|
||
|
}
|