|
21 | 21 | #include "absl/status/status.h" |
22 | 22 | #include "absl/status/status_matchers.h" |
23 | 23 | #include "absl/strings/string_view.h" |
| 24 | +#include "checker/checker_options.h" |
24 | 25 | #include "checker/internal/test_ast_helpers.h" |
| 26 | +#include "checker/standard_library.h" |
| 27 | +#include "checker/type_checker.h" |
25 | 28 | #include "checker/type_checker_builder.h" |
26 | 29 | #include "checker/validation_result.h" |
27 | 30 | #include "common/decl.h" |
@@ -391,6 +394,108 @@ TEST(TypeCheckerBuilderTest, AddContextDeclaration) { |
391 | 394 | EXPECT_TRUE(result.IsValid()); |
392 | 395 | } |
393 | 396 |
|
| 397 | +TEST(TypeCheckerBuilderTest, WellKnownTypeContextDeclarationError) { |
| 398 | + ASSERT_OK_AND_ASSIGN( |
| 399 | + std::unique_ptr<TypeCheckerBuilder> builder, |
| 400 | + CreateTypeCheckerBuilder(GetSharedTestingDescriptorPool())); |
| 401 | + |
| 402 | + ASSERT_THAT(builder->AddContextDeclaration("google.protobuf.Any"), |
| 403 | + StatusIs(absl::StatusCode::kInvalidArgument, |
| 404 | + HasSubstr("'google.protobuf.Any' is not a struct"))); |
| 405 | +} |
| 406 | + |
| 407 | +TEST(TypeCheckerBuilderTest, AllowWellKnownTypeContextDeclaration) { |
| 408 | + CheckerOptions options; |
| 409 | + options.allow_well_known_type_context_declarations = true; |
| 410 | + ASSERT_OK_AND_ASSIGN( |
| 411 | + std::unique_ptr<TypeCheckerBuilder> builder, |
| 412 | + CreateTypeCheckerBuilder(GetSharedTestingDescriptorPool(), options)); |
| 413 | + |
| 414 | + ASSERT_THAT(builder->AddContextDeclaration("google.protobuf.Any"), IsOk()); |
| 415 | + ASSERT_THAT(builder->AddLibrary(StandardCheckerLibrary()), IsOk()); |
| 416 | + |
| 417 | + ASSERT_OK_AND_ASSIGN(std::unique_ptr<TypeChecker> type_checker, |
| 418 | + builder->Build()); |
| 419 | + ASSERT_OK_AND_ASSIGN( |
| 420 | + auto ast, |
| 421 | + MakeTestParsedAst( |
| 422 | + R"cel(value == b'' && type_url == 'type.googleapis.com/google.protobuf.Duration')cel")); |
| 423 | + ASSERT_OK_AND_ASSIGN(ValidationResult result, |
| 424 | + type_checker->Check(std::move(ast))); |
| 425 | + |
| 426 | + ASSERT_TRUE(result.IsValid()); |
| 427 | +} |
| 428 | + |
| 429 | +TEST(TypeCheckerBuilderTest, AllowWellKnownTypeContextDeclarationStruct) { |
| 430 | + CheckerOptions options; |
| 431 | + options.allow_well_known_type_context_declarations = true; |
| 432 | + ASSERT_OK_AND_ASSIGN( |
| 433 | + std::unique_ptr<TypeCheckerBuilder> builder, |
| 434 | + CreateTypeCheckerBuilder(GetSharedTestingDescriptorPool(), options)); |
| 435 | + |
| 436 | + ASSERT_THAT(builder->AddContextDeclaration("google.protobuf.Struct"), IsOk()); |
| 437 | + ASSERT_THAT(builder->AddLibrary(StandardCheckerLibrary()), IsOk()); |
| 438 | + |
| 439 | + ASSERT_OK_AND_ASSIGN(std::unique_ptr<TypeChecker> type_checker, |
| 440 | + builder->Build()); |
| 441 | + ASSERT_OK_AND_ASSIGN( |
| 442 | + auto ast, |
| 443 | + MakeTestParsedAst(R"cel(fields.foo.bar_list.exists(x, x == 1))cel")); |
| 444 | + ASSERT_OK_AND_ASSIGN(ValidationResult result, |
| 445 | + type_checker->Check(std::move(ast))); |
| 446 | + |
| 447 | + ASSERT_TRUE(result.IsValid()); |
| 448 | +} |
| 449 | + |
| 450 | +TEST(TypeCheckerBuilderTest, AllowWellKnownTypeContextDeclarationValue) { |
| 451 | + CheckerOptions options; |
| 452 | + options.allow_well_known_type_context_declarations = true; |
| 453 | + ASSERT_OK_AND_ASSIGN( |
| 454 | + std::unique_ptr<TypeCheckerBuilder> builder, |
| 455 | + CreateTypeCheckerBuilder(GetSharedTestingDescriptorPool(), options)); |
| 456 | + |
| 457 | + ASSERT_THAT(builder->AddContextDeclaration("google.protobuf.Value"), IsOk()); |
| 458 | + ASSERT_THAT(builder->AddLibrary(StandardCheckerLibrary()), IsOk()); |
| 459 | + |
| 460 | + ASSERT_OK_AND_ASSIGN(std::unique_ptr<TypeChecker> type_checker, |
| 461 | + builder->Build()); |
| 462 | + ASSERT_OK_AND_ASSIGN( |
| 463 | + auto ast, MakeTestParsedAst( |
| 464 | + // Note: one of fields are all added with safe traversal, so |
| 465 | + // we lose the union discriminator information. |
| 466 | + R"cel( |
| 467 | + null_value == null && |
| 468 | + number_value == 0.0 && |
| 469 | + string_value == '' && |
| 470 | + list_value == [] && |
| 471 | + struct_value == {} && |
| 472 | + bool_value == false)cel")); |
| 473 | + ASSERT_OK_AND_ASSIGN(ValidationResult result, |
| 474 | + type_checker->Check(std::move(ast))); |
| 475 | + |
| 476 | + ASSERT_TRUE(result.IsValid()); |
| 477 | +} |
| 478 | + |
| 479 | +TEST(TypeCheckerBuilderTest, AllowWellKnownTypeContextDeclarationInt64Value) { |
| 480 | + CheckerOptions options; |
| 481 | + options.allow_well_known_type_context_declarations = true; |
| 482 | + ASSERT_OK_AND_ASSIGN( |
| 483 | + std::unique_ptr<TypeCheckerBuilder> builder, |
| 484 | + CreateTypeCheckerBuilder(GetSharedTestingDescriptorPool(), options)); |
| 485 | + |
| 486 | + ASSERT_THAT(builder->AddContextDeclaration("google.protobuf.Int64Value"), |
| 487 | + IsOk()); |
| 488 | + ASSERT_THAT(builder->AddLibrary(StandardCheckerLibrary()), IsOk()); |
| 489 | + |
| 490 | + ASSERT_OK_AND_ASSIGN(std::unique_ptr<TypeChecker> type_checker, |
| 491 | + builder->Build()); |
| 492 | + ASSERT_OK_AND_ASSIGN(auto ast, MakeTestParsedAst(R"cel(value == 0)cel")); |
| 493 | + ASSERT_OK_AND_ASSIGN(ValidationResult result, |
| 494 | + type_checker->Check(std::move(ast))); |
| 495 | + |
| 496 | + ASSERT_TRUE(result.IsValid()); |
| 497 | +} |
| 498 | + |
394 | 499 | TEST(TypeCheckerBuilderTest, AddLibraryRedeclaredError) { |
395 | 500 | ASSERT_OK_AND_ASSIGN( |
396 | 501 | std::unique_ptr<TypeCheckerBuilder> builder, |
|
0 commit comments