@@ -115,6 +115,9 @@ public final class CelVerifierZ3ImplTest {
115115 .addVar (
116116 "test_all_types" ,
117117 StructTypeReference .create ("cel.expr.conformance.proto3.TestAllTypes" ))
118+ .addVar ("json_val" , StructTypeReference .create ("google.protobuf.Value" ))
119+ .addVar ("json_list" , StructTypeReference .create ("google.protobuf.ListValue" ))
120+ .addVar ("json_struct" , StructTypeReference .create ("google.protobuf.Struct" ))
118121 .build ();
119122
120123 private static final CelVerifier VERIFIER =
@@ -226,9 +229,6 @@ private enum IsSatisfiableInconclusiveTestCase {
226229 MASKED_BY_BMC_MAP (
227230 "string_int_map == {'a':1, 'b':2, 'c':3, 'd':4, 'e':5, 'f':6} ? string_int_map.exists(k,"
228231 + " k == 'g') : false" ),
229- MASKED_BY_BMC_NESTED (
230- "nested_list == [[1, 2, 3, 4, 5, 6]] ? nested_list.exists(row, row.exists(x, x == 42)) :"
231- + " false" ),
232232 APPROXIMATED_STRING_TO_INT ("int('123') == 123" ),
233233 APPROXIMATED_DOUBLE_TO_INT ("int(1.5) == 1" ),
234234 APPROXIMATED_INT_TO_STRING ("string(123) == '123'" ),
@@ -252,6 +252,26 @@ public void isSatisfiable_inconclusive(@TestParameter IsSatisfiableInconclusiveT
252252 assertThat (result .status ()).isEqualTo (VerificationStatus .INCONCLUSIVE );
253253 }
254254
255+ @ Test
256+ public void isSatisfiable_maskedByBmcNested_inconclusive () throws Exception {
257+ String expr =
258+ "nested_list == [[1, 2, 3, 4, 5, 6]] ? nested_list.exists(row, row.exists(x, x == 42)) :"
259+ + " false" ;
260+ CelAbstractSyntaxTree ast = CEL .compile (expr ).getAst ();
261+
262+ // Reduce the comprehension unroll limit specifically for this heavy nested query
263+ // to prevent Z3 from timing out during the macro expansion.
264+ CelVerifier customVerifier =
265+ CelVerifierFactory .newVerifier ()
266+ .setComprehensionUnrollLimit (3 )
267+ .setTypeProvider (VERIFIER .getTypeProvider ())
268+ .build ();
269+
270+ CelVerificationResult result = customVerifier .isSatisfiable (ast );
271+
272+ assertThat (result .status ()).isEqualTo (VerificationStatus .INCONCLUSIVE );
273+ }
274+
255275 @ Test
256276 public void isSatisfiable_comprehensionZeroUnrollLimit_inconclusive () throws Exception {
257277 String expr = "int_list == [1] ? int_list.exists(x, x == 1) : false" ;
@@ -1590,7 +1610,34 @@ private enum EquivalenceTestCase {
15901610 "true" ),
15911611 OPTIONAL_FIELD_SELECTION_MAP_COMPREHENSION (
15921612 "{'a': 1, 'b': 2}.transformMap(k, v, v > 1, v).?b" , "optional.of(2)" ),
1593- OPTIONAL_FIELD_SELECTION_BINDER ("cel.bind(m, {'a': 1}, m.?a)" , "optional.of(1)" );
1613+ OPTIONAL_FIELD_SELECTION_BINDER ("cel.bind(m, {'a': 1}, m.?a)" , "optional.of(1)" ),
1614+ JSON_VALUE_BOOL ("google.protobuf.Value{bool_value: true}" , "true" ),
1615+ JSON_VALUE_NUMBER ("google.protobuf.Value{number_value: 1.0}" , "1.0" ),
1616+ JSON_VALUE_NULL ("google.protobuf.Value{null_value: 0}" , "null" ),
1617+ JSON_VALUE_EMPTY ("google.protobuf.Value{}" , "null" ),
1618+ JSON_LIST_VALUE_EMPTY ("google.protobuf.ListValue{}" , "[]" ),
1619+ JSON_STRUCT_EMPTY ("google.protobuf.Struct{}" , "{}" ),
1620+ JSON_LIST_VALUE ("google.protobuf.ListValue{values: [1, 2]}" , "[1, 2]" ),
1621+ JSON_STRUCT ("google.protobuf.Struct{fields: {'a': 1}}" , "{'a': 1}" ),
1622+ JSON_DEEP_NESTING (
1623+ "google.protobuf.ListValue{values: [google.protobuf.Struct{fields: {'a':"
1624+ + " google.protobuf.Value{number_value: 1.0}}}]}" ,
1625+ "[{'a': 1.0}]" ),
1626+ JSON_NUMBER_HETEROGENEOUS_EQUALITY ("google.protobuf.Value{number_value: 1.0} == 1" , "true" ),
1627+ JSON_VALUE_OPTIONAL_NONE ("google.protobuf.Value{?string_value: optional.none()}" , "null" ),
1628+ JSON_LIST_VALUE_OPTIONAL_NONE ("google.protobuf.ListValue{?values: optional.none()}" , "[]" ),
1629+ JSON_STRUCT_OPTIONAL_NONE ("google.protobuf.Struct{?fields: optional.none()}" , "{}" ),
1630+ JSON_VALUE_TYPE_REFLECTION ("type(google.protobuf.Value{string_value: 'hi'}) == string" , "true" ),
1631+ JSON_STRUCT_TYPE_REFLECTION ("type(google.protobuf.Struct{fields: {'a': 1}}) == map" , "true" ),
1632+ JSON_VAR_VALUE_EQUALITY ("json_val == 'hi' || json_val != 'hi'" , "true" ),
1633+ JSON_VAR_LIST_EQUALITY ("json_list == [1, 2] || json_list != [1, 2]" , "true" ),
1634+ JSON_VAR_MAP_EQUALITY ("json_struct == {'a': 1} || json_struct != {'a': 1}" , "true" ),
1635+ JSON_VALUE_OPTIONAL_NULL_VALUE_NONE (
1636+ "google.protobuf.Value{?null_value: optional.none()}" , "null" ),
1637+ JSON_VALUE_OPTIONAL_NULL_VALUE_OF ("google.protobuf.Value{?null_value: optional.of(0)}" , "null" ),
1638+ OPTIONAL_INDEX_LIST_UNWRAPPING ("optional.of([1, 2, 3])[?0]" , "optional.of(1)" ),
1639+ OPTIONAL_INDEX_MAP_UNWRAPPING ("optional.of({'a': 1})[?'a']" , "optional.of(1)" ),
1640+ OPTIONAL_INDEX_UNWRAPPING_NONE ("optional.none()[?0]" , "optional.none()" );
15941641
15951642 private final String exprA ;
15961643 private final String exprB ;
@@ -1644,7 +1691,10 @@ private enum EquivalenceViolationTestCase {
16441691 "TestAllTypes{single_int32: 0}.?single_int32" , "optional.of(0)" ),
16451692 OPTIONAL_PROTO3_WRAPPER_ZERO_VS_UNSET (
16461693 "TestAllTypes{single_int64_wrapper: 0}.?single_int64_wrapper" ,
1647- "TestAllTypes{}.?single_int64_wrapper" );
1694+ "TestAllTypes{}.?single_int64_wrapper" ),
1695+ OPTIONAL_DYNAMIC_TARGET_TYPE_MISMATCH ("dyn_var.?a == optional.none()" , "false" ),
1696+ OPTIONAL_NESTED_NONE_VS_MISSING (
1697+ "{'a': optional.none()}.?a.orValue(optional.of(1))" , "optional.of(1)" );
16481698
16491699 final String exprA ;
16501700 final String exprB ;
0 commit comments