Add CompilerLibraries for lists and strings extensions. · google/cel-cpp@2a8b2c8
@@ -22,13 +22,14 @@
2222#include "cel/expr/syntax.pb.h"
2323#include "absl/status/status.h"
2424#include "absl/status/status_matchers.h"
25-#include "checker/standard_library.h"
25+#include "absl/strings/string_view.h"
2626#include "checker/validation_result.h"
2727#include "common/source.h"
2828#include "common/value.h"
2929#include "common/value_testing.h"
3030#include "compiler/compiler.h"
3131#include "compiler/compiler_factory.h"
32+#include "compiler/standard_library.h"
3233#include "extensions/protobuf/runtime_adapter.h"
3334#include "internal/testing.h"
3435#include "internal/testing_descriptor_pool.h"
@@ -43,7 +44,6 @@
4344#include "runtime/runtime_options.h"
4445#include "runtime/standard_runtime_builder_factory.h"
4546#include "google/protobuf/arena.h"
46-#include "google/protobuf/descriptor.h"
47474848namespace cel::extensions {
4949namespace {
@@ -281,8 +281,8 @@ TEST(ListsFunctionsTest, ListSortByMacroParseError) {
281281}
282282283283struct ListCheckerTestCase {
284-const std::string expr;
285-bool is_valid;
284+ std::string expr;
285+std::string error_substr;
286286};
287287288288class ListsCheckerLibraryTest
@@ -291,64 +291,86 @@ class ListsCheckerLibraryTest
291291void SetUp() override {
292292// Arrange: Configure the compiler.
293293// Add the lists checker library to the compiler builder.
294-ASSERT_OK_AND_ASSIGN(std::unique_ptr<CompilerBuilder> compiler_builder,
295-NewCompilerBuilder(descriptor_pool_));
296-ASSERT_THAT(compiler_builder->AddLibrary(StandardCheckerLibrary()), IsOk());
297-ASSERT_THAT(compiler_builder->AddLibrary(ListsCheckerLibrary()), IsOk());
294+ASSERT_OK_AND_ASSIGN(
295+ std::unique_ptr<CompilerBuilder> compiler_builder,
296+NewCompilerBuilder(internal::GetTestingDescriptorPool()));
297+ASSERT_THAT(compiler_builder->AddLibrary(StandardCompilerLibrary()),
298+IsOk());
299+ASSERT_THAT(compiler_builder->AddLibrary(ListsCompilerLibrary()), IsOk());
300+ compiler_builder->GetCheckerBuilder().set_container(
301+"cel.expr.conformance.proto3");
298302ASSERT_OK_AND_ASSIGN(compiler_, std::move(*compiler_builder).Build());
299303 }
300304301-const google::protobuf::DescriptorPool* descriptor_pool_ =
302-internal::GetTestingDescriptorPool();
303305 std::unique_ptr<Compiler> compiler_;
304306};
305307306308TEST_P(ListsCheckerLibraryTest, ListsFunctionsTypeCheckerSuccess) {
307309// Act & Assert: Compile the expression and validate the result.
308310ASSERT_OK_AND_ASSIGN(ValidationResult result,
309311 compiler_->Compile(GetParam().expr));
310-EXPECT_EQ(result.IsValid(), GetParam().is_valid);
312+ absl::string_view error_substr = GetParam().error_substr;
313+EXPECT_EQ(result.IsValid(), error_substr.empty());
314+315+if (!error_substr.empty()) {
316+EXPECT_THAT(result.FormatError(), HasSubstr(error_substr));
317+ }
311318}
312319313320// Returns a vector of test cases for the ListsCheckerLibraryTest.
314321// Returns both positive and negative test cases for the lists functions.
315322std::vector<ListCheckerTestCase> createListsCheckerParams() {
316323return {
317324// lists.distinct()
318- {R"([1,2,3,4,4].distinct() == [1,2,3,4])", true},
319- {R"('abc'.distinct() == [1,2,3,4])", false},
320- {R"([1,2,3,4,4].distinct() == 'abc')", false},
321- {R"([1,2,3,4,4].distinct(1) == [1,2,3,4])", false},
325+ {R"([1,2,3,4,4].distinct() == [1,2,3,4])"},
326+ {R"('abc'.distinct() == [1,2,3,4])",
327+"no matching overload for 'distinct'"},
328+ {R"([1,2,3,4,4].distinct() == 'abc')", "no matching overload for '_==_'"},
329+ {R"([1,2,3,4,4].distinct(1) == [1,2,3,4])", "undeclared reference"},
322330// lists.flatten()
323- {R"([1,2,3,4].flatten() == [1,2,3,4])", true},
324- {R"([1,2,3,4].flatten(1) == [1,2,3,4])", true},
325- {R"('abc'.flatten() == [1,2,3,4])", false},
326- {R"([1,2,3,4].flatten() == 'abc')", false},
327- {R"('abc'.flatten(1) == [1,2,3,4])", false},
328- {R"([1,2,3,4].flatten('abc') == [1,2,3,4])", false},
329- {R"([1,2,3,4].flatten(1) == 'abc')", false},
331+ {R"([1,2,3,4].flatten() == [1,2,3,4])"},
332+ {R"([1,2,3,4].flatten(1) == [1,2,3,4])"},
333+ {R"('abc'.flatten() == [1,2,3,4])", "no matching overload for 'flatten'"},
334+ {R"([1,2,3,4].flatten() == 'abc')", "no matching overload for '_==_'"},
335+ {R"('abc'.flatten(1) == [1,2,3,4])",
336+"no matching overload for 'flatten'"},
337+ {R"([1,2,3,4].flatten('abc') == [1,2,3,4])",
338+"no matching overload for 'flatten'"},
339+ {R"([1,2,3,4].flatten(1) == 'abc')", "no matching overload"},
330340// lists.range()
331- {R"(lists.range(4) == [0,1,2,3])", true},
332- {R"(lists.range('abc') == [])", false},
333- {R"(lists.range(4) == 'abc')", false},
334- {R"(lists.range(4, 4) == [0,1,2,3])", false},
341+ {R"(lists.range(4) == [0,1,2,3])"},
342+ {R"(lists.range('abc') == [])", "no matching overload for 'lists.range'"},
343+ {R"(lists.range(4) == 'abc')", "no matching overload for '_==_'"},
344+ {R"(lists.range(4, 4) == [0,1,2,3])", "undeclared reference"},
335345// lists.reverse()
336- {R"([1,2,3,4].reverse() == [4,3,2,1])", true},
337- {R"('abc'.reverse() == [])", false},
338- {R"([1,2,3,4].reverse() == 'abc')", false},
339- {R"([1,2,3,4].reverse(1) == [4,3,2,1])", false},
346+ {R"([1,2,3,4].reverse() == [4,3,2,1])"},
347+ {R"('abc'.reverse() == [])", "no matching overload for 'reverse'"},
348+ {R"([1,2,3,4].reverse() == 'abc')", "no matching overload for '_==_'"},
349+ {R"([1,2,3,4].reverse(1) == [4,3,2,1])", "undeclared reference"},
340350// lists.slice()
341- {R"([1,2,3,4].slice(0, 4) == [1,2,3,4])", true},
342- {R"('abc'.slice(0, 4) == [1,2,3,4])", false},
343- {R"([1,2,3,4].slice('abc', 4) == [1,2,3,4])", false},
344- {R"([1,2,3,4].slice(0, 'abc') == [1,2,3,4])", false},
345- {R"([1,2,3,4].slice(0, 4) == 'abc')", false},
346- {R"([1,2,3,4].slice(0, 2, 3) == [1,2,3,4])", false},
351+ {R"([1,2,3,4].slice(0, 4) == [1,2,3,4])"},
352+ {R"('abc'.slice(0, 4) == [1,2,3,4])", "no matching overload for 'slice'"},
353+ {R"([1,2,3,4].slice('abc', 4) == [1,2,3,4])",
354+"no matching overload for 'slice'"},
355+ {R"([1,2,3,4].slice(0, 'abc') == [1,2,3,4])",
356+"no matching overload for 'slice'"},
357+ {R"([1,2,3,4].slice(0, 4) == 'abc')", "no matching overload for '_==_'"},
358+ {R"([1,2,3,4].slice(0, 2, 3) == [1,2,3,4])", "undeclared reference"},
347359// lists.sort()
348- {R"([1,2,3,4].sort() == [1,2,3,4])", true},
349- {R"('abc'.sort() == [])", false},
350- {R"([1,2,3,4].sort() == 'abc')", false},
351- {R"([1,2,3,4].sort(2) == [1,2,3,4])", false},
360+ {R"([1,2,3,4].sort() == [1,2,3,4])"},
361+ {R"([TestAllTypes{}, TestAllTypes{}].sort() == [])",
362+"no matching overload for 'sort'"},
363+ {R"('abc'.sort() == [])", "no matching overload for 'sort'"},
364+ {R"([1,2,3,4].sort() == 'abc')", "no matching overload for '_==_'"},
365+ {R"([1,2,3,4].sort(2) == [1,2,3,4])", "undeclared reference"},
366+// sortBy macro
367+ {R"([1,2,3,4].sortBy(x, -x) == [4,3,2,1])"},
368+ {R"([TestAllTypes{}, TestAllTypes{}].sortBy(x, x) == [])",
369+"no matching overload for '@sortByAssociatedKeys'"},
370+ {R"(
371+ [TestAllTypes{single_int64: 2}, TestAllTypes{single_int64: 1}]
372+ .sortBy(x, x.single_int64) ==
373+ [TestAllTypes{single_int64: 1}, TestAllTypes{single_int64: 2}])"},
352374 };
353375}
354376