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"

47474848

namespace cel::extensions {

4949

namespace {

@@ -281,8 +281,8 @@ TEST(ListsFunctionsTest, ListSortByMacroParseError) {

281281

}

282282283283

struct ListCheckerTestCase {

284-

const std::string expr;

285-

bool is_valid;

284+

std::string expr;

285+

std::string error_substr;

286286

};

287287288288

class ListsCheckerLibraryTest

@@ -291,64 +291,86 @@ class ListsCheckerLibraryTest

291291

void 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");

298302

ASSERT_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

};

305307306308

TEST_P(ListsCheckerLibraryTest, ListsFunctionsTypeCheckerSuccess) {

307309

// Act & Assert: Compile the expression and validate the result.

308310

ASSERT_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.

315322

std::vector<ListCheckerTestCase> createListsCheckerParams() {

316323

return {

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