diff --git a/compiler/BUILD b/compiler/BUILD index 22894ee78..acd4c46c4 100644 --- a/compiler/BUILD +++ b/compiler/BUILD @@ -74,6 +74,7 @@ cc_test( "//testutil:baseline_tests", "@com_google_absl//absl/status", "@com_google_absl//absl/status:status_matchers", + "@com_google_absl//absl/strings", "@com_google_protobuf//:protobuf", ], ) diff --git a/compiler/compiler_factory_test.cc b/compiler/compiler_factory_test.cc index 9d6c663b3..ca195ff41 100644 --- a/compiler/compiler_factory_test.cc +++ b/compiler/compiler_factory_test.cc @@ -19,6 +19,7 @@ #include "absl/status/status.h" #include "absl/status/status_matchers.h" +#include "absl/strings/match.h" #include "checker/optional.h" #include "checker/standard_library.h" #include "checker/type_check_issue.h" @@ -42,6 +43,7 @@ using ::cel::test::FormatBaselineAst; using ::testing::Contains; using ::testing::HasSubstr; using ::testing::Property; +using ::testing::Truly; TEST(CompilerFactoryTest, Works) { ASSERT_OK_AND_ASSIGN( @@ -162,6 +164,43 @@ TEST(CompilerFactoryTest, ParserOptions) { ASSERT_THAT(compiler->Compile("a.?b.orValue('foo')"), IsOk()); } +TEST(CompilerFactoryTest, DisableStandarMacros) { + CompilerOptions options; + options.parser_options.disable_standard_macros = true; + + ASSERT_OK_AND_ASSIGN( + auto builder, + NewCompilerBuilder(cel::internal::GetSharedTestingDescriptorPool(), + options)); + + ASSERT_THAT(builder->AddLibrary(StandardCheckerLibrary()), IsOk()); + ASSERT_THAT(builder->GetParserBuilder().AddMacro(cel::ExistsMacro()), IsOk()); + + // a: map(dyn, dyn) + ASSERT_THAT(builder->GetCheckerBuilder().AddVariable( + MakeVariableDecl("a", MapType())), + IsOk()); + + ASSERT_OK_AND_ASSIGN(auto compiler, std::move(*builder).Build()); + + ASSERT_OK_AND_ASSIGN(ValidationResult result, compiler->Compile("a.b")); + + EXPECT_TRUE(result.IsValid()); + + // The has macro is disabled, so looks like a function call. + ASSERT_OK_AND_ASSIGN(result, compiler->Compile("has(a.b)")); + + EXPECT_FALSE(result.IsValid()); + EXPECT_THAT(result.GetIssues(), + Contains(Truly([](const TypeCheckIssue& issue) { + return absl::StrContains(issue.message(), + "undeclared reference to 'has'"); + }))); + + ASSERT_OK_AND_ASSIGN(result, compiler->Compile("a.exists(x, x == 'foo')")); + EXPECT_TRUE(result.IsValid()); +} + TEST(CompilerFactoryTest, FailsIfLibraryAddedTwice) { ASSERT_OK_AND_ASSIGN( auto builder,