|
17 | 17 | #include <memory> |
18 | 18 | #include <string> |
19 | 19 | #include <utility> |
| 20 | +#include <vector> |
20 | 21 |
|
21 | 22 | #include "cel/expr/syntax.pb.h" |
22 | 23 | #include "absl/status/status.h" |
23 | 24 | #include "absl/status/status_matchers.h" |
| 25 | +#include "checker/standard_library.h" |
| 26 | +#include "checker/validation_result.h" |
24 | 27 | #include "common/source.h" |
25 | 28 | #include "common/value.h" |
26 | 29 | #include "common/value_testing.h" |
| 30 | +#include "compiler/compiler.h" |
| 31 | +#include "compiler/compiler_factory.h" |
27 | 32 | #include "extensions/protobuf/runtime_adapter.h" |
28 | 33 | #include "internal/testing.h" |
29 | 34 | #include "internal/testing_descriptor_pool.h" |
|
38 | 43 | #include "runtime/runtime_options.h" |
39 | 44 | #include "runtime/standard_runtime_builder_factory.h" |
40 | 45 | #include "google/protobuf/arena.h" |
| 46 | +#include "google/protobuf/descriptor.h" |
41 | 47 |
|
42 | 48 | namespace cel::extensions { |
43 | 49 | namespace { |
44 | | -using ::cel::expr::Expr; |
45 | | -using ::cel::expr::ParsedExpr; |
46 | | -using ::cel::expr::SourceInfo; |
47 | 50 |
|
48 | 51 | using ::absl_testing::IsOk; |
49 | 52 | using ::absl_testing::StatusIs; |
50 | 53 | using ::cel::test::ErrorValueIs; |
| 54 | +using ::cel::expr::Expr; |
| 55 | +using ::cel::expr::ParsedExpr; |
| 56 | +using ::cel::expr::SourceInfo; |
51 | 57 | using ::testing::HasSubstr; |
| 58 | +using ::testing::ValuesIn; |
52 | 59 |
|
53 | 60 | struct TestInfo { |
54 | 61 | std::string expr; |
@@ -273,5 +280,80 @@ TEST(ListsFunctionsTest, ListSortByMacroParseError) { |
273 | 280 | HasSubstr("sortBy can only be applied to"))); |
274 | 281 | } |
275 | 282 |
|
| 283 | +struct ListCheckerTestCase { |
| 284 | + const std::string expr; |
| 285 | + bool is_valid; |
| 286 | +}; |
| 287 | + |
| 288 | +class ListsCheckerLibraryTest |
| 289 | + : public ::testing::TestWithParam<ListCheckerTestCase> { |
| 290 | + public: |
| 291 | + void SetUp() override { |
| 292 | + // Arrange: Configure the compiler. |
| 293 | + // 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()); |
| 298 | + ASSERT_OK_AND_ASSIGN(compiler_, std::move(*compiler_builder).Build()); |
| 299 | + } |
| 300 | + |
| 301 | + const google::protobuf::DescriptorPool* descriptor_pool_ = |
| 302 | + internal::GetTestingDescriptorPool(); |
| 303 | + std::unique_ptr<Compiler> compiler_; |
| 304 | +}; |
| 305 | + |
| 306 | +TEST_P(ListsCheckerLibraryTest, ListsFunctionsTypeCheckerSuccess) { |
| 307 | + // Act & Assert: Compile the expression and validate the result. |
| 308 | + ASSERT_OK_AND_ASSIGN(ValidationResult result, |
| 309 | + compiler_->Compile(GetParam().expr)); |
| 310 | + EXPECT_EQ(result.IsValid(), GetParam().is_valid); |
| 311 | +} |
| 312 | + |
| 313 | +// Returns a vector of test cases for the ListsCheckerLibraryTest. |
| 314 | +// Returns both positive and negative test cases for the lists functions. |
| 315 | +std::vector<ListCheckerTestCase> createListsCheckerParams() { |
| 316 | + return { |
| 317 | + // 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}, |
| 322 | + // 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}, |
| 330 | + // 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}, |
| 335 | + // 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}, |
| 340 | + // 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}, |
| 347 | + // 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}, |
| 352 | + }; |
| 353 | +} |
| 354 | + |
| 355 | +INSTANTIATE_TEST_SUITE_P(ListsCheckerLibraryTest, ListsCheckerLibraryTest, |
| 356 | + ValuesIn(createListsCheckerParams())); |
| 357 | + |
276 | 358 | } // namespace |
277 | 359 | } // namespace cel::extensions |
0 commit comments