# proto-file: ../../../proto/cel/expr/conformance/test/simple.proto # proto-message: cel.expr.conformance.test.SimpleTestFile name: "comparisons" description: "Tests for boolean-valued functions and operators." section { name: "eq_literal" description: "Literals comparison on _==_" test { name: "eq_int" expr: "1 == 1" value: { bool_value: true } } test { name: "not_eq_int" expr: "-1 == 1" value: { bool_value: false } } test { name: "eq_int_uint" expr: "dyn(1) == 1u" value: { bool_value: true } } test { name: "not_eq_int_uint" expr: "dyn(2) == 1u" value: { bool_value: false } } test { name: "eq_int_double" expr: "dyn(1) == 1.0" value: { bool_value: true } } test { name: "not_eq_int_double" expr: "dyn(2) == 1.0" value: { bool_value: false } } test { name: "eq_uint" expr: "2u == 2u" value: { bool_value: true } } test { name: "not_eq_uint" expr: "1u == 2u" value: { bool_value: false } } test { name: "eq_uint_int" expr: "dyn(1u) == 1" value: { bool_value: true } } test { name: "not_eq_uint_int" expr: "dyn(2u) == 1" value: { bool_value: false } } test { name: "eq_uint_double" expr: "dyn(1u) == 1.0" value: { bool_value: true } } test { name: "not_eq_uint_double" expr: "dyn(2u) == 1.0" value: { bool_value: false } } test { name: "eq_double" expr: "1.0 == 1.0e+0" value: { bool_value: true } } test { name: "not_eq_double" expr: "-1.0 == 1.0" value: { bool_value: false } } test { name: "not_eq_double_nan" expr: "0.0/0.0 == 0.0/0.0" value: { bool_value: false } } test { name: "not_eq_int_double_nan" expr: "dyn(1) == 0.0/0.0" value: { bool_value: false } } test { name: "not_eq_uint_double_nan" expr: "dyn(1u) == 0.0/0.0" value: { bool_value: false } } test { name: "eq_double_int" expr: "dyn(1.0) == 1" value: { bool_value: true } } test { name: "not_eq_double_int" expr: "dyn(2.0) == 1" value: { bool_value: false } } test { name: "eq_double_uint" expr: "dyn(1.0) == 1u" value: { bool_value: true } } test { name: "not_eq_double_uint" expr: "dyn(2.0) == 1u" value: { bool_value: false } } test { name: "eq_string" expr: "'' == \"\"" value: { bool_value: true } } test { name: "not_eq_string" expr: "'a' == 'b'" value: { bool_value: false } } test { name: "eq_raw_string" expr: "'abc' == r'abc'" value: { bool_value: true } } test { name: "not_eq_string_case" expr: "'abc' == 'ABC'" value: { bool_value: false } } test { name: "eq_string_unicode" expr: "'ίσος' == 'ίσος'" value: { bool_value: true } } test { name: "not_eq_string_unicode_ascii" expr: "'a' == 'à'" value: { bool_value: false } } test { name: "no_string_normalization" description: "Should not normalize Unicode." expr: "'Am\\u00E9lie' == 'Ame\\u0301lie'" value: { bool_value: false } } test { name: "eq_null" expr: "null == null" value: { bool_value: true } } test { name: "eq_bool" expr: "true == true" value: { bool_value: true } } test { name: "not_eq_bool" expr: "false == true" value: { bool_value: false } } test { name: "eq_bytes" description: "Test bytes literal equality with encoding" expr: "b'ÿ' == b'\\303\\277'" value: { bool_value: true } } test { name: "not_eq_bytes" expr: "b'abc' == b'abcd'" value: { bool_value: false } } test { name: "eq_list_empty" expr: "[] == []" value: { bool_value: true } } test { name: "eq_list_null" expr: "[null] == [null]" value: { bool_value: true } } test { name: "not_eq_list_null" expr: "['1', '2', null] == ['1', '2', '3']" value: { bool_value: false } } test { name: "eq_list_numbers" expr: "[1, 2, 3] == [1, 2, 3]" value: { bool_value: true } } test { name: "eq_list_mixed_type_numbers" expr: "[1.0, 2.0, 3] == [1u, 2, 3u]" value: { bool_value: true } } test { name: "not_eq_list_mixed_type_numbers" expr: "[1.0, 2.1] == [1u, 2]" value: { bool_value: false } } test { name: "not_eq_list_order" expr: "[1, 2, 3] == [1, 3, 2]" value: { bool_value: false } } test { name: "not_eq_list_string_case" expr: "['case'] == ['cAse']" value: { bool_value: false } } test { name: "not_eq_list_length" expr: "['one'] == [2, 3]" disable_check: true value: { bool_value: false } } test { name: "not_eq_list_false_vs_types" expr: "[1, 'dos', 3] == [1, 2, 4]" value: { bool_value: false } } test { name: "eq_map_empty" expr: "{} == {}" value: { bool_value: true } } test { name: "eq_map_null" expr: "{'k': null} == {'k': null}" value: { bool_value: true } } test { name: "not_eq_map_null" expr: "{'k': 1, 'j': 2} == {'k': 1, 'j': null}" value: { bool_value: false } } test { name: "eq_map_onekey" expr: "{'k':'v'} == {\"k\":\"v\"}" value: { bool_value: true } } test { name: "eq_map_double_value" expr: "{'k':1.0} == {'k':1e+0}" value: { bool_value: true } } test { name: "eq_map_mixed_type_numbers" expr: "{1: 1.0, 2u: 3u} == {1u: 1, 2: 3.0}" value: { bool_value: true } } test { name: "not_eq_map_value" expr: "{'k':'v'} == {'k':'v1'}" value: { bool_value: false } } test { name: "not_eq_map_extra_key" expr: "{'k':'v','k1':'v1'} == {'k':'v'}" value: { bool_value: false } } test { name: "eq_map_key_order" expr: "{'k1':'v1','k2':'v2'} == {'k2':'v2','k1':'v1'}" value: { bool_value: true } } test { name: "not_eq_map_key_casing" expr: "{'key':'value'} == {'Key':'value'}" value: { bool_value: false } } test { name: "not_eq_map_false_vs_types" expr: "{'k1': 1, 'k2': 'dos', 'k3': 3} == {'k1': 1, 'k2': 2, 'k3': 4}" value: { bool_value: false } } test { name: "eq_mixed_types" expr: "1.0 == 1" disable_check: true # need to make it fail in the evaluation phase value: { bool_value: true } } test { name: "eq_list_elem_mixed_types" expr: "[1] == [1.0]" disable_check: true # need to make it fail in the evaluation phase value: { bool_value: true } } test { name: "eq_map_value_mixed_types" expr: "{'k':'v', 1:1} == {'k':'v', 1:'v1'}" value: { bool_value: false } } test { name: "eq_dyn_json_null" expr: "dyn(google.protobuf.Value{}) == null" value: { bool_value: true } } test { name: "not_eq_dyn_bool_null" expr: "dyn(false) == null" value: { bool_value: false } } test { name: "not_eq_dyn_bytes_null" expr: "dyn(b'') == null" value: { bool_value: false } } test { name: "not_eq_dyn_double_null" expr: "dyn(2.1) == null" value: { bool_value: false } } test { name: "not_eq_dyn_duration_null" expr: "dyn(duration('0s')) == null" value: { bool_value: false } } test { name: "not_eq_dyn_int_null" expr: "dyn(1) == null" value: { bool_value: false } } test { name: "not_eq_dyn_list_null" expr: "dyn([]) == null" value: { bool_value: false } } test { name: "not_eq_dyn_map_null" expr: "dyn({}) == null" value: { bool_value: false } } test { name: "not_eq_dyn_proto2_msg_null" container: "cel.expr.conformance.proto2" expr: "dyn(TestAllTypes{}) == null" value: { bool_value: false } } test { name: "not_eq_dyn_proto3_msg_null" container: "cel.expr.conformance.proto3" expr: "dyn(TestAllTypes{}) == null" value: { bool_value: false } } test { name: "not_eq_dyn_string_null" expr: "dyn('') == null" value: { bool_value: false } } test { name: "not_eq_dyn_timestamp_null" expr: "dyn(timestamp(0)) == null" value: { bool_value: false } } test { name: "not_eq_list_elem_null" expr: "[1, 2, null] == [1, null, 3]" value: { bool_value: false } } test { name: "not_eq_map_value_null" expr: "{1:'hello', 2:'world'} == {1:'goodbye', 2:null}" value: { bool_value: false } } test { name: "eq_dyn_int_uint" expr: "dyn(1) == 1u" value: { bool_value: true } } test { name: "eq_dyn_int_double" expr: "dyn(1) == 1.0" value: { bool_value: true } } test { name: "eq_dyn_uint_int" expr: "dyn(1u) == 1" value: { bool_value: true } } test { name: "eq_dyn_uint_double" expr: "dyn(1u) == 1.0" value: { bool_value: true } } test { name: "eq_dyn_double_int" expr: "dyn(1.0) == 1" value: { bool_value: true } } test { name: "eq_dyn_double_uint" expr: "dyn(1.0) == 1u" value: { bool_value: true } } test { name: "not_eq_dyn_int_uint" expr: "dyn(1) == 2u" value: { bool_value: false } } test { name: "not_eq_dyn_int_double" expr: "dyn(1) == 2.0" value: { bool_value: false } } test { name: "not_eq_dyn_uint_int" expr: "dyn(1u) == 2" value: { bool_value: false } } test { name: "not_eq_dyn_uint_double" expr: "dyn(1u) == 120" value: { bool_value: false } } test { name: "not_eq_dyn_double_int" expr: "dyn(1.0) == 2" value: { bool_value: false } } test { name: "not_eq_dyn_double_uint" expr: "dyn(1.0) == 2u" value: { bool_value: false } } } section { name: "eq_wrapper" description: "Wrapper type comparison on _==_. Wrapper types treated as boxed primitives when they appear on message fields. An unset wrapper field should be treated as null. The tests show the distinction between unset, empty, and set equality behavior." test { name: "eq_bool" expr: "google.protobuf.BoolValue{value: true} == true" value: { bool_value: true } } test { name: "eq_bool_empty" expr: "google.protobuf.BoolValue{} == false" value: { bool_value: true } } test { name: "eq_bool_not_null" expr: "google.protobuf.BoolValue{} != null" value: { bool_value: true } } test { name: "eq_bool_proto2_null" container: "cel.expr.conformance.proto2" expr: "TestAllTypes{}.single_bool_wrapper == null" value: { bool_value: true } } test { name: "eq_bool_proto3_null" container: "cel.expr.conformance.proto3" expr: "TestAllTypes{}.single_bool_wrapper == null" value: { bool_value: true } } test { name: "eq_bytes" expr: "google.protobuf.BytesValue{value: b'set'} == b'set'" value: { bool_value: true } } test { name: "eq_bytes_empty" expr: "google.protobuf.BytesValue{} == b''" value: { bool_value: true } } test { name: "eq_bytes_not_null" expr: "google.protobuf.BytesValue{} != null" value: { bool_value: true } } test { name: "eq_bytes_proto2_null" container: "cel.expr.conformance.proto2" expr: "TestAllTypes{}.single_bytes_wrapper == null" value: { bool_value: true } } test { name: "eq_bytes_proto3_null" container: "cel.expr.conformance.proto3" expr: "TestAllTypes{}.single_bytes_wrapper == null" value: { bool_value: true } } test { name: "eq_double" expr: "google.protobuf.DoubleValue{value: -1.175494e-40} == -1.175494e-40" value: { bool_value: true } } test { name: "eq_double_empty" expr: "google.protobuf.DoubleValue{} == 0.0" value: { bool_value: true } } test { name: "eq_double_not_null" expr: "google.protobuf.DoubleValue{} != null" value: { bool_value: true } } test { name: "eq_double_proto2_null" container: "cel.expr.conformance.proto2" expr: "TestAllTypes{}.single_double_wrapper == null" value: { bool_value: true } } test { name: "eq_double_proto3_null" container: "cel.expr.conformance.proto3" expr: "TestAllTypes{}.single_double_wrapper == null" value: { bool_value: true } } test { name: "eq_float" expr: "google.protobuf.FloatValue{value: -1.5} == -1.5" value: { bool_value: true } } test { name: "eq_float_empty" expr: "google.protobuf.FloatValue{} == 0.0" value: { bool_value: true } } test { name: "eq_float_not_null" expr: "google.protobuf.FloatValue{} != null" value: { bool_value: true } } test { name: "eq_float_proto2_null" container: "cel.expr.conformance.proto2" expr: "TestAllTypes{}.single_float_wrapper == null" value: { bool_value: true } } test { name: "eq_float_proto3_null" container: "cel.expr.conformance.proto3" expr: "TestAllTypes{}.single_float_wrapper == null" value: { bool_value: true } } test { name: "eq_int32" expr: "google.protobuf.Int32Value{value: 123} == 123" value: { bool_value: true } } test { name: "eq_int32_empty" expr: "google.protobuf.Int32Value{} == 0" value: { bool_value: true } } test { name: "eq_int32_not_null" expr: "google.protobuf.Int32Value{} != null" value: { bool_value: true } } test { name: "eq_int32_proto2_null" container: "cel.expr.conformance.proto2" expr: "TestAllTypes{}.single_int32_wrapper == null" value: { bool_value: true } } test { name: "eq_int32_proto3_null" container: "cel.expr.conformance.proto3" expr: "TestAllTypes{}.single_int32_wrapper == null" value: { bool_value: true } } test { name: "eq_int64" expr: "google.protobuf.Int64Value{value: 2147483650} == 2147483650" value: { bool_value: true } } test { name: "eq_int64_empty" expr: "google.protobuf.Int64Value{} == 0" value: { bool_value: true } } test { name: "eq_int64_not_null" expr: "google.protobuf.Int64Value{} != null" value: { bool_value: true } } test { name: "eq_int64_proto2_null" container: "cel.expr.conformance.proto2" expr: "TestAllTypes{}.single_int64_wrapper == null" value: { bool_value: true } } test { name: "eq_int64_proto3_null" container: "cel.expr.conformance.proto3" expr: "TestAllTypes{}.single_int64_wrapper == null" value: { bool_value: true } } test { name: "eq_string" expr: "google.protobuf.StringValue{value: 'set'} == 'set'" value: { bool_value: true } } test { name: "eq_string_empty" expr: "google.protobuf.StringValue{} == ''" value: { bool_value: true } } test { name: "eq_string_not_null" expr: "google.protobuf.StringValue{} != null" value: { bool_value: true } } test { name: "eq_string_proto2_null" container: "cel.expr.conformance.proto2" expr: "TestAllTypes{}.single_string_wrapper == null" value: { bool_value: true } } test { name: "eq_string_proto3_null" container: "cel.expr.conformance.proto3" expr: "TestAllTypes{}.single_string_wrapper == null" value: { bool_value: true } } test { name: "eq_uint32" expr: "google.protobuf.UInt32Value{value: 42u} == 42u" value: { bool_value: true } } test { name: "eq_uint32_empty" expr: "google.protobuf.UInt32Value{} == 0u" value: { bool_value: true } } test { name: "eq_uint32_not_null" expr: "google.protobuf.UInt32Value{} != null" value: { bool_value: true } } test { name: "eq_uint32_proto2_null" container: "cel.expr.conformance.proto2" expr: "TestAllTypes{}.single_uint32_wrapper == null" value: { bool_value: true } } test { name: "eq_uint32_proto3_null" container: "cel.expr.conformance.proto3" expr: "TestAllTypes{}.single_uint32_wrapper == null" value: { bool_value: true } } test { name: "eq_uint64" expr: "google.protobuf.UInt64Value{value: 4294967296u} == 4294967296u" value: { bool_value: true } } test { name: "eq_uint64_empty" expr: "google.protobuf.UInt64Value{} == 0u" value: { bool_value: true } } test { name: "eq_uint64_not_null" expr: "google.protobuf.UInt64Value{} != null" value: { bool_value: true } } test { name: "eq_uint64_proto2_null" container: "cel.expr.conformance.proto2" expr: "TestAllTypes{}.single_uint64_wrapper == null" value: { bool_value: true } } test { name: "eq_uint64_proto3_null" container: "cel.expr.conformance.proto3" expr: "TestAllTypes{}.single_uint64_wrapper == null" value: { bool_value: true } } test { name: "eq_proto2" container: "cel.expr.conformance.proto2" expr: "TestAllTypes{single_int64: 1234, single_string: '1234'} == TestAllTypes{single_int64: 1234, single_string: '1234'}" value { bool_value: true } } test { name: "eq_proto3" container: "cel.expr.conformance.proto3" expr: "TestAllTypes{single_int64: 1234, single_string: '1234'} == TestAllTypes{single_int64: 1234, single_string: '1234'}" value { bool_value: true } } test { name: "eq_proto2_missing_fields_neq" container: "cel.expr.conformance.proto2" expr: "TestAllTypes{single_int64: 1234} == TestAllTypes{single_string: '1234'}" value { bool_value: false } } test { name: "eq_proto3_missing_fields_neq" container: "cel.expr.conformance.proto3" expr: "TestAllTypes{single_int64: 1234} == TestAllTypes{single_string: '1234'}" value { bool_value: false } } test { name: "eq_proto_nan_equal" container: "cel.expr.conformance.proto2" description: "For proto equality, fields with NaN value are treated as not equal." expr: "TestAllTypes{single_double: double('NaN')} == TestAllTypes{single_double: double('NaN')}" value { bool_value: false } } test { name: "eq_proto_different_types" container: "cel.expr.conformance.proto2" description: "At runtime, differently typed messages are treated as not equal." expr: "dyn(TestAllTypes{}) == dyn(NestedTestAllTypes{})" value { bool_value: false } } test { name: "eq_proto2_any_unpack_equal" description: "Any values should be unpacked and compared." container: "cel.expr.conformance.proto2" # Two equal messages with any fields serialized differently (but both are valid). # TestAllTypes{single_any: [TestAllTypes]{single_int64: 1234, single_string: '1234'}} expr: "TestAllTypes{single_any: google.protobuf.Any{type_url: 'type.googleapis.com/cel.expr.conformance.proto2.TestAllTypes', value: b'\\020\\256\\366\\377\\377\\377\\377\\377\\377\\377\\001r\\0041234'}} ==" " TestAllTypes{single_any: google.protobuf.Any{type_url: 'type.googleapis.com/cel.expr.conformance.proto2.TestAllTypes', value: b'r\\0041234\\020\\256\\366\\377\\377\\377\\377\\377\\377\\377\\001'}}" value { bool_value: true } } test { name: "eq_proto2_any_unpack_not_equal" description: "Any values should be unpacked and compared." container: "cel.expr.conformance.proto2" # Two messages with any fields that are not equal # TestAllTypes{single_any: [TestAllTypes]{single_int64: 1234, single_string: '1234'}} # TestAllTypes{single_any: [TestAllTypes]{single_double: -1234.0, single_string: '1234'}} expr: "TestAllTypes{single_any: google.protobuf.Any{type_url: 'type.googleapis.com/cel.expr.conformance.proto2.TestAllTypes', value: b'a\\000\\000\\000\\000\\000H\\223\\300r\\0041234'}} ==" " TestAllTypes{single_any: google.protobuf.Any{type_url: 'type.googleapis.com/cel.expr.conformance.proto2.TestAllTypes', value: b'r\\0041234\\020\\256\\366\\377\\377\\377\\377\\377\\377\\377\\001'}}" value { bool_value: false } } test { name: "eq_proto2_any_unpack_bytewise_fallback_not_equal" description: "If an any field is missing its type_url, the comparison should fallback to a bytewise comparison of the serialized proto." container: "cel.expr.conformance.proto2" # The missing type info any is doubly nested to skip create message validations. expr: "TestAllTypes{single_any: google.protobuf.Any{type_url: 'type.googleapis.com/cel.expr.conformance.proto2.TestAllTypes', value: b'\\242\\006\\023\\022\\021\\020\\256\\366\\377\\377\\377\\377\\377\\377\\377\\001r\\0041234'}} ==" " TestAllTypes{single_any: google.protobuf.Any{type_url: 'type.googleapis.com/cel.expr.conformance.proto2.TestAllTypes', value: b'\\242\\006\\023\\022\\021r\\0041234\\020\\256\\366\\377\\377\\377\\377\\377\\377\\377\\001'}}" value { bool_value: false } } test { name: "eq_proto2_any_unpack_bytewise_fallback_equal" description: "If an any field is missing its type_url, the comparison should fallback to a bytewise comparison of the serialized proto." container: "cel.expr.conformance.proto2" # The missing type info any is doubly nested to skip create message validations. expr: "TestAllTypes{single_any: google.protobuf.Any{type_url: 'type.googleapis.com/cel.expr.conformance.proto2.TestAllTypes', value: b'\\242\\006\\023\\022\\021\\020\\256\\366\\377\\377\\377\\377\\377\\377\\377\\001r\\0041234'}} ==" " TestAllTypes{single_any: google.protobuf.Any{type_url: 'type.googleapis.com/cel.expr.conformance.proto2.TestAllTypes', value: b'\\242\\006\\023\\022\\021\\020\\256\\366\\377\\377\\377\\377\\377\\377\\377\\001r\\0041234'}}" value { bool_value: true } } test { name: "eq_proto3_any_unpack_equal" description: "Any values should be unpacked and compared." container: "cel.expr.conformance.proto3" # Two equal messages with any fields serialized differently (but both are valid). expr: "TestAllTypes{single_any: google.protobuf.Any{type_url: 'type.googleapis.com/cel.expr.conformance.proto2.TestAllTypes', value: b'\\020\\256\\366\\377\\377\\377\\377\\377\\377\\377\\001r\\0041234'}} ==" " TestAllTypes{single_any: google.protobuf.Any{type_url: 'type.googleapis.com/cel.expr.conformance.proto2.TestAllTypes', value: b'r\\0041234\\020\\256\\366\\377\\377\\377\\377\\377\\377\\377\\001'}}" value { bool_value: true } } test { name: "eq_proto3_any_unpack_not_equal" description: "Any values should be unpacked and compared." container: "cel.expr.conformance.proto3" # Two messages with any fields that are not equal # TestAllTypes{single_any: [TestAllTypes]{single_int64: 1234, single_string: '1234'}} # TestAllTypes{single_any: [TestAllTypes]{single_double: -1234.0, single_string: '1234'}} expr: "TestAllTypes{single_any: google.protobuf.Any{type_url: 'type.googleapis.com/cel.expr.conformance.proto2.TestAllTypes', value: b'a\\000\\000\\000\\000\\000H\\223\\300r\\0041234'}} ==" " TestAllTypes{single_any: google.protobuf.Any{type_url: 'type.googleapis.com/cel.expr.conformance.proto2.TestAllTypes', value: b'r\\0041234\\020\\256\\366\\377\\377\\377\\377\\377\\377\\377\\001'}}" value { bool_value: false } } test { name: "eq_proto3_any_unpack_bytewise_fallback_not_equal" description: "If an any field is missing its type_url, the comparison should fallback to a bytewise comparison of the serialized proto." container: "cel.expr.conformance.proto3" # The missing type info any is doubly nested to skip create message validations. expr: "TestAllTypes{single_any: google.protobuf.Any{type_url: 'type.googleapis.com/cel.expr.conformance.proto2.TestAllTypes', value: b'\\242\\006\\023\\022\\021\\020\\256\\366\\377\\377\\377\\377\\377\\377\\377\\001r\\0041234'}} ==" " TestAllTypes{single_any: google.protobuf.Any{type_url: 'type.googleapis.com/cel.expr.conformance.proto2.TestAllTypes', value: b'\\242\\006\\023\\022\\021r\\0041234\\020\\256\\366\\377\\377\\377\\377\\377\\377\\377\\001'}}" value { bool_value: false } } test { name: "eq_proto3_any_unpack_bytewise_fallback_equal" description: "If an any field is missing its type_url, the comparison should fallback to a bytewise comparison of the serialized proto." container: "cel.expr.conformance.proto3" # The missing type info any is doubly nested to skip create message validations. expr: "TestAllTypes{single_any: google.protobuf.Any{type_url: 'type.googleapis.com/cel.expr.conformance.proto2.TestAllTypes', value: b'\\242\\006\\023\\022\\021\\020\\256\\366\\377\\377\\377\\377\\377\\377\\377\\001r\\0041234'}} ==" " TestAllTypes{single_any: google.protobuf.Any{type_url: 'type.googleapis.com/cel.expr.conformance.proto2.TestAllTypes', value: b'\\242\\006\\023\\022\\021\\020\\256\\366\\377\\377\\377\\377\\377\\377\\377\\001r\\0041234'}}" value { bool_value: true } } } section { name: "ne_literal" description: "Literals comparison on _!=_" test { name: "ne_int" expr: "24 != 42" value: { bool_value: true } } test { name: "not_ne_int" expr: "1 != 1" value: { bool_value: false } } test { name: "ne_int_double" expr: "dyn(24) != 24.1" value: { bool_value: true } } test { name: "not_ne_int_double" expr: "dyn(1) != 1.0" value: { bool_value: false } } test { name: "ne_int_uint" expr: "dyn(24) != 42u" value: { bool_value: true } } test { name: "not_ne_int_uint" expr: "dyn(1) != 1u" value: { bool_value: false } } test { name: "ne_uint" expr: "1u != 2u" value: { bool_value: true } } test { name: "not_ne_uint" expr: "99u != 99u" value: { bool_value: false } } test { name: "ne_uint_double" expr: "dyn(1u) != 2.0" value: { bool_value: true } } test { name: "not_ne_uint_double" expr: "dyn(99u) != 99.0" value: { bool_value: false } } test { name: "ne_double" expr: "9.0e+3 != 9001.0" value: { bool_value: true } } test { name: "not_ne_double_nan" expr: "0.0/0.0 != 0.0/0.0" value: { bool_value: true } } test { name: "not_ne_int_double_nan" expr: "dyn(1) != 0.0/0.0" value: { bool_value: true } } test { name: "not_ne_uint_double_nan" expr: "dyn(1u) != 0.0/0.0" value: { bool_value: true } } test { name: "not_ne_double" expr: "1.0 != 1e+0" value: { bool_value: false } } test { name: "ne_double_int" expr: "dyn(9000) != 9001.0" value: { bool_value: true } } test { name: "not_ne_double_int" expr: "dyn(1) != 1e+0" value: { bool_value: false } } test { name: "ne_double_uint" expr: "dyn(9000u) != 9001.0" value: { bool_value: true } } test { name: "not_ne_double_uint" expr: "dyn(1u) != 1e+0" value: { bool_value: false } } test { name: "ne_double_nan" expr: "0.0/0.0 != 0.0/0.0" value: { bool_value: true } } test { name: "ne_string" expr: "'abc' != ''" value: { bool_value: true } } test { name: "not_ne_string" expr: "'abc' != 'abc'" value: { bool_value: false } } test { name: "ne_string_unicode" expr: "'résumé' != 'resume'" value: { bool_value: true } } test { name: "not_ne_string_unicode" expr: "'ίδιο' != 'ίδιο'" value: { bool_value: false } } test { name: "ne_bytes" expr: "b'\\x00\\xFF' != b'ÿ'" value: { bool_value: true } } test { name: "not_ne_bytes" expr: "b'\\303\\277' != b'ÿ'" value: { bool_value: false } } test { name: "ne_bool" expr: "false != true" value: { bool_value: true } } test { name: "not_ne_bool" expr: "true != true" value: { bool_value: false } } test { name: "not_ne_null" description: "null can only be equal to null, or else it won't match" expr: "null != null" value: { bool_value: false } } test { name: "ne_list_empty" expr: "[] != [1]" value: { bool_value: true } } test { name: "not_ne_list_empty" expr: "[] != []" value: { bool_value: false } } test { name: "ne_list_bool" expr: "[true, false, true] != [true, true, false]" value: { bool_value: true } } test { name: "not_ne_list_bool" expr: "[false, true] != [false, true]" value: { bool_value: false } } test { name: "not_ne_list_of_list" expr: "[[]] != [[]]" value: { bool_value: false } } test { name: "ne_map_by_value" expr: "{'k':'v'} != {'k':'v1'}" value: { bool_value: true } } test { name: "ne_map_by_key" expr: "{'k':true} != {'k1':true}" value: { bool_value: true } } test { name: "not_ne_map_int_to_float" expr: "{1:1.0} != {1:1.0}" value: { bool_value: false } } test { name: "not_ne_map_key_order" expr: "{'a':'b','c':'d'} != {'c':'d','a':'b'}" value: { bool_value: false } } test { name: "ne_mixed_types" expr: "2u != 2" disable_check: true value: { bool_value: false } } test { name: "ne_proto2" container: "cel.expr.conformance.proto2" expr: "TestAllTypes{single_int64: 1234, single_string: '1234'} != TestAllTypes{single_int64: 1234, single_string: '1234'}" value { bool_value: false } } test { name: "ne_proto3" container: "cel.expr.conformance.proto3" expr: "TestAllTypes{single_int64: 1234, single_string: '1234'} != TestAllTypes{single_int64: 1234, single_string: '1234'}" value { bool_value: false } } test { name: "ne_proto2_missing_fields_neq" container: "cel.expr.conformance.proto2" expr: "TestAllTypes{single_int64: 1234} != TestAllTypes{single_string: '1234'}" value { bool_value: true } } test { name: "ne_proto3_missing_fields_neq" container: "cel.expr.conformance.proto3" expr: "TestAllTypes{single_int64: 1234} != TestAllTypes{single_string: '1234'}" value { bool_value: true } } test { name: "ne_proto_nan_not_equal" container: "cel.expr.conformance.proto2" description: "For proto equality, NaN field values are not considered equal." expr: "TestAllTypes{single_double: double('NaN')} != TestAllTypes{single_double: double('NaN')}" value { bool_value: true } } test { name: "ne_proto_different_types" container: "cel.expr.conformance.proto2" description: "At runtime, comparing differently typed messages is false." expr: "dyn(TestAllTypes{}) != dyn(NestedTestAllTypes{})" value: { bool_value: true } } test { name: "ne_proto2_any_unpack" description: "Any values should be unpacked and compared." container: "cel.expr.conformance.proto2" # Two equal messages with any fields serialized differently (but both are valid). # TestAllTypes{single_any: [TestAllTypes]{single_int64: 1234, single_string: '1234'}} expr: "TestAllTypes{single_any: google.protobuf.Any{type_url: 'type.googleapis.com/cel.expr.conformance.proto2.TestAllTypes', value: b'\\020\\256\\366\\377\\377\\377\\377\\377\\377\\377\\001r\\0041234'}} !=" " TestAllTypes{single_any: google.protobuf.Any{type_url: 'type.googleapis.com/cel.expr.conformance.proto2.TestAllTypes', value: b'r\\0041234\\020\\256\\366\\377\\377\\377\\377\\377\\377\\377\\001'}}" value { bool_value: false } } test { name: "ne_proto2_any_unpack_bytewise_fallback" description: "If an any field is missing its type_url, the comparison should fallback to a bytewise comparison of the serialized proto." container: "cel.expr.conformance.proto3" # The missing type info any is doubly nested to skip create # message validations. expr: "TestAllTypes{single_any: google.protobuf.Any{type_url: 'type.googleapis.com/cel.expr.conformance.proto2.TestAllTypes', value: b'\\242\\006\\023\\022\\021\\020\\256\\366\\377\\377\\377\\377\\377\\377\\377\\001r\\0041234'}} !=" " TestAllTypes{single_any: google.protobuf.Any{type_url: 'type.googleapis.com/cel.expr.conformance.proto2.TestAllTypes', value: b'\\242\\006\\023\\022\\021r\\0041234\\020\\256\\366\\377\\377\\377\\377\\377\\377\\377\\001'}}" value { bool_value: true } } test { name: "ne_proto3_any_unpack" description: "Any values should be unpacked and compared." container: "cel.expr.conformance.proto2" # Two equal messages with any fields serialized differently (but both are valid). expr: "TestAllTypes{single_any: google.protobuf.Any{type_url: 'type.googleapis.com/cel.expr.conformance.proto2.TestAllTypes', value: b'\\020\\256\\366\\377\\377\\377\\377\\377\\377\\377\\001r\\0041234'}} !=" " TestAllTypes{single_any: google.protobuf.Any{type_url: 'type.googleapis.com/cel.expr.conformance.proto2.TestAllTypes', value: b'r\\0041234\\020\\256\\366\\377\\377\\377\\377\\377\\377\\377\\001'}}" value { bool_value: false } } test { name: "ne_proto3_any_unpack_bytewise_fallback" description: "If an any field is missing its type_url, the comparison should fallback to a bytewise comparison of the serialized proto." container: "cel.expr.conformance.proto3" # The missing type info any is doubly nested to skip create message validations. expr: "TestAllTypes{single_any: google.protobuf.Any{type_url: 'type.googleapis.com/cel.expr.conformance.proto2.TestAllTypes', value: b'\\242\\006\\023\\022\\021\\020\\256\\366\\377\\377\\377\\377\\377\\377\\377\\001r\\0041234'}} !=" " TestAllTypes{single_any: google.protobuf.Any{type_url: 'type.googleapis.com/cel.expr.conformance.proto2.TestAllTypes', value: b'\\242\\006\\023\\022\\021r\\0041234\\020\\256\\366\\377\\377\\377\\377\\377\\377\\377\\001'}}" value { bool_value: true } } } section { name: "lt_literal" description: "Literals comparison on _<_. (a < b) == (b > a) == !(a >= b) == !(b <= a)" test { name: "lt_int" expr: "-1 < 0" value: { bool_value: true } } test { name: "not_lt_int" expr: "0 < 0" value: { bool_value: false } } test { name: "lt_uint" expr: "0u < 1u" value: { bool_value: true } } test { name: "not_lt_uint" expr: "2u < 2u" value: { bool_value: false } } test { name: "lt_double" expr: "1.0 < 1.0000001" value: { bool_value: true } } test { name: "not_lt_double" description: "Following IEEE 754, negative zero compares equal to zero" expr: "-0.0 < 0.0" value: { bool_value: false } } test { name: "lt_string" expr: "'a' < 'b'" value: { bool_value: true } } test { name: "lt_string_empty_to_nonempty" expr: "'' < 'a'" value: { bool_value: true } } test { name: "lt_string_case" expr: "'Abc' < 'aBC'" value: { bool_value: true } } test { name: "lt_string_length" expr: "'abc' < 'abcd'" value: { bool_value: true } } test { name: "lt_string_diacritical_mark_sensitive" description: "Verifies that the we're not using a string comparison function that strips diacritical marks (á)" expr: "'a' < '\\u00E1'" value: { bool_value: true } } test { name: "not_lt_string_empty" expr: "'' < ''" value: { bool_value: false } } test { name: "not_lt_string_same" expr: "'abc' < 'abc'" value: { bool_value: false } } test { name: "not_lt_string_case_length" expr: "'a' < 'AB'" value: { bool_value: false } } test { name: "unicode_order_lexical" description: "Compare the actual code points of the string, instead of decomposing ế into 'e' plus accent modifiers." expr: "'f' < '\\u1EBF'" value: { bool_value: true } } test { name: "lt_bytes" expr: "b'a' < b'b'" value: { bool_value: true } } test { name: "not_lt_bytes_same" expr: "b'abc' < b'abc'" value: { bool_value: false } } test { name: "not_lt_bytes_width" expr: "b'á' < b'b'" value: { bool_value: false } } test { name: "lt_bool_false_first" expr: "false < true" value: { bool_value: true } } test { name: "not_lt_bool_same" expr: "true < true" value: { bool_value: false } } test { name: "not_lt_bool_true_first" expr: "true < false" value: { bool_value: false } } test { name: "lt_list_unsupported" expr: "[0] < [1]" disable_check: true eval_error: { errors: { message: "no such overload" } } } test { name: "lt_map_unsupported" expr: "{0:'a'} < {1:'b'}" disable_check: true eval_error: { errors: { message: "no such overload" } } } test { name: "lt_null_unsupported" description: "Ensure _<_ doesn't have a binding for null" expr: "null < null" disable_check: true eval_error: { errors: { message: "no such overload" } } } test { name: "lt_mixed_types_error" expr: "'foo' < 1024" disable_check: true eval_error: { errors: { message: "no such overload" } } } test { name: "lt_dyn_int_uint" expr: "dyn(1) < 2u" value: { bool_value: true } } test { name: "lt_dyn_int_double" expr: "dyn(1) < 2.0" value: { bool_value: true } } test { name: "lt_dyn_uint_int" expr: "dyn(1u) < 2" value: { bool_value: true } } test { name: "lt_dyn_uint_double" expr: "dyn(1u) < 2.0" value: { bool_value: true } } test { name: "lt_dyn_double_int" expr: "dyn(1.0) < 2" value: { bool_value: true } } test { name: "lt_dyn_double_uint" expr: "dyn(1.0) < 2u" value: { bool_value: true } } test { name: "not_lt_dyn_int_uint" expr: "dyn(1) < 1u" value: { bool_value: false } } test { name: "not_lt_dyn_int_double" expr: "dyn(1) < 1.0" value: { bool_value: false } } test { name: "not_lt_dyn_uint_int" expr: "dyn(1u) < 1" value: { bool_value: false } } test { name: "not_lt_dyn_uint_double" expr: "dyn(1u) < 1.0" value: { bool_value: false } } test { name: "not_lt_dyn_double_int" expr: "dyn(1.0) < 1" value: { bool_value: false } } test { name: "not_lt_dyn_double_uint" expr: "dyn(1.0) < 1u" value: { bool_value: false } } test { name: "lt_dyn_int_big_uint" expr: "dyn(1) < 9223372036854775808u" value: { bool_value: true } } test { name: "lt_dyn_small_int_uint" expr: "dyn(-1) < 0u" value: { bool_value: true } } test { name: "not_lt_dyn_int_big_lossy_double" expr: "dyn(9223372036854775807) < 9223372036854775808.0" value: { bool_value: false } } test { name: "lt_dyn_int_big_lossy_double" expr: "dyn(9223372036854775807) < 9223372036854777857.0" value: { bool_value: true } } test { name: "not_lt_dyn_int_small_double" expr: "dyn(9223372036854775807) < -9223372036854777857.0" value: { bool_value: false } } test { name: "not_lt_dyn_int_small_lossy_double" expr: "dyn(-9223372036854775808) < -9223372036854775809.0" value: { bool_value: false } } test { name: "not_lt_dyn_uint_small_int" expr: "dyn(1u) < -9223372036854775808" value: { bool_value: false } } test { name: "not_lt_dyn_big_uint_int" expr: "dyn(9223372036854775808u) < 1" value: { bool_value: false } } test { name: "not_lt_dyn_uint_small_double" expr: "dyn(18446744073709551615u) < -1.0" value: { bool_value: false } } test { name: "lt_dyn_uint_big_double" expr: "dyn(18446744073709551615u) < 18446744073709590000.0" value: { bool_value: true } } test { name: "not_lt_dyn_big_double_uint" expr: "dyn(18446744073709553665.0) < 18446744073709551615u" value: { bool_value: false } } test { name: "not_lt_dyn_big_double_int" expr: "dyn(9223372036854775808.0) < 9223372036854775807" value: { bool_value: false } } test { name: "not_lt_dyn_small_double_int" expr: "dyn(-9223372036854775809.0) < -9223372036854775808" value: { bool_value: false } } } section { name: "gt_literal" description: "Literals comparison on _>_" test { name: "gt_int" expr: "42 > -42" value: { bool_value: true } } test { name: "not_gt_int" expr: "0 > 0" value: { bool_value: false } } test { name: "gt_uint" expr: "48u > 46u" value: { bool_value: true } } test { name: "not_gt_uint" expr: "0u > 999u" value: { bool_value: false } } test { name: "gt_double" expr: "1e+1 > 1e+0" value: { bool_value: true } } test { name: "not_gt_double" expr: ".99 > 9.9e-1" value: { bool_value: false } } test { name: "gt_string_case" expr: "'abc' > 'aBc'" value: { bool_value: true } } test { name: "gt_string_to_empty" expr: "'A' > ''" value: { bool_value: true } } test { name: "not_gt_string_empty_to_empty" expr: "'' > ''" value: { bool_value: false } } test { name: "gt_string_unicode" expr: "'α' > 'omega'" value: { bool_value: true } } test { name: "gt_bytes_one" expr: "b'\x01' > b'\x00'" value: { bool_value: true } } test { name: "gt_bytes_one_to_empty" expr: "b'\x00' > b''" value: { bool_value: true } } test { name: "not_gt_bytes_sorting" expr: "b'\x00\x01' > b'\x01'" value: { bool_value: false } } test { name: "gt_bool_true_false" expr: "true > false" value: { bool_value: true } } test { name: "not_gt_bool_false_true" expr: "false > true" value: { bool_value: false } } test { name: "not_gt_bool_same" expr: "true > true" value: { bool_value: false } } test { name: "gt_null_unsupported" expr: "null > null" disable_check: true eval_error: { errors: { message: "no such overload" } } } test { name: "gt_list_unsupported" expr: "[1] > [0]" disable_check: true eval_error: { errors: { message: "no such overload" } } } test { name: "gt_map_unsupported" expr: "{1:'b'} > {0:'a'}" disable_check: true eval_error: { errors: { message: "no such overload" } } } test { name: "gt_mixed_types_error" expr: "'foo' > 1024" disable_check: true eval_error: { errors: { message: "no such overload" } } } test { name: "gt_dyn_int_uint" expr: "dyn(2) > 1u" value: { bool_value: true } } test { name: "gt_dyn_int_double" expr: "dyn(2) > 1.0" value: { bool_value: true } } test { name: "gt_dyn_uint_int" expr: "dyn(2u) > 1" value: { bool_value: true } } test { name: "gt_dyn_uint_double" expr: "dyn(2u) > 1.0" value: { bool_value: true } } test { name: "gt_dyn_double_int" expr: "dyn(2.0) > 1" value: { bool_value: true } } test { name: "gt_dyn_double_uint" expr: "dyn(2.0) > 1u" value: { bool_value: true } } test { name: "not_gt_dyn_int_uint" expr: "dyn(1) > 1u" value: { bool_value: false } } test { name: "not_gt_dyn_int_double" expr: "dyn(1) > 1.0" value: { bool_value: false } } test { name: "not_gt_dyn_uint_int" expr: "dyn(1u) > 1" value: { bool_value: false } } test { name: "not_gt_dyn_uint_double" expr: "dyn(1u) > 1.0" value: { bool_value: false } } test { name: "not_gt_dyn_double_int" expr: "dyn(1.0) > 1" value: { bool_value: false } } test { name: "not_gt_dyn_double_uint" expr: "dyn(1.0) > 1u" value: { bool_value: false } } test { name: "not_gt_dyn_int_big_uint" expr: "dyn(1) > 9223372036854775808u" value: { bool_value: false } } test { name: "not_gt_dyn_small_int_uint" expr: "dyn(-1) > 0u" value: { bool_value: false } } test { name: "not_gt_dyn_int_big_double" expr: "dyn(9223372036854775807) > 9223372036854775808.0" value: { bool_value: false } } test { name: "not_gt_dyn_int_small_lossy_double" description: "The conversion of the int to double is lossy and the numbers end up being equal" expr: "dyn(-9223372036854775808) > -9223372036854775809.0" value: { bool_value: false } } test { name: "gt_dyn_int_small_lossy_double_greater" expr: "dyn(-9223372036854775808) > -9223372036854777857.0" value: { bool_value: true } } test { name: "gt_dyn_uint_small_int" expr: "dyn(1u) > -1" value: { bool_value: true } } test { name: "gt_dyn_big_uint_int" expr: "dyn(9223372036854775808u) > 1" value: { bool_value: true } } test { name: "gt_dyn_uint_small_double" expr: "dyn(9223372036854775807u) > -1.0" value: { bool_value: true } } test { name: "not_gt_dyn_uint_big_double" expr: "dyn(18446744073709551615u) > 18446744073709590000.0" value: { bool_value: false } } test { name: "gt_dyn_big_double_uint" expr: "dyn(18446744073709553665.0) > 18446744073709551615u" value: { bool_value: true } } test { name: "not_gt_dyn_big_double_int" expr: "dyn(9223372036854775808.0) > 9223372036854775807" value: { bool_value: false } } test { name: "not_gt_dyn_small_double_int" expr: "dyn(-9223372036854775809.0) > -9223372036854775808" value: { bool_value: false } } } section { name: "lte_literal" description: "Literals comparison on _<=_" test { name: "lte_int_lt" expr: "0 <= 1" value: { bool_value: true } } test { name: "lte_int_eq" expr: "1 <= 1" value: { bool_value: true } } test { name: "not_lte_int_gt" expr: "1 <= -1" value: { bool_value: false } } test { name: "lte_uint_lt" expr: "0u <= 1u" value: { bool_value: true } } test { name: "lte_uint_eq" expr: "1u <= 1u" value: { bool_value: true } } test { name: "not_lte_uint_gt" expr: "1u <= 0u" value: { bool_value: false } } test { name: "lte_double_lt" expr: "0.0 <= 0.1e-31" value: { bool_value: true } } test { name: "lte_double_eq" expr: "0.0 <= 0e-1" value: { bool_value: true } } test { name: "not_lte_double_gt" expr: "1.0 <= 0.99" value: { bool_value: false } } test { name: "lte_string_empty" expr: "'' <= ''" value: { bool_value: true } } test { name: "lte_string_from_empty" expr: "'' <= 'a'" value: { bool_value: true } } test { name: "not_lte_string_to_empty" expr: "'a' <= ''" value: { bool_value: false } } test { name: "lte_string_lexicographical" expr: "'aBc' <= 'abc'" value: { bool_value: true } } test { name: "lte_string_unicode_eq" expr: "'α' <= 'α'" value: { bool_value: true } } test { name: "lte_string_unicode_lt" expr: "'a' <= 'α'" value: { bool_value: true } } test { name: "not_lte_string_unicode" expr: "'α' <= 'a'" value: { bool_value: false } } test { name: "lte_bytes_empty" expr: "b'' <= b'\x00'" value: { bool_value: true } } test { name: "not_lte_bytes_length" expr: "b'\x01\x00' <= b'\x01'" value: { bool_value: false } } test { name: "lte_bool_false_true" expr: "false <= true" value: { bool_value: true } } test { name: "lte_bool_false_false" expr: "false <= false" value: { bool_value: true } } test { name: "lte_bool_true_false" expr: "true <= false" value: { bool_value: false } } test { name: "lte_null_unsupported" expr: "null <= null" disable_check: true eval_error: { errors: { message: "no such overload" } } } test { name: "lte_list_unsupported" expr: "[0] <= [0]" disable_check: true eval_error: { errors: { message: "no such overload" } } } test { name: "lte_map_unsupported" expr: "{0:'a'} <= {1:'b'}" disable_check: true eval_error: { errors: { message: "no such overload" } } } test { name: "lte_mixed_types_error" expr: "'foo' <= 1024" disable_check: true eval_error: { errors: { message: "no such overload" } } } test { name: "lte_dyn_int_uint" expr: "dyn(1) <= 2u" value: { bool_value: true } } test { name: "lte_dyn_int_double" expr: "dyn(1) <= 2.0" value: { bool_value: true } } test { name: "lte_dyn_uint_int" expr: "dyn(1u) <= 2" value: { bool_value: true } } test { name: "lte_dyn_uint_double" expr: "dyn(1u) <= 2.0" value: { bool_value: true } } test { name: "lte_dyn_double_int" expr: "dyn(1.0) <= 2" value: { bool_value: true } } test { name: "lte_dyn_double_uint" expr: "dyn(1.0) <= 2u" value: { bool_value: true } } test { name: "not_lte_dyn_int_uint" expr: "dyn(2) <= 1u" value: { bool_value: false } } test { name: "not_lte_dyn_int_double" expr: "dyn(2) <= 1.0" value: { bool_value: false } } test { name: "not_lte_dyn_uint_int" expr: "dyn(2u) <= 1" value: { bool_value: false } } test { name: "not_lte_dyn_uint_double" expr: "dyn(2u) <= 1.0" value: { bool_value: false } } test { name: "not_lte_dyn_double_int" expr: "dyn(2.0) <= 1" value: { bool_value: false } } test { name: "not_lte_dyn_double_uint" expr: "dyn(2.0) <= 1u" value: { bool_value: false } } test { name: "lte_dyn_int_big_uint" expr: "dyn(1) <= 9223372036854775808u" value: { bool_value: true } } test { name: "lte_dyn_small_int_uint" expr: "dyn(-1) <= 0u" value: { bool_value: true } } test { name: "lte_dyn_int_big_double" expr: "dyn(9223372036854775807) <= 9223372036854775808.0" value: { bool_value: true } } test { name: "lte_dyn_int_small_lossy_double" description: "The conversion of the int to double is lossy and the numbers end up being equal" expr: "dyn(-9223372036854775808) <= -9223372036854775809.0" value: { bool_value: true } } test { name: "not_lte_dyn_int_small_lossy_double_less" expr: "dyn(-9223372036854775808) <= -9223372036854777857.0" value: { bool_value: false } } test { name: "not_lte_dyn_uint_small_int" expr: "dyn(1u) <= -9223372036854775808" value: { bool_value: false } } test { name: "not_lte_dyn_big_uint_int" expr: "dyn(9223372036854775808u) <= 1" value: { bool_value: false } } test { name: "not_lte_dyn_uint_small_double" expr: "dyn(18446744073709551615u) <= -1.0" value: { bool_value: false } } test { name: "lte_dyn_uint_big_double" expr: "dyn(18446744073709551615u) <= 18446744073709590000.0" value: { bool_value: true } } test { name: "not_lte_dyn_big_double_uint" expr: "dyn(18446744073709553665.0) <= 18446744073709551615u" value: { bool_value: false } } test { name: "lte_dyn_big_double_int" expr: "dyn(9223372036854775808.0) <= 9223372036854775807" value: { bool_value: true } } test { name: "lte_dyn_small_double_int" expr: "dyn(-9223372036854775809.0) <= -9223372036854775808" value: { bool_value: true } } } section { name: "gte_literal" description: "Literals comparison on _>=_" test { name: "gte_int_gt" expr: "0 >= -1" value: { bool_value: true } } test { name: "gte_int_eq" expr: "999 >= 999" value: { bool_value: true } } test { name: "not_gte_int_lt" expr: "999 >= 1000" value: { bool_value: false } } test { name: "gte_uint_gt" expr: "1u >= 0u" value: { bool_value: true } } test { name: "gte_uint_eq" expr: "0u >= 0u" value: { bool_value: true } } test { name: "not_gte_uint_lt" expr: "1u >= 10u" value: { bool_value: false } } test { name: "gte_double_gt" expr: "1e+1 >= 1e+0" value: { bool_value: true } } test { name: "gte_double_eq" expr: "9.80665 >= 9.80665e+0" value: { bool_value: true } } test { name: "not_gte_double_lt" expr: "0.9999 >= 1.0" value: { bool_value: false } } test { name: "gte_string_empty" expr: "'' >= ''" value: { bool_value: true } } test { name: "gte_string_to_empty" expr: "'a' >= ''" value: { bool_value: true } } test { name: "gte_string_empty_to_nonempty" expr: "'' >= 'a'" value: { bool_value: false } } test { name: "gte_string_length" expr: "'abcd' >= 'abc'" value: { bool_value: true } } test { name: "not_gte_string_lexicographical" expr: "'abc' >= 'abd'" value: { bool_value: false } } test { name: "gte_string_unicode_eq" expr: "'τ' >= 'τ'" value: { bool_value: true } } test { name: "gte_string_unicode_gt" expr: "'τ' >= 't'" value: { bool_value: true } } test { name: "not_get_string_unicode" expr: "'t' >= 'τ'" value: { bool_value: false } } test { name: "gte_bytes_to_empty" expr: "b'\x00' >= b''" value: { bool_value: true } } test { name: "not_gte_bytes_empty_to_nonempty" expr: "b'' >= b'\x00'" value: { bool_value: false } } test { name: "gte_bytes_samelength" expr: "b'\x00\x01' >= b'\x01\x00'" value: { bool_value: false } } test { name: "gte_bool_gt" expr: "true >= false" value: { bool_value: true } } test { name: "gte_bool_eq" expr: "true >= true" value: { bool_value: true } } test { name: "not_gte_bool_lt" expr: "false >= true" value: { bool_value: false } } test { name: "gte_null_unsupported" expr: "null >= null" disable_check: true eval_error: { errors: { message: "no such overload" } } } test { name: "gte_list_unsupported" expr: "['y'] >= ['x']" disable_check: true eval_error: { errors: { message: "no such overload" } } } test { name: "gte_map_unsupported" expr: "{1:'b'} >= {0:'a'}" disable_check: true eval_error: { errors: { message: "no such overload" } } } test { name: "gte_mixed_types_error" expr: "'foo' >= 1.0" disable_check: true eval_error: { errors: { message: "no such overload" } } } test { name: "gte_dyn_int_uint" expr: "dyn(2) >= 1u" value: { bool_value: true } } test { name: "gte_dyn_int_double" expr: "dyn(2) >= 1.0" value: { bool_value: true } } test { name: "gte_dyn_uint_int" expr: "dyn(2u) >= 1" value: { bool_value: true } } test { name: "gte_dyn_uint_double" expr: "dyn(2u) >= 1.0" value: { bool_value: true } } test { name: "gte_dyn_double_int" expr: "dyn(2.0) >= 1" value: { bool_value: true } } test { name: "gte_dyn_double_uint" expr: "dyn(2.0) >= 1u" value: { bool_value: true } } test { name: "not_gte_dyn_int_uint" expr: "dyn(0) >= 1u" value: { bool_value: false } } test { name: "not_gte_dyn_int_double" expr: "dyn(0) >= 1.0" value: { bool_value: false } } test { name: "not_gte_dyn_uint_int" expr: "dyn(0u) >= 1" value: { bool_value: false } } test { name: "not_gte_dyn_uint_double" expr: "dyn(0u) >= 1.0" value: { bool_value: false } } test { name: "not_gte_dyn_double_int" expr: "dyn(0.0) >= 1" value: { bool_value: false } } test { name: "not_gte_dyn_double_uint" expr: "dyn(0.0) >= 1u" value: { bool_value: false } } test { name: "not_gte_dyn_int_big_uint" expr: "dyn(1) >= 9223372036854775808u" value: { bool_value: false } } test { name: "not_gte_dyn_small_int_uint" expr: "dyn(-1) >= 0u" value: { bool_value: false } } test { name: "gte_dyn_int_big_lossy_double" expr: "dyn(9223372036854775807) >= 9223372036854775808.0" value: { bool_value: true } } test { name: "not_gte_dyn_int_big_double" expr: "dyn(9223372036854775807) >= 9223372036854777857.0" value: { bool_value: false } } test { name: "gte_dyn_int_small_lossy_double_equal" description: "The conversion of the int to double is lossy and the numbers end up being equal" expr: "dyn(-9223372036854775808) >= -9223372036854775809.0" value: { bool_value: true } } test { name: "gte_dyn_int_small_lossy_double_greater" expr: "dyn(-9223372036854775808) >= -9223372036854777857.0" value: { bool_value: true } } test { name: "gte_dyn_uint_small_int" expr: "dyn(1u) >= -1" value: { bool_value: true } } test { name: "gte_dyn_big_uint_int" expr: "dyn(9223372036854775808u) >= 1" value: { bool_value: true } } test { name: "gte_dyn_uint_small_double" expr: "dyn(9223372036854775807u) >= -1.0" value: { bool_value: true } } test { name: "not_gte_dyn_uint_big_double" expr: "dyn(18446744073709551615u) >= 18446744073709553665.0" value: { bool_value: false } } test { name: "gte_dyn_big_double_uint" expr: "dyn(18446744073709553665.0) >= 18446744073709551615u" value: { bool_value: true } } test { name: "gte_dyn_big_double_int" expr: "dyn(9223372036854775808.0) >= 9223372036854775807" value: { bool_value: true } } test { name: "gte_dyn_small_double_int" expr: "dyn(-9223372036854775809.0) >= -9223372036854775808" value: { bool_value: true } } } section { name: "in_list_literal" description: "Set membership tests using list literals and the 'in' operator" test { name: "elem_not_in_empty_list" expr: "'empty' in []" value { bool_value: false } } test { name: "elem_in_list" expr: "'elem' in ['elem', 'elemA', 'elemB']" value { bool_value: true } } test { name: "elem_not_in_list" expr: "'not' in ['elem1', 'elem2', 'elem3']" value { bool_value: false } } test { name: "elem_in_mixed_type_list" description: "Set membership tests should succeed if the 'elem' exists in a mixed element type list." expr: "'elem' in [1, 'elem', 2]" value { bool_value: true } } test { name: "elem_in_mixed_type_list_cross_type" description: "Set membership tests should return false due to the introduction of heterogeneous-equality. Set membership via 'in' is equivalent to the macro exists() behavior." expr: "'elem' in [1u, 'str', 2, b'bytes']" value: { bool_value: false } } } section { name: "in_map_literal" description: "Set membership tests using map literals and the 'in' operator" test { name: "key_not_in_empty_map" expr: "'empty' in {}" value { bool_value: false } } test { name: "key_in_map" expr: "'key' in {'key':'1', 'other':'2'}" value { bool_value: true } } test { name: "key_not_in_map" expr: "'key' in {'lock':1, 'gate':2}" value { bool_value: false } } test { name: "key_in_mixed_key_type_map" description: "Map keys are of mixed type, but since the key is present the result is true." expr: "'key' in {3:3.0, 'key':2u}" value { bool_value: true } } test { name: "key_in_mixed_key_type_map_cross_type" expr: "'key' in {1u:'str', 2:b'bytes'}" value: { bool_value: false } } } section { name: "bound" description: "Comparing bound variables with literals or other variables" test { name: "bytes_gt_left_false" expr: "x > b'\x00'" value: { bool_value: false } type_env: { name: "x" ident: { type: { primitive: BYTES } } } bindings: { key: "x" value: { value: { bytes_value: "\x00" } } } } test { name: "int_lte_right_true" expr: "123 <= x" value: { bool_value: true } type_env: { name: "x" ident: { type: { primitive: INT64 } } } bindings: { key: "x" value: { value: { int64_value: 124 } } } } test { name: "bool_lt_right_true" expr: "false < x" value: { bool_value: true } type_env: { name: "x" ident: { type: { primitive: BOOL } } } bindings: { key: "x" value: { value: { bool_value: true } } } } test { name: "double_ne_left_false" expr: "x != 9.8" value: { bool_value: false } type_env: { name: "x" ident: { type: { primitive: DOUBLE } } } bindings: { key: "x" value: { value: { double_value: 9.8 } } } } test { name: "map_ne_right_false" expr: "{'a':'b','c':'d'} != x" value: { bool_value: false } type_env: { name: "x" ident: { type: { map_type: { key_type: { primitive: STRING } value_type: { primitive: STRING } } } } } bindings: { key: "x" value: { value: { map_value { entries { key: { string_value: "c" } value: { string_value: "d" } } entries { key: { string_value: "a" } value: { string_value: "b" } } } } } } } test { name: "null_eq_left_true" description: "A comparison _==_ against null only binds if the type is determined to be null or we skip the type checking" expr: "x == null" value: { bool_value: true } type_env: { name: "x" ident: { type: { null: NULL_VALUE } } } bindings: { key: "x" value: { value: { null_value: NULL_VALUE } } } } test { name: "list_eq_right_false" expr: "[1, 2] == x" value: { bool_value: false } type_env: { name: "x" ident: { type: { list_type: { elem_type: { primitive: INT64 } } } } } bindings: { key: "x" value: { value: { list_value { values: { int64_value: 2 } values: { int64_value: 1 } } } } } } test { name: "string_gte_right_true" expr: "'abcd' >= x" value: { bool_value: true } type_env: { name: "x" ident: { type: { primitive: STRING } } } bindings: { key: "x" value: { value: { string_value: "abc" } } } } test { name: "uint_eq_right_false" expr: "999u == x" value: { bool_value: false } type_env: { name: "x" ident: { type: { primitive: UINT64 } } } bindings: { key: "x" value: { value: { uint64_value: 1000 } } } } test { name: "null_lt_right_no_such_overload" description: "There is no _<_ operation for null, even if both operands are null" expr: "null < x" eval_error: { errors: { message: "no such overload" } } disable_check: true bindings: { key: "x" value: { value: { null_value: NULL_VALUE } } } } }