1616#include < memory>
1717#include < string>
1818#include < utility>
19+ #include < vector>
1920
21+ #include " absl/algorithm/container.h"
2022#include " absl/status/status_matchers.h"
2123#include " absl/status/statusor.h"
2224#include " absl/strings/ascii.h"
2325#include " absl/strings/str_cat.h"
2426#include " absl/strings/str_join.h"
27+ #include " checker/optional.h"
2528#include " checker/standard_library.h"
2629#include " checker/type_check_issue.h"
2730#include " checker/validation_result.h"
3033#include " common/type.h"
3134#include " compiler/compiler.h"
3235#include " compiler/compiler_factory.h"
36+ #include " compiler/standard_library.h"
3337#include " internal/testing.h"
3438#include " internal/testing_descriptor_pool.h"
3539#include " testutil/baseline_tests.h"
@@ -42,6 +46,8 @@ using ::absl_testing::IsOk;
4246using ::cel::expr::conformance::proto3::TestAllTypes;
4347using ::cel::test::FormatBaselineAst;
4448using ::testing::HasSubstr;
49+ using ::testing::IsEmpty;
50+ using ::testing::ValuesIn;
4551
4652struct TestCase {
4753 std::string expr;
@@ -271,5 +277,108 @@ TEST(OptionalTest, NotEnabled) {
271277 HasSubstr (" undeclared reference to 'optional'" ));
272278}
273279
280+ struct OptionalExtensionVersionTestCase {
281+ std::string expr;
282+ std::vector<int > expected_supported_versions;
283+ };
284+
285+ class OptionalExtensionVersionTest
286+ : public ::testing::TestWithParam<OptionalExtensionVersionTestCase> {};
287+
288+ TEST_P (OptionalExtensionVersionTest, OptionalExtensionVersions) {
289+ const OptionalExtensionVersionTestCase& test_case = GetParam ();
290+ for (int version = 0 ; version <= cel::kOptionalExtensionLatestVersion ;
291+ ++version) {
292+ CompilerLibrary compiler_library = OptionalCompilerLibrary (version);
293+
294+ CompilerOptions compiler_options;
295+ compiler_options.parser_options .enable_optional_syntax = true ;
296+
297+ ASSERT_OK_AND_ASSIGN (
298+ std::unique_ptr<CompilerBuilder> builder,
299+ cel::NewCompilerBuilder (internal::GetTestingDescriptorPool (),
300+ compiler_options));
301+ ASSERT_THAT (builder->AddLibrary (StandardCompilerLibrary ()), IsOk ());
302+ ASSERT_THAT (builder->AddLibrary (std::move (compiler_library)), IsOk ());
303+
304+ ASSERT_OK_AND_ASSIGN (std::unique_ptr<Compiler> compiler, builder->Build ());
305+ ASSERT_OK_AND_ASSIGN (ValidationResult result,
306+ compiler->Compile (test_case.expr ));
307+ if (absl::c_contains (test_case.expected_supported_versions , version)) {
308+ EXPECT_THAT (result.GetIssues (), IsEmpty ())
309+ << " Expected no issues for expr: " << test_case.expr
310+ << " at version: " << version << " but got: " << result.FormatError ();
311+ } else {
312+ EXPECT_THAT (result.GetIssues (),
313+ Contains (Property (&TypeCheckIssue::message,
314+ HasSubstr (" undeclared reference" ))))
315+ << " Expected undeclared reference for expr: " << test_case.expr
316+ << " at version: " << version;
317+ }
318+ }
319+ };
320+
321+ std::vector<OptionalExtensionVersionTestCase>
322+ CreateOptionalExtensionVersionParams () {
323+ return {
324+ OptionalExtensionVersionTestCase{
325+ .expr = " optional_type" ,
326+ .expected_supported_versions = {0 , 1 , 2 },
327+ },
328+ OptionalExtensionVersionTestCase{
329+ .expr = " optional.of('foo').optMap(x, x)" ,
330+ .expected_supported_versions = {0 , 1 , 2 },
331+ },
332+ OptionalExtensionVersionTestCase{
333+ .expr = " optional.of('foo')" ,
334+ .expected_supported_versions = {0 , 1 , 2 },
335+ },
336+ OptionalExtensionVersionTestCase{
337+ .expr = " optional.ofNonZeroValue(1)" ,
338+ .expected_supported_versions = {0 , 1 , 2 },
339+ },
340+ OptionalExtensionVersionTestCase{
341+ .expr = " optional.of('foo').value()" ,
342+ .expected_supported_versions = {0 , 1 , 2 },
343+ },
344+ OptionalExtensionVersionTestCase{
345+ .expr = " optional.of('foo').hasValue()" ,
346+ .expected_supported_versions = {0 , 1 , 2 },
347+ },
348+ OptionalExtensionVersionTestCase{
349+ .expr = " optional.of(1).or(optional.of(2))" ,
350+ .expected_supported_versions = {0 , 1 , 2 },
351+ },
352+ OptionalExtensionVersionTestCase{
353+ .expr = " optional.of(1).orValue(2)" ,
354+ .expected_supported_versions = {0 , 1 , 2 },
355+ },
356+ OptionalExtensionVersionTestCase{
357+ .expr = " [1, 2, 3][?5]" ,
358+ .expected_supported_versions = {0 , 1 , 2 },
359+ },
360+ OptionalExtensionVersionTestCase{
361+ .expr = " dyn(1).?bar" ,
362+ .expected_supported_versions = {0 , 1 , 2 },
363+ },
364+ OptionalExtensionVersionTestCase{
365+ .expr = " optional.of('foo').optFlatMap(x, optional.of(x))" ,
366+ .expected_supported_versions = {1 , 2 },
367+ },
368+ OptionalExtensionVersionTestCase{
369+ .expr = " [1, 2, 3].first()" ,
370+ .expected_supported_versions = {2 },
371+ },
372+ OptionalExtensionVersionTestCase{
373+ .expr = " [1, 2, 3].last()" ,
374+ .expected_supported_versions = {2 },
375+ },
376+ };
377+ }
378+
379+ INSTANTIATE_TEST_SUITE_P (OptionalExtensionVersionTest,
380+ OptionalExtensionVersionTest,
381+ ValuesIn (CreateOptionalExtensionVersionParams()));
382+
274383} // namespace
275384} // namespace cel
0 commit comments