(t *testing.T)
| 345 | } |
| 346 | |
| 347 | func TestOptimize_predicate_combination(t *testing.T) { |
| 348 | tests := []struct { |
| 349 | op string |
| 350 | fn string |
| 351 | wantOp string |
| 352 | }{ |
| 353 | {"and", "all", "and"}, |
| 354 | {"&&", "all", "&&"}, |
| 355 | {"or", "any", "or"}, |
| 356 | {"||", "any", "||"}, |
| 357 | {"and", "none", "or"}, |
| 358 | {"&&", "none", "||"}, |
| 359 | } |
| 360 | |
| 361 | for _, tt := range tests { |
| 362 | rule := fmt.Sprintf(`%s(users, .Age > 18 and .Name != "Bob") %s %s(users, .Age < 30)`, tt.fn, tt.op, tt.fn) |
| 363 | t.Run(rule, func(t *testing.T) { |
| 364 | tree, err := parser.Parse(rule) |
| 365 | require.NoError(t, err) |
| 366 | |
| 367 | err = optimizer.Optimize(&tree.Node, nil) |
| 368 | require.NoError(t, err) |
| 369 | |
| 370 | expected := &ast.BuiltinNode{ |
| 371 | Name: tt.fn, |
| 372 | Arguments: []ast.Node{ |
| 373 | &ast.IdentifierNode{Value: "users"}, |
| 374 | &ast.PredicateNode{ |
| 375 | Node: &ast.BinaryNode{ |
| 376 | Operator: tt.wantOp, |
| 377 | Left: &ast.BinaryNode{ |
| 378 | Operator: "and", |
| 379 | Left: &ast.BinaryNode{ |
| 380 | Operator: ">", |
| 381 | Left: &ast.MemberNode{ |
| 382 | Node: &ast.PointerNode{}, |
| 383 | Property: &ast.StringNode{Value: "Age"}, |
| 384 | }, |
| 385 | Right: &ast.IntegerNode{Value: 18}, |
| 386 | }, |
| 387 | Right: &ast.BinaryNode{ |
| 388 | Operator: "!=", |
| 389 | Left: &ast.MemberNode{ |
| 390 | Node: &ast.PointerNode{}, |
| 391 | Property: &ast.StringNode{Value: "Name"}, |
| 392 | }, |
| 393 | Right: &ast.StringNode{Value: "Bob"}, |
| 394 | }, |
| 395 | }, |
| 396 | Right: &ast.BinaryNode{ |
| 397 | Operator: "<", |
| 398 | Left: &ast.MemberNode{ |
| 399 | Node: &ast.PointerNode{}, |
| 400 | Property: &ast.StringNode{Value: "Age"}, |
| 401 | }, |
| 402 | Right: &ast.IntegerNode{Value: 30}, |
| 403 | }, |
| 404 | }, |
nothing calls this directly
no test coverage detected
searching dependent graphs…