|
55 | 55 | #include "cel/expr/conformance/proto3/test_all_types.pb.h" |
56 | 56 | #include "google/protobuf/arena.h" |
57 | 57 | #include "google/protobuf/message.h" |
| 58 | +#include "google/protobuf/text_format.h" |
58 | 59 |
|
59 | 60 | namespace cel { |
60 | 61 | namespace checker_internal { |
@@ -1471,6 +1472,93 @@ TEST(TypeCheckerImplTest, TypeInferredFromStructCreation) { |
1471 | 1472 | std::make_unique<AstType>(DynTypeSpec()))))))); |
1472 | 1473 | } |
1473 | 1474 |
|
| 1475 | +struct VariadicLogicalCheckerTestCase { |
| 1476 | + std::string expr; |
| 1477 | +}; |
| 1478 | + |
| 1479 | +class VariadicLogicalCheckerTest |
| 1480 | + : public testing::TestWithParam<VariadicLogicalCheckerTestCase> {}; |
| 1481 | + |
| 1482 | +TEST_P(VariadicLogicalCheckerTest, Check) { |
| 1483 | + const auto& test_case = GetParam(); |
| 1484 | + |
| 1485 | + auto builder = cel::NewParserBuilder(); |
| 1486 | + builder->GetOptions().enable_variadic_logical_operators = true; |
| 1487 | + ASSERT_OK_AND_ASSIGN(auto parser, std::move(*builder).Build()); |
| 1488 | + ASSERT_OK_AND_ASSIGN(auto source, cel::NewSource(test_case.expr)); |
| 1489 | + ASSERT_OK_AND_ASSIGN(auto parsed_ast, parser->Parse(*source)); |
| 1490 | + |
| 1491 | + google::protobuf::Arena arena; |
| 1492 | + TypeCheckEnv env(GetSharedTestingDescriptorPool()); |
| 1493 | + ASSERT_THAT(RegisterMinimalBuiltins(&arena, env), IsOk()); |
| 1494 | + TypeCheckerImpl impl(std::move(env)); |
| 1495 | + auto checker_builder = impl.ToBuilder(); |
| 1496 | + ASSERT_THAT(checker_builder->AddVariable(MakeVariableDecl("a", BoolType())), |
| 1497 | + IsOk()); |
| 1498 | + ASSERT_THAT(checker_builder->AddVariable(MakeVariableDecl("b", BoolType())), |
| 1499 | + IsOk()); |
| 1500 | + ASSERT_THAT(checker_builder->AddVariable(MakeVariableDecl("c", BoolType())), |
| 1501 | + IsOk()); |
| 1502 | + ASSERT_THAT(checker_builder->AddVariable(MakeVariableDecl("d", BoolType())), |
| 1503 | + IsOk()); |
| 1504 | + ASSERT_THAT(checker_builder->AddVariable(MakeVariableDecl("e", BoolType())), |
| 1505 | + IsOk()); |
| 1506 | + |
| 1507 | + ASSERT_OK_AND_ASSIGN(auto checker, checker_builder->Build()); |
| 1508 | + ASSERT_OK_AND_ASSIGN(ValidationResult result, |
| 1509 | + checker->Check(std::move(parsed_ast))); |
| 1510 | + |
| 1511 | + ASSERT_TRUE(result.IsValid()) |
| 1512 | + << absl::StrJoin(result.GetIssues(), "\n", |
| 1513 | + [](std::string* out, const TypeCheckIssue& issue) { |
| 1514 | + absl::StrAppend(out, issue.message()); |
| 1515 | + }); |
| 1516 | + |
| 1517 | + ASSERT_OK_AND_ASSIGN(std::unique_ptr<Ast> checked_ast, result.ReleaseAst()); |
| 1518 | + EXPECT_THAT(checked_ast->type_map(), |
| 1519 | + Contains(Pair(checked_ast->root_expr().id(), |
| 1520 | + Eq(AstType(PrimitiveType::kBool))))); |
| 1521 | +} |
| 1522 | + |
| 1523 | +INSTANTIATE_TEST_SUITE_P( |
| 1524 | + VariadicLogicalChecker, VariadicLogicalCheckerTest, |
| 1525 | + testing::Values(VariadicLogicalCheckerTestCase{"true && false && true"}, |
| 1526 | + VariadicLogicalCheckerTestCase{"a && b && c && d"}, |
| 1527 | + VariadicLogicalCheckerTestCase{"a || b || c || d"}, |
| 1528 | + VariadicLogicalCheckerTestCase{"a && b && (c || d || e)"}, |
| 1529 | + VariadicLogicalCheckerTestCase{"a && b && c"}, |
| 1530 | + VariadicLogicalCheckerTestCase{"a || b || c"}, |
| 1531 | + VariadicLogicalCheckerTestCase{"[a, b, c].exists(x, x)"}, |
| 1532 | + VariadicLogicalCheckerTestCase{"[a, b, c].all(x, x)"})); |
| 1533 | + |
| 1534 | +TEST(TypeCheckerImplTest, VariadicLogicalOperatorsError) { |
| 1535 | + cel::expr::ParsedExpr parsed_expr; |
| 1536 | + ASSERT_TRUE(google::protobuf::TextFormat::ParseFromString( |
| 1537 | + R"pb( |
| 1538 | + expr { |
| 1539 | + call_expr { |
| 1540 | + function: "_&&_" |
| 1541 | + args { const_expr { bool_value: true } } |
| 1542 | + } |
| 1543 | + } |
| 1544 | + )pb", |
| 1545 | + &parsed_expr)); |
| 1546 | + ASSERT_OK_AND_ASSIGN(auto parsed_ast, |
| 1547 | + cel::CreateAstFromParsedExpr(parsed_expr)); |
| 1548 | + |
| 1549 | + google::protobuf::Arena arena; |
| 1550 | + TypeCheckEnv env(GetSharedTestingDescriptorPool()); |
| 1551 | + ASSERT_THAT(RegisterMinimalBuiltins(&arena, env), IsOk()); |
| 1552 | + TypeCheckerImpl impl(std::move(env)); |
| 1553 | + ASSERT_OK_AND_ASSIGN(ValidationResult result, |
| 1554 | + impl.Check(std::move(parsed_ast))); |
| 1555 | + |
| 1556 | + EXPECT_FALSE(result.IsValid()); |
| 1557 | + EXPECT_THAT( |
| 1558 | + result.GetIssues(), |
| 1559 | + Contains(IsIssueWithSubstring(Severity::kError, "undeclared reference"))); |
| 1560 | +} |
| 1561 | + |
1474 | 1562 | TEST(TypeCheckerImplTest, ExpectedTypeMatches) { |
1475 | 1563 | google::protobuf::Arena arena; |
1476 | 1564 | TypeCheckEnv env(GetSharedTestingDescriptorPool()); |
|
0 commit comments