(t testing.TB, policy *Policy, ast *cel.Ast)
| 533 | } |
| 534 | |
| 535 | func verifySourceInfoCoverage(t testing.TB, policy *Policy, ast *cel.Ast) { |
| 536 | t.Helper() |
| 537 | info := ast.SourceInfo() |
| 538 | |
| 539 | exprLines := exprLinesFromPolicy(policy) |
| 540 | coveredLines := make(map[int]bool) |
| 541 | ids := ast.NativeRep().IDs() |
| 542 | for id, offset := range info.GetPositions() { |
| 543 | if offset <= 0 { |
| 544 | t.Errorf("id %d has invalid offset %v", id, offset) |
| 545 | } |
| 546 | // Check that each position in the SourceInfo corresponds to a valid AST node. |
| 547 | if !ids[id] { |
| 548 | t.Errorf("id %d not found in AST", id) |
| 549 | } |
| 550 | loc, found := ast.Source().OffsetLocation(offset) |
| 551 | if found { |
| 552 | coveredLines[loc.Line()] = true |
| 553 | } else { |
| 554 | t.Errorf("invalid source location for offset %d", offset) |
| 555 | } |
| 556 | } |
| 557 | // Verify that each source line inside an expression is covered by the at least one node in the |
| 558 | // AST. |
| 559 | for line := range exprLines { |
| 560 | if !coveredLines[line] { |
| 561 | t.Errorf("Line %d expected to be covered by SourceInfo, but was not", line) |
| 562 | } |
| 563 | } |
| 564 | |
| 565 | if t.Failed() { |
| 566 | checked, err := cel.AstToCheckedExpr(ast) |
| 567 | if err != nil { |
| 568 | t.Logf("cel.AstToCheckedExpr() failed: %v", err) |
| 569 | } else { |
| 570 | t.Logf("AST:\n%s", prototext.Format(checked.GetExpr())) |
| 571 | } |
| 572 | } |
| 573 | } |
| 574 | |
| 575 | // exprLinesFromPolicy returns a set of line numbers within a policy where expressions (variables, |
| 576 | // conditions, etc.) are defined. |
no test coverage detected