github.com/jgbaldwinbrown/perf@v0.1.1/benchproc/internal/parse/filter_test.go (about) 1 // Copyright 2022 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package parse 6 7 import "testing" 8 9 func TestParseFilter(t *testing.T) { 10 check := func(query string, want string) { 11 t.Helper() 12 q, err := ParseFilter(query) 13 if err != nil { 14 t.Errorf("%s: unexpected error %s", query, err) 15 } else if got := q.String(); got != want { 16 t.Errorf("%s: got %s, want %s", query, got, want) 17 } 18 } 19 checkErr := func(query, error string, pos int) { 20 t.Helper() 21 _, err := ParseFilter(query) 22 if se, _ := err.(*SyntaxError); se == nil || se.Msg != error || se.Off != pos { 23 t.Errorf("%s: want error %s at %d; got %s", query, error, pos, err) 24 } 25 } 26 check(`*`, `*`) 27 check(`a:b`, `a:b`) 28 checkErr(`a`, "expected key:value", 0) 29 checkErr(`a :`, "expected key:value", 0) 30 check(`a :b`, `a:b`) 31 check(`a : b`, `a:b`) 32 checkErr(`a:`, "expected key:value", 0) 33 checkErr(``, "expected key:value or subexpression", 0) 34 checkErr(`()`, "expected key:value or subexpression", 1) 35 checkErr(`AND`, "expected key:value or subexpression", 0) 36 check(`"a":"b c"`, `a:"b c"`) 37 check(`"a\"":"b c"`, `"a\"":"b c"`) 38 check(`"a\u2603":"b c"`, `a☃:"b c"`) 39 checkErr(`"a\z":"b c"`, "bad escape sequence", 0) 40 checkErr(`a "b`, "missing end quote", 2) 41 check("a-b:c", `a-b:c`) // "-" inside bare word 42 check("a*b:c", `a*b:c`) // "*" inside bare word 43 44 // Parens 45 check(`(a:b)`, `a:b`) 46 checkErr(`(a:b`, "missing \")\"", 4) 47 checkErr(`(a:b))`, "unexpected \")\"", 5) 48 49 // Operators 50 check(`a:b c:d e:f`, `(a:b AND c:d AND e:f)`) 51 check(`-a:b`, `-a:b`) 52 check(`-*`, `-*`) 53 check(`a:b AND c:d`, `(a:b AND c:d)`) 54 check(`-a:b AND c:d`, `(-a:b AND c:d)`) 55 check(`-(a:b AND c:d)`, `-(a:b AND c:d)`) 56 check(`a:b AND * AND c:d`, `(a:b AND * AND c:d)`) 57 check(`a:b OR c:d`, `(a:b OR c:d)`) 58 check(`a:b AND c:d OR e:f AND g:h`, `((a:b AND c:d) OR (e:f AND g:h))`) 59 check(`a:b AND (c:d OR e:f) AND g:h`, `(a:b AND (c:d OR e:f) AND g:h)`) 60 61 // Regexp match 62 checkErr("a:/b", "missing close \"/\"", 2) 63 checkErr("a:/[[:foo:]]/", "error parsing regexp: invalid character class range: `[:foo:]`", 2) 64 checkErr("a:/b/c", "regexp must be followed by space or an operator (unescaped \"/\"?)", 5) 65 check("a:/b[/](/)\\/c/", "a:/b[/](/)\\/c/") 66 67 // Multi-match 68 check(`a:(b OR c OR d)`, `(a:b OR a:c OR a:d)`) 69 check(`a:(b OR "c " OR /d/)`, `(a:b OR a:"c " OR a:/d/)`) 70 checkErr(`a:(b c)`, "value list must be separated by OR", 5) 71 checkErr(`a:(b AND c)`, "value list must be separated by OR", 5) 72 checkErr(`a:(b OR AND)`, "expected value", 8) 73 checkErr(`a:()`, "expected value", 3) 74 }