Skip to content

Commit 285b058

Browse files
jnthntatumcopybara-github
authored andcommitted
Add test cases around type-checking gp.NullValue
google.protobuf.NullValue is represented as an enum (int in CEL), but is interpreted to mean a null literal when set as the alternative in google.protobuf.Value. It is not normally referenced directly, but behaves a bit surprisingly when it is. PiperOrigin-RevId: 881561365
1 parent 84b5c5d commit 285b058

3 files changed

Lines changed: 154 additions & 0 deletions

File tree

checker/src/test/java/dev/cel/checker/ExprCheckerTest.java

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,71 @@ public void jsonType() throws Exception {
517517
runTest();
518518
}
519519

520+
@Test
521+
public void jsonTypeNullConstruction() throws Exception {
522+
// Ok
523+
source = "google.protobuf.Value{null_value: google.protobuf.NullValue.NULL_VALUE}";
524+
runTest();
525+
526+
// Error
527+
source = "google.protobuf.Value{null_value: null}";
528+
runTest();
529+
530+
// Ok
531+
source = "cel.expr.conformance.proto3.TestAllTypes{single_value: null}";
532+
runTest();
533+
534+
// Ok but not expected (int coerced to double/json number 0.0)
535+
source =
536+
"cel.expr.conformance.proto3.TestAllTypes{single_value:"
537+
+ " google.protobuf.NullValue.NULL_VALUE}";
538+
runTest();
539+
540+
// Error
541+
source = "cel.expr.conformance.proto3.TestAllTypes{null_value: null}";
542+
runTest();
543+
544+
// Ok
545+
source =
546+
"cel.expr.conformance.proto3.TestAllTypes{null_value:"
547+
+ " google.protobuf.NullValue.NULL_VALUE}";
548+
runTest();
549+
}
550+
551+
@Test
552+
public void jsonTypeNullAccess() throws Exception {
553+
source = "google.protobuf.Value{null_value: google.protobuf.NullValue.NULL_VALUE} == null";
554+
runTest();
555+
556+
source = "cel.expr.conformance.proto3.TestAllTypes{single_value: null}.single_value == null";
557+
runTest();
558+
559+
source =
560+
"cel.expr.conformance.proto3.TestAllTypes{single_value:"
561+
+ " google.protobuf.NullValue.NULL_VALUE}.single_value == null";
562+
runTest();
563+
564+
// Error
565+
source =
566+
"cel.expr.conformance.proto3.TestAllTypes{null_value:"
567+
+ " google.protobuf.NullValue.NULL_VALUE}.null_value == null";
568+
runTest();
569+
570+
// Ok
571+
source =
572+
"cel.expr.conformance.proto3.TestAllTypes{null_value:"
573+
+ " google.protobuf.NullValue.NULL_VALUE}.null_value == 0";
574+
runTest();
575+
576+
// Error
577+
source = "google.protobuf.NullValue.NULL_VALUE == null";
578+
runTest();
579+
580+
// Ok
581+
source = "google.protobuf.NullValue.NULL_VALUE == 0";
582+
runTest();
583+
}
584+
520585
// Call Style and User Functions
521586
// =============================
522587

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
Source: google.protobuf.Value{null_value: google.protobuf.NullValue.NULL_VALUE} == null
2+
=====>
3+
_==_(
4+
google.protobuf.Value{
5+
null_value:google.protobuf.NullValue.NULL_VALUE~int^google.protobuf.NullValue.NULL_VALUE
6+
}~dyn^google.protobuf.Value,
7+
null~null
8+
)~bool^equals
9+
10+
Source: cel.expr.conformance.proto3.TestAllTypes{single_value: null}.single_value == null
11+
=====>
12+
_==_(
13+
cel.expr.conformance.proto3.TestAllTypes{
14+
single_value:null~null
15+
}~cel.expr.conformance.proto3.TestAllTypes^cel.expr.conformance.proto3.TestAllTypes.single_value~dyn,
16+
null~null
17+
)~bool^equals
18+
19+
Source: cel.expr.conformance.proto3.TestAllTypes{single_value: google.protobuf.NullValue.NULL_VALUE}.single_value == null
20+
=====>
21+
_==_(
22+
cel.expr.conformance.proto3.TestAllTypes{
23+
single_value:google.protobuf.NullValue.NULL_VALUE~int^google.protobuf.NullValue.NULL_VALUE
24+
}~cel.expr.conformance.proto3.TestAllTypes^cel.expr.conformance.proto3.TestAllTypes.single_value~dyn,
25+
null~null
26+
)~bool^equals
27+
28+
Source: cel.expr.conformance.proto3.TestAllTypes{null_value: google.protobuf.NullValue.NULL_VALUE}.null_value == null
29+
=====>
30+
ERROR: test_location:1:103: found no matching overload for '_==_' applied to '(int, null)' (candidates: (%A0, %A0))
31+
| cel.expr.conformance.proto3.TestAllTypes{null_value: google.protobuf.NullValue.NULL_VALUE}.null_value == null
32+
| ......................................................................................................^
33+
34+
Source: cel.expr.conformance.proto3.TestAllTypes{null_value: google.protobuf.NullValue.NULL_VALUE}.null_value == 0
35+
=====>
36+
_==_(
37+
cel.expr.conformance.proto3.TestAllTypes{
38+
null_value:google.protobuf.NullValue.NULL_VALUE~int^google.protobuf.NullValue.NULL_VALUE
39+
}~cel.expr.conformance.proto3.TestAllTypes^cel.expr.conformance.proto3.TestAllTypes.null_value~int,
40+
0~int
41+
)~bool^equals
42+
43+
Source: google.protobuf.NullValue.NULL_VALUE == null
44+
=====>
45+
ERROR: test_location:1:38: found no matching overload for '_==_' applied to '(int, null)' (candidates: (%A0, %A0))
46+
| google.protobuf.NullValue.NULL_VALUE == null
47+
| .....................................^
48+
49+
Source: google.protobuf.NullValue.NULL_VALUE == 0
50+
=====>
51+
_==_(
52+
google.protobuf.NullValue.NULL_VALUE~int^google.protobuf.NullValue.NULL_VALUE,
53+
0~int
54+
)~bool^equals
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
Source: google.protobuf.Value{null_value: google.protobuf.NullValue.NULL_VALUE}
2+
=====>
3+
google.protobuf.Value{
4+
null_value:google.protobuf.NullValue.NULL_VALUE~int^google.protobuf.NullValue.NULL_VALUE
5+
}~dyn^google.protobuf.Value
6+
7+
Source: google.protobuf.Value{null_value: null}
8+
=====>
9+
ERROR: test_location:1:33: expected type of field 'null_value' is 'int' but provided type is 'null'
10+
| google.protobuf.Value{null_value: null}
11+
| ................................^
12+
13+
Source: cel.expr.conformance.proto3.TestAllTypes{single_value: null}
14+
=====>
15+
cel.expr.conformance.proto3.TestAllTypes{
16+
single_value:null~null
17+
}~cel.expr.conformance.proto3.TestAllTypes^cel.expr.conformance.proto3.TestAllTypes
18+
19+
Source: cel.expr.conformance.proto3.TestAllTypes{single_value: google.protobuf.NullValue.NULL_VALUE}
20+
=====>
21+
cel.expr.conformance.proto3.TestAllTypes{
22+
single_value:google.protobuf.NullValue.NULL_VALUE~int^google.protobuf.NullValue.NULL_VALUE
23+
}~cel.expr.conformance.proto3.TestAllTypes^cel.expr.conformance.proto3.TestAllTypes
24+
25+
Source: cel.expr.conformance.proto3.TestAllTypes{null_value: null}
26+
=====>
27+
ERROR: test_location:1:52: expected type of field 'null_value' is 'int' but provided type is 'null'
28+
| cel.expr.conformance.proto3.TestAllTypes{null_value: null}
29+
| ...................................................^
30+
31+
Source: cel.expr.conformance.proto3.TestAllTypes{null_value: google.protobuf.NullValue.NULL_VALUE}
32+
=====>
33+
cel.expr.conformance.proto3.TestAllTypes{
34+
null_value:google.protobuf.NullValue.NULL_VALUE~int^google.protobuf.NullValue.NULL_VALUE
35+
}~cel.expr.conformance.proto3.TestAllTypes^cel.expr.conformance.proto3.TestAllTypes

0 commit comments

Comments
 (0)