Skip to content

Commit 5eb221b

Browse files
CEL Dev Teamcopybara-github
authored andcommitted
Custom assertion function for the C++ testrunner.
PiperOrigin-RevId: 819065671
1 parent 215b338 commit 5eb221b

File tree

4 files changed

+46
-1
lines changed

4 files changed

+46
-1
lines changed

testing/testrunner/BUILD

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,14 @@ cc_library(
1313
hdrs = ["cel_test_context.h"],
1414
deps = [
1515
":cel_expression_source",
16+
"//common:value",
1617
"//compiler",
1718
"//eval/public:cel_expression",
1819
"//runtime",
1920
"//runtime:activation",
2021
"@com_google_absl//absl/base:nullability",
2122
"@com_google_absl//absl/container:flat_hash_map",
2223
"@com_google_absl//absl/memory",
23-
"@com_google_absl//absl/status",
2424
"@com_google_absl//absl/status:statusor",
2525
"@com_google_cel_spec//proto/cel/expr:checked_cc_proto",
2626
"@com_google_cel_spec//proto/cel/expr:value_cc_proto",

testing/testrunner/cel_test_context.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "absl/container/flat_hash_map.h"
2727
#include "absl/memory/memory.h"
2828
#include "absl/status/statusor.h"
29+
#include "common/value.h"
2930
#include "compiler/compiler.h"
3031
#include "eval/public/cel_expression.h"
3132
#include "runtime/activation.h"
@@ -42,6 +43,10 @@ class CelTestContext {
4243
using CelActivationFactoryFn = std::function<absl::StatusOr<cel::Activation>(
4344
const cel::expr::conformance::test::TestCase& test_case,
4445
google::protobuf::Arena* arena)>;
46+
using AssertFn = std::function<void(
47+
const cel::Value& computed,
48+
const cel::expr::conformance::test::TestCase& test_case,
49+
google::protobuf::Arena* arena)>;
4550

4651
// Creates a CelTestContext using a `CelExpressionBuilder`.
4752
//
@@ -127,6 +132,12 @@ class CelTestContext {
127132
return activation_factory_;
128133
}
129134

135+
// Allows the runner to inject a custom assertion function. If not set, the
136+
// default assertion logic in TestRunner will be used.
137+
void SetAssertFn(AssertFn assert_fn) { assert_fn_ = std::move(assert_fn); }
138+
139+
const AssertFn& assert_fn() const { return assert_fn_; }
140+
130141
private:
131142
// Delete copy and move constructors.
132143
CelTestContext(const CelTestContext&) = delete;
@@ -173,6 +184,7 @@ class CelTestContext {
173184
std::unique_ptr<const cel::Runtime> runtime_;
174185

175186
CelActivationFactoryFn activation_factory_;
187+
AssertFn assert_fn_;
176188
};
177189

178190
} // namespace cel::test

testing/testrunner/runner_lib.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,10 @@ void TestRunner::AssertError(const cel::Value& computed,
340340

341341
void TestRunner::Assert(const cel::Value& computed, const TestCase& test_case,
342342
google::protobuf::Arena* arena) {
343+
if (test_context_->assert_fn()) {
344+
test_context_->assert_fn()(computed, test_case, arena);
345+
return;
346+
}
343347
TestOutput output = test_case.output();
344348
if (output.has_result_value() || output.has_result_expr()) {
345349
AssertValue(computed, output, arena);

testing/testrunner/runner_lib_test.cc

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -652,6 +652,35 @@ TEST(TestRunnerStandaloneTest, BasicTestWithActivationFactorySucceeds) {
652652
EXPECT_NO_FATAL_FAILURE(test_runner.RunTest(test_case));
653653
}
654654

655+
TEST(TestRunnerStandaloneTest, CustomAssertFnIsUsed) {
656+
// Compile the expression.
657+
ASSERT_OK_AND_ASSIGN(cel::ValidationResult validation_result,
658+
DefaultCompiler().Compile("1 + 1"));
659+
CheckedExpr checked_expr;
660+
ASSERT_THAT(cel::AstToCheckedExpr(*validation_result.GetAst(), &checked_expr),
661+
absl_testing::IsOk());
662+
// Create a runtime.
663+
ASSERT_OK_AND_ASSIGN(std::unique_ptr<const cel::Runtime> runtime,
664+
CreateTestRuntime());
665+
// Set the output to a value that would fail the default assertion.
666+
TestCase test_case = ParseTextProtoOrDie<TestCase>(R"pb(
667+
output { result_value { int64_value: 102 } }
668+
)pb");
669+
std::unique_ptr<CelTestContext> context =
670+
CelTestContext::CreateFromRuntime(std::move(runtime));
671+
672+
context->SetAssertFn([&](const cel::Value& computed,
673+
const TestCase& test_case, google::protobuf::Arena* arena) {
674+
ASSERT_TRUE(computed.Is<cel::IntValue>());
675+
EXPECT_EQ(computed.As<cel::IntValue>().value(), 2);
676+
});
677+
678+
context->SetExpressionSource(
679+
CelExpressionSource::FromCheckedExpr(std::move(checked_expr)));
680+
TestRunner test_runner(std::move(context));
681+
EXPECT_NO_FATAL_FAILURE(test_runner.RunTest(test_case));
682+
}
683+
655684
TEST(CoverageTest, RuntimeCoverage) {
656685
ASSERT_OK_AND_ASSIGN(
657686
std::unique_ptr<cel::CompilerBuilder> compiler_builder,

0 commit comments

Comments
 (0)