github.com/orteth01/up@v0.2.0/internal/logs/parser/parser_test.go (about)

     1  package parser
     2  
     3  import (
     4  	"testing"
     5  )
     6  
     7  // TODO: precedence...
     8  // TODO: byte size literals
     9  // TODO: support literals: `method = GET`, `ip = 70.*` etc
    10  // TODO: error tests
    11  // TODO: test error messages
    12  // TODO: add "starts with" / "ends with" to compliment "contains"?
    13  // TODO: document best practices for logging json from an app
    14  
    15  var cases = []struct {
    16  	Input  string
    17  	Output string
    18  }{
    19  	// {`method = GET`, `{ $.method = "GET" }`},
    20  	// {`method = foo.bar.baz`, `{ $.method = "foo.bar.baz" }`},
    21  	// {`method = foo.bar.*`, `{ $.method = "foo.bar.*" }`},
    22  	{`method = "GET"`, `{ $.fields.method = "GET" }`},
    23  	{`debug`, `{ ($.level = "debug") }`},
    24  	{`info`, `{ ($.level = "info") }`},
    25  	{`warn`, `{ ($.level = "warn") }`},
    26  	{`error`, `{ ($.level = "error") }`},
    27  	{`fatal`, `{ ($.level = "fatal") }`},
    28  	{`not info`, `{ !(($.level = "info")) }`},
    29  	{`not error or fatal`, `{ !(($.level = "error") || ($.level = "fatal")) }`},
    30  	{`!info`, `{ !($.level = "info") }`},
    31  	{`level = "info"`, `{ $.level = "info" }`},
    32  	{`message = "user signin"`, `{ $.message = "user signin" }`},
    33  	{`status = 0`, `{ $.fields.status = 0 }`},
    34  	{`status = 0.123`, `{ $.fields.status = 0.123 }`},
    35  	{`status = .123`, `{ $.fields.status = .123 }`},
    36  	{`status = 200`, `{ $.fields.status = 200 }`},
    37  	{`price = 1.95`, `{ $.fields.price = 1.95 }`},
    38  	{`price == 1.95`, `{ $.fields.price = 1.95 }`},
    39  	{`price > 1.95`, `{ $.fields.price > 1.95 }`},
    40  	{`price < 1.95`, `{ $.fields.price < 1.95 }`},
    41  	{`price >= 1.95`, `{ $.fields.price >= 1.95 }`},
    42  	{`price <= 1.95`, `{ $.fields.price <= 1.95 }`},
    43  	{`price != 1.95`, `{ $.fields.price != 1.95 }`},
    44  	{`!enabled`, `{ !$.fields.enabled }`},
    45  	{`!   enabled`, `{ !$.fields.enabled }`},
    46  	{`foo = 1 || bar = 2`, `{ $.fields.foo = 1 || $.fields.bar = 2 }`},
    47  	{`foo = 1 && bar = 2`, `{ $.fields.foo = 1 && $.fields.bar = 2 }`},
    48  	{`foo = 1 or bar = 2`, `{ $.fields.foo = 1 || $.fields.bar = 2 }`},
    49  	{`foo = 1 and bar = 2`, `{ $.fields.foo = 1 && $.fields.bar = 2 }`},
    50  	{`foo = 1 bar = 2`, `{ $.fields.foo = 1 && $.fields.bar = 2 }`},
    51  	{`foo.bar.baz = 1`, `{ $.fields.foo.bar.baz = 1 }`},
    52  	{`level = "error" and (duration >= 500 or duration = 0)`, `{ $.level = "error" && ($.fields.duration >= 500 || $.fields.duration = 0) }`},
    53  	{`level = "error" (duration >= 500 or duration = 0)`, `{ $.level = "error" && ($.fields.duration >= 500 || $.fields.duration = 0) }`},
    54  	{`cart.total = 15.99`, `{ $.fields.cart.total = 15.99 }`},
    55  	{`user.name contains "obi"`, `{ $.fields.user.name = "*obi*" }`},
    56  	{`user in ("Tobi")`, `{ ($.fields.user = "Tobi") }`},
    57  	{`pet.age in (1, 2, 3)`, `{ ($.fields.pet.age = 1 || $.fields.pet.age = 2 || $.fields.pet.age = 3) }`},
    58  	{`user in ("Tobi", "Loki", "Jane")`, `{ ($.fields.user = "Tobi" || $.fields.user = "Loki" || $.fields.user = "Jane") }`},
    59  	{`user.name in ("Tobi", "Loki", "Jane")`, `{ ($.fields.user.name = "Tobi" || $.fields.user.name = "Loki" || $.fields.user.name = "Jane") }`},
    60  	{`not user.admin`, `{ !($.fields.user.admin) }`},
    61  	{`not user.role in ("Admin", "Moderator")`, `{ !(($.fields.user.role = "Admin" || $.fields.user.role = "Moderator")) }`},
    62  	{`user.role not in ("Admin", "Moderator")`, `{ !(($.fields.user.role = "Admin" || $.fields.user.role = "Moderator")) }`},
    63  	{`not level = "error" or level = "fatal"`, `{ !($.level = "error" || $.level = "fatal") }`},
    64  	{`cart.products[0] = "something"`, `{ $.fields.cart.products[0] = "something" }`},
    65  	{`cart.products[0].price = 15.00`, `{ $.fields.cart.products[0].price = 15.00 }`},
    66  	{`cart.products[0][1].price = 15.00`, `{ $.fields.cart.products[0][1].price = 15.00 }`},
    67  	{`cart.products[0].items[1].price = 15.00`, `{ $.fields.cart.products[0].items[1].price = 15.00 }`},
    68  	{`user.name in ("Tobi", "Loki") and status >= 500`, `{ ($.fields.user.name = "Tobi" || $.fields.user.name = "Loki") && $.fields.status >= 500 }`},
    69  	{`method in ("POST", "PUT") and ip = "207.*" and status = 200 and duration >= 50`, `{ ($.fields.method = "POST" || $.fields.method = "PUT") && $.fields.ip = "207.*" && $.fields.status = 200 && $.fields.duration >= 50 }`},
    70  	{`method in ("POST", "PUT") ip = "207.*" status = 200 duration >= 50`, `{ ($.fields.method = "POST" || $.fields.method = "PUT") && $.fields.ip = "207.*" && $.fields.status = 200 && $.fields.duration >= 50 }`},
    71  	// {`ip = 111.222.333.*`, ``},
    72  	// {`user.email is null`, ``},
    73  }
    74  
    75  func TestParse(t *testing.T) {
    76  	for _, c := range cases {
    77  		n, err := Parse(c.Input)
    78  
    79  		if err != nil {
    80  			t.Errorf("error parsing %q: %s", c.Input, err)
    81  			continue
    82  		}
    83  
    84  		if n.String() != c.Output {
    85  			t.Errorf("\n\ntext: %s\nwant: %s\n got: %s\n", c.Input, c.Output, n.String())
    86  		}
    87  	}
    88  }
    89  
    90  func BenchmarkParse(b *testing.B) {
    91  	for i := 0; i < b.N; i++ {
    92  		Parse(`user.name in ("Tobi", "Loki", "Jane")`)
    93  	}
    94  }