52
52
#include " cel/expr/conformance/proto3/test_all_types.pb.h"
53
53
#include " google/protobuf/arena.h"
54
54
#include " google/protobuf/message.h"
55
+ #include " google/protobuf/text_format.h"
55
56
56
57
namespace google ::api::expr::runtime {
57
58
@@ -103,6 +104,7 @@ struct RecursiveTestCase {
103
104
std::string test_name;
104
105
std::string expr;
105
106
test::CelValueMatcher matcher;
107
+ std::string pb_expr;
106
108
};
107
109
108
110
class RecursivePlanTest : public ::testing::TestWithParam<RecursiveTestCase> {
@@ -144,19 +146,29 @@ class RecursivePlanTest : public ::testing::TestWithParam<RecursiveTestCase> {
144
146
}
145
147
};
146
148
147
- absl::StatusOr<ParsedExpr> ParseWithBind (absl::string_view cel ) {
149
+ absl::StatusOr<ParsedExpr> ParseTestCase ( const RecursiveTestCase& test_case ) {
148
150
static const std::vector<Macro>* kMacros = []() {
149
151
auto * result = new std::vector<Macro>(Macro::AllMacros ());
150
152
absl::c_copy (cel::extensions::bindings_macros (),
151
153
std::back_inserter (*result));
152
154
return result;
153
155
}();
154
- return ParseWithMacros (cel, *kMacros , " <input>" );
156
+
157
+ if (!test_case.expr .empty ()) {
158
+ return ParseWithMacros (test_case.expr , *kMacros , " <input>" );
159
+ } else if (!test_case.pb_expr .empty ()) {
160
+ ParsedExpr result;
161
+ if (!google::protobuf::TextFormat::ParseFromString (test_case.pb_expr , &result)) {
162
+ return absl::InvalidArgumentError (" Failed to parse proto" );
163
+ }
164
+ return result;
165
+ }
166
+ return absl::InvalidArgumentError (" No expression provided" );
155
167
}
156
168
157
169
TEST_P (RecursivePlanTest, ParsedExprRecursiveImpl) {
158
170
const RecursiveTestCase& test_case = GetParam ();
159
- ASSERT_OK_AND_ASSIGN (ParsedExpr parsed_expr, ParseWithBind (test_case. expr ));
171
+ ASSERT_OK_AND_ASSIGN (ParsedExpr parsed_expr, ParseTestCase (test_case));
160
172
cel::RuntimeOptions options;
161
173
options.container = " cel.expr.conformance.proto3" ;
162
174
google::protobuf::Arena arena;
@@ -183,7 +195,7 @@ TEST_P(RecursivePlanTest, ParsedExprRecursiveImpl) {
183
195
184
196
TEST_P (RecursivePlanTest, ParsedExprRecursiveOptimizedImpl) {
185
197
const RecursiveTestCase& test_case = GetParam ();
186
- ASSERT_OK_AND_ASSIGN (ParsedExpr parsed_expr, ParseWithBind (test_case. expr ));
198
+ ASSERT_OK_AND_ASSIGN (ParsedExpr parsed_expr, ParseTestCase (test_case));
187
199
cel::RuntimeOptions options;
188
200
options.container = " cel.expr.conformance.proto3" ;
189
201
google::protobuf::Arena arena;
@@ -216,7 +228,7 @@ TEST_P(RecursivePlanTest, ParsedExprRecursiveOptimizedImpl) {
216
228
217
229
TEST_P (RecursivePlanTest, ParsedExprRecursiveTraceSupport) {
218
230
const RecursiveTestCase& test_case = GetParam ();
219
- ASSERT_OK_AND_ASSIGN (ParsedExpr parsed_expr, ParseWithBind (test_case. expr ));
231
+ ASSERT_OK_AND_ASSIGN (ParsedExpr parsed_expr, ParseTestCase (test_case));
220
232
cel::RuntimeOptions options;
221
233
options.container = " cel.expr.conformance.proto3" ;
222
234
google::protobuf::Arena arena;
@@ -249,7 +261,7 @@ TEST_P(RecursivePlanTest, Disabled) {
249
261
google::protobuf::LinkMessageReflection<TestAllTypes>();
250
262
251
263
const RecursiveTestCase& test_case = GetParam ();
252
- ASSERT_OK_AND_ASSIGN (ParsedExpr parsed_expr, ParseWithBind (test_case. expr ));
264
+ ASSERT_OK_AND_ASSIGN (ParsedExpr parsed_expr, ParseTestCase (test_case));
253
265
cel::RuntimeOptions options;
254
266
options.container = " cel.expr.conformance.proto3" ;
255
267
google::protobuf::Arena arena;
@@ -326,7 +338,212 @@ INSTANTIATE_TEST_SUITE_P(
326
338
{" re_matches_receiver" ,
327
339
" (string_abc + string_def).matches(r'(123)?' + r'abc' + r'def')" ,
328
340
test::IsCelBool (true )},
329
- }),
341
+ {" block" , " " , test::IsCelBool (true ),
342
+ R"pb(
343
+ expr {
344
+ id: 1
345
+ call_expr {
346
+ function: "cel.@block"
347
+ args {
348
+ id: 2
349
+ list_expr {
350
+ elements { const_expr { int64_value: 8 } }
351
+ elements { const_expr { int64_value: 10 } }
352
+ }
353
+ }
354
+ args {
355
+ id: 3
356
+ call_expr {
357
+ function: "_<_"
358
+ args { ident_expr { name: "@index0" } }
359
+ args { ident_expr { name: "@index1" } }
360
+ }
361
+ }
362
+ }
363
+ })pb" },
364
+ {" block_with_comprehensions" , " " , test::IsCelBool (true ),
365
+ // Something like:
366
+ // variables:
367
+ // - users: {'bob': ['bar'], 'alice': ['foo', 'bar']}
368
+ // - somone_has_bar: users.exists(u, 'bar' in users[u])
369
+ // policy:
370
+ // - someone_has_bar && !users.exists(u, u == 'eve'))
371
+ //
372
+ R"pb(
373
+ expr {
374
+ call_expr {
375
+ function: "cel.@block"
376
+ args {
377
+ list_expr {
378
+ elements {
379
+ struct_expr: {
380
+ entries: {
381
+ map_key: { const_expr: { string_value: "bob" } }
382
+ value: {
383
+ list_expr: {
384
+ elements: { const_expr: { string_value: "bar" } }
385
+ }
386
+ }
387
+ }
388
+ entries: {
389
+ map_key: { const_expr: { string_value: "alice" } }
390
+ value: {
391
+ list_expr: {
392
+ elements: { const_expr: { string_value: "bar" } }
393
+ elements: { const_expr: { string_value: "foo" } }
394
+ }
395
+ }
396
+ }
397
+ }
398
+ }
399
+ elements {
400
+ id: 16
401
+ comprehension_expr: {
402
+ iter_var: "u"
403
+ iter_range: {
404
+ id: 1
405
+ ident_expr: { name: "@index0" }
406
+ }
407
+ accu_var: "__result__"
408
+ accu_init: {
409
+ id: 9
410
+ const_expr: { bool_value: false }
411
+ }
412
+ loop_condition: {
413
+ id: 12
414
+ call_expr: {
415
+ function: "@not_strictly_false"
416
+ args: {
417
+ id: 11
418
+ call_expr: {
419
+ function: "!_"
420
+ args: {
421
+ id: 10
422
+ ident_expr: { name: "__result__" }
423
+ }
424
+ }
425
+ }
426
+ }
427
+ }
428
+ loop_step: {
429
+ id: 14
430
+ call_expr: {
431
+ function: "_||_"
432
+ args: {
433
+ id: 13
434
+ ident_expr: { name: "__result__" }
435
+ }
436
+ args: {
437
+ id: 5
438
+ call_expr: {
439
+ function: "@in"
440
+ args: {
441
+ id: 4
442
+ const_expr: { string_value: "bar" }
443
+ }
444
+ args: {
445
+ id: 7
446
+ call_expr: {
447
+ function: "_[_]"
448
+ args: {
449
+ id: 6
450
+ ident_expr: { name: "@index0" }
451
+ }
452
+ args: {
453
+ id: 8
454
+ ident_expr: { name: "u" }
455
+ }
456
+ }
457
+ }
458
+ }
459
+ }
460
+ }
461
+ }
462
+ result: {
463
+ id: 15
464
+ ident_expr: { name: "__result__" }
465
+ }
466
+ }
467
+ }
468
+ }
469
+ }
470
+ args {
471
+ id: 17
472
+ call_expr: {
473
+ function: "_&&_"
474
+ args: {
475
+ id: 1
476
+ ident_expr: { name: "@index1" }
477
+ }
478
+ args: {
479
+ id: 2
480
+ call_expr: {
481
+ function: "!_"
482
+ args: {
483
+ id: 16
484
+ comprehension_expr: {
485
+ iter_var: "u"
486
+ iter_range: {
487
+ id: 3
488
+ ident_expr: { name: "@index0" }
489
+ }
490
+ accu_var: "__result__"
491
+ accu_init: {
492
+ id: 9
493
+ const_expr: { bool_value: false }
494
+ }
495
+ loop_condition: {
496
+ id: 12
497
+ call_expr: {
498
+ function: "@not_strictly_false"
499
+ args: {
500
+ id: 11
501
+ call_expr: {
502
+ function: "!_"
503
+ args: {
504
+ id: 10
505
+ ident_expr: { name: "__result__" }
506
+ }
507
+ }
508
+ }
509
+ }
510
+ }
511
+ loop_step: {
512
+ id: 14
513
+ call_expr: {
514
+ function: "_||_"
515
+ args: {
516
+ id: 13
517
+ ident_expr: { name: "__result__" }
518
+ }
519
+ args: {
520
+ id: 7
521
+ call_expr: {
522
+ function: "_==_"
523
+ args: {
524
+ id: 6
525
+ ident_expr: { name: "u" }
526
+ }
527
+ args: {
528
+ id: 8
529
+ const_expr: { string_value: "eve" }
530
+ }
531
+ }
532
+ }
533
+ }
534
+ }
535
+ result: {
536
+ id: 15
537
+ ident_expr: { name: "__result__" }
538
+ }
539
+ }
540
+ }
541
+ }
542
+ }
543
+ }
544
+ }
545
+ }
546
+ })pb" }}),
330
547
331
548
[](const testing::TestParamInfo<RecursiveTestCase>& info) -> std::string {
332
549
return info.param .test_name ;
0 commit comments