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  }