# proto-file: ../../../proto/cel/expr/conformance/test/simple.proto # proto-message: cel.expr.conformance.test.SimpleTestFile name: "conversions" description: "Tests for type conversions." section { name: "bytes" description: "Conversions to bytes." test { name: "string_empty" expr: "bytes('')" value: { bytes_value: "" } } test { name: "string" expr: "bytes('abc')" value: { bytes_value: "abc" } } test { name: "string_unicode" expr: "bytes('ÿ')" value: { bytes_value: "\303\277" } } test { name: "string_unicode_vs_literal" expr: "bytes('\\377') == b'\\377'" value: { bool_value: false } } } section { name: "double" description: "Conversions to double." test { name: "int_zero" expr: "double(0)" value: { double_value: 0.0 } } test { name: "int_pos" expr: "double(1000000000000)" value: { double_value: 1e12 } } test { name: "int_neg" expr: "double(-1000000000000000)" value: { double_value: -1e15 } } test { name: "int_min_exact" description: "Smallest contiguous representable int (-2^53)." expr: "double(-9007199254740992)" value { double_value: -9.007199254740992e15 } } test { name: "int_max_exact" description: "Largest contiguous representable int (2^53)." expr: "double(9007199254740992)" value { double_value: 9.007199254740992e15 } } test { name: "int_range" description: "Largest signed 64-bit. Rounds to nearest double." expr: "double(9223372036854775807)" value: { double_value: 9.223372036854775807e18 } } test { name: "uint_zero" expr: "double(0u)" value: { double_value: 0.0 } } test { name: "uint_pos" expr: "double(123u)" value: { double_value: 123.0 } } test { name: "uint_max_exact" description: "Largest contiguous representable int (2^53)." expr: "double(9007199254740992u)" value { double_value: 9.007199254740992e15 } } test { name: "uint_range" description: "Largest unsigned 64-bit." expr: "double(18446744073709551615u)" value: { double_value: 1.8446744073709551615e19 } } test { name: "string_zero" expr: "double('0')" value: { double_value: 0.0 } } test { name: "string_zero_dec" expr: "double('0.0')" value: { double_value: 0.0 } } test { name: "string_neg_zero" expr: "double('-0.0')" value: { double_value: -0.0 } } test { name: "string_no_dec" expr: "double('123')" value: { double_value: 123.0 } } test { name: "string_pos" expr: "double('123.456')" value: { double_value: 123.456 } } test { name: "string_neg" expr: "double('-987.654')" value: { double_value: -987.654 } } test { name: "string_exp_pos_pos" expr: "double('6.02214e23')" value: { double_value: 6.02214e23 } } test { name: "string_exp_pos_neg" expr: "double('1.38e-23')" value: { double_value: 1.38e-23 } } test { name: "string_exp_neg_pos" expr: "double('-84.32e7')" value: { double_value: -8.432e8 } } test { name: "string_exp_neg_neg" expr: "double('-5.43e-21')" value: { double_value: -5.43e-21 } } } section { name: "dyn" description: "Tests for dyn annotation." test { name: "dyn_heterogeneous_list" description: "No need to disable type checking." expr: "type(dyn([1, 'one']))" value: { type_value: "list" } } } section { name: "int" description: "Conversions to int." test { name: "uint" expr: "int(42u)" value: { int64_value: 42 } } test { name: "uint_zero" expr: "int(0u)" value: { int64_value: 0 } } test { name: "uint_max_exact" expr: "int(9223372036854775807u)" value { int64_value: 9223372036854775807 } } test { name: "uint_range" expr: "int(18446744073709551615u)" eval_error { errors { message: "range error" } } } test { name: "double_round_neg" expr: "int(-123.456)" value: { int64_value: -123 } } test { name: "double_truncate" expr: "int(1.9)" value: { int64_value: 1 } } test { name: "double_truncate_neg" expr: "int(-7.9)" value: { int64_value: -7 } } test { name: "double_half_pos" expr: "int(11.5)" value: { int64_value: 11 } } test { name: "double_half_neg" expr: "int(-3.5)" value: { int64_value: -3 } } test { name: "double_big_exact" description: "Beyond exact range (2^53), but no loss of precision (2^55)." expr: "int(double(36028797018963968))" value { int64_value: 36028797018963968 } } test { name: "double_big_precision" description: "Beyond exact range (2^53), but loses precision (2^55 + 1)." expr: "int(double(36028797018963969))" value { int64_value: 36028797018963968 } } test { name: "double_int_max_range" description: "The double(2^63-1) cast produces a floating point value outside the int range" expr: "int(9223372036854775807.0)" eval_error { errors: { message: "range" } } } test { name: "double_int_min_range" description: "The double(-2^63) cast produces a floating point value outside the int range" expr: "int(-9223372036854775808.0)" eval_error { errors: { message: "range" } } } test { name: "double_range" expr: "int(1e99)" eval_error { errors: { message: "range" } } } test { name: "string" expr: "int('987')" value: { int64_value: 987 } } test { name: "timestamp" expr: "int(timestamp('2004-09-16T23:59:59Z'))" value: { int64_value: 1095379199 } } } section { name: "string" description: "Conversions to string." test { name: "int" expr: "string(123)" value: { string_value: "123" } } test { name: "int_neg" expr: "string(-456)" value: { string_value: "-456" } } test { name: "uint" expr: "string(9876u)" value: { string_value: "9876" } } test { name: "double" expr: "string(123.456)" value: { string_value: "123.456" } } test { name: "double_hard" expr: "string(-4.5e-3)" value: { string_value: "-0.0045" } } test { name: "bytes" expr: "string(b'abc')" value: { string_value: "abc" } } test { name: "bytes_unicode" expr: "string(b'\\303\\277')" value: { string_value: "ÿ" } } test { name: "bytes_invalid" expr: "string(b'\\000\\xff')" eval_error { errors { message: "invalid UTF-8" } } } } section { name: "type" description: "Type reflection tests." test { name: "bool" expr: "type(true)" value: { type_value: "bool" } } test { name: "bool_denotation" expr: "bool" value: { type_value: "bool" } } test { name: "dyn_no_denotation" expr: "dyn" disable_check: true eval_error { errors { message: "unknown variable" } } } test { name: "int" expr: "type(0)" value: { type_value: "int" } } test { name: "int_denotation" expr: "int" value: { type_value: "int" } } test { name: "eq_same" expr: "type(true) == type(false)" value: { bool_value: true } } test { name: "uint" expr: "type(64u)" value: { type_value: "uint" } } test { name: "uint_denotation" expr: "uint" value: { type_value: "uint" } } test { name: "double" expr: "type(3.14)" value: { type_value: "double" } } test { name: "double_denotation" expr: "double" value: { type_value: "double" } } test { name: "null_type" expr: "type(null)" value: { type_value: "null_type" } } test { name: "null_type_denotation" expr: "null_type" value: { type_value: "null_type" } } test { name: "string" expr: "type('foo')" value: { type_value: "string" } } test { name: "string_denotation" expr: "string" value: { type_value: "string" } } test { name: "bytes" expr: "type(b'\\xff')" value: { type_value: "bytes" } } test { name: "bytes_denotation" expr: "bytes" value: { type_value: "bytes" } } test { name: "list" expr: "type([1, 2, 3])" value: { type_value: "list" } } test { name: "list_denotation" expr: "list" value: { type_value: "list" } } test { name: "lists_monomorphic" expr: "type([1, 2, 3]) == type(['one', 'two', 'three'])" value: { bool_value: true } } test { name: "map" expr: "type({4: 16})" value: { type_value: "map" } } test { name: "map_denotation" expr: "map" value: { type_value: "map" } } test { name: "map_monomorphic" expr: "type({'one': 1}) == type({1: 'one'})" value: { bool_value: true } } test { name: "eq_diff" expr: "type(7) == type(7u)" value: { bool_value: false } } test { name: "neq_same" expr: "type(0.0) != type(-0.0)" value: { bool_value: false } } test { name: "neq_diff" expr: "type(0.0) != type(0)" value: { bool_value: true } } test { name: "meta" expr: "type(type(7)) == type(type(7u))" value: { bool_value: true } } test { name: "type" expr: "type(int)" value: { type_value: "type" } } test { name: "type_denotation" expr: "type" value: { type_value: "type" } } test { name: "type_type" expr: "type(type)" value: { type_value: "type" } } } section { name: "uint" description: "Conversions to uint." test { name: "int" expr: "uint(1729)" value: { uint64_value: 1729 } } test { name: "int_max" expr: "uint(9223372036854775807)" value { uint64_value: 9223372036854775807 } } test { name: "int_neg" expr: "uint(-1)" eval_error { errors { message: "range" } } } test { name: "double" expr: "uint(3.14159265)" value: { uint64_value: 3 } } test { name: "double_truncate" expr: "uint(1.9)" value: { uint64_value: 1 } } test { name: "double_half" expr: "uint(25.5)" value: { uint64_value: 25 } } test { name: "double_big_exact" description: "Beyond exact range (2^53), but no loss of precision (2^55)." expr: "uint(double(36028797018963968u))" value { uint64_value: 36028797018963968 } } test { name: "double_big_precision" description: "Beyond exact range (2^53), but loses precision (2^55 + 1)." expr: "uint(double(36028797018963969u))" value { uint64_value: 36028797018963968 } } test { name: "double_uint_max_range" description: "The exact conversion of uint max as a double does not round trip." expr: "int(18446744073709551615.0)" eval_error { errors: { message: "range" } } } test { name: "double_range_beyond_uint" expr: "uint(6.022e23)" eval_error { errors { message: "range" } } } test { name: "string" expr: "uint('300')" value: { uint64_value: 300 } } } section { name: "bool" description: "Conversions to bool" test { name: "string_1" expr: "bool('1')" value: { bool_value: true } } test { name: "string_t" expr: "bool('t')" value: { bool_value: true } } test { name: "string_true_lowercase" expr: "bool('true')" value: { bool_value: true } } test { name: "string_true_uppercase" expr: "bool('TRUE')" value: { bool_value: true } } test { name: "string_true_pascalcase" expr: "bool('True')" value: { bool_value: true } } test { name: "string_0" expr: "bool('0')" value: { bool_value: false } } test { name: "string_f" expr: "bool('f')" value: { bool_value: false } } test { name: "string_false_lowercase" expr: "bool('false')" value: { bool_value: false } } test { name: "string_false_uppercase" expr: "bool('FALSE')" value: { bool_value: false } } test { name: "string_false_pascalcase" expr: "bool('False')" value: { bool_value: false } } test { name: "string_true_badcase" expr: "bool('TrUe')" eval_error { errors { message: "Type conversion error" } } } test { name: "string_false_badcase" expr: "bool('FaLsE')" eval_error { errors { message: "Type conversion error" } } } } section { name: "identity" description: "Identity functions" test { name: "bool" expr: "bool(true)" value: { bool_value: true } } test { name: "int" expr: "int(1)" value: { int64_value: 1 } } test { name: "uint" expr: "uint(1u)" value: { uint64_value: 1 } } test { name: "double" expr: "double(5.5)" value: { double_value: 5.5 } } test { name: "string" expr: "string('hello')" value: { string_value: "hello" } } test { name: "bytes" expr: "bytes(b'abc')" value: { bytes_value: "abc" } } test { name: "duration" expr: "duration(duration('100s')) == duration('100s')" value: { bool_value: true } } test { name: "timestamp" expr: "timestamp(timestamp(1000000000)) == timestamp(1000000000)" value: { bool_value: true } } }