# proto-file: ../../../proto/cel/expr/conformance/test/simple.proto # proto-message: cel.expr.conformance.test.SimpleTestFile name: "fields" description: "Tests for field access in maps." section { name: "map_fields" description: "select an element in a map" test { name: "map_key_int64" expr: "{0:1,2:2,5:true}[5]" value: { bool_value: true } } test { name: "map_key_uint64" expr: "{0u:1u,2u:'happy',5u:3u}[2u]" value: { string_value: "happy" } } test { name: "map_key_string" expr: "{'name':100u}['name']" value: { uint64_value: 100 } } test { name: "map_key_bool" expr: "{true:5}[true]" value: { int64_value: 5 } } test { name: "map_key_mixed_type" expr: "{true:1,2:2,5u:3}[true]" value: { int64_value: 1 } } test { name: "map_key_mixed_numbers_double_key" expr: "{1u: 1.0, 2: 2.0, 3u: 3.0}[3.0]" value: { double_value: 3.0 } } test { name: "map_key_mixed_numbers_lossy_double_key" expr: "{1u: 1.0, 2: 2.0, 3u: 3.0}[3.1]" eval_error: { errors: { message: "no such key" } } } test { name: "map_key_mixed_numbers_uint_key" expr: "{1u: 1.0, 2: 2.0, 3u: 3.0}[2u]" value: { double_value: 2.0 } } test { name: "map_key_mixed_numbers_int_key" expr: "{1u: 1.0, 2: 2.0, 3u: 3.0}[1]" value: { double_value: 1.0 } } test { name: "map_field_access" expr: "x.name" type_env: { name: "x" ident: { type: { map_type: { key_type: { primitive: STRING } value_type: { primitive: INT64 } } } } } bindings: { key: "x" value: { value: { map_value: { entries { key: { string_value: "name" } value: { int64_value: 1024 } } } } } } value: { int64_value: 1024 } } test { name: "map_no_such_key" expr: "{0:1,2:2,5:3}[1]" eval_error: { errors: { message: "no such key" } } } test { name: "map_no_such_key_or_false" expr: "dyn({0:1,2:2,5:3}[1]) || false" eval_error: { errors: { message: "no such key" } } } test { name: "map_no_such_key_or_true" expr: "dyn({0:1,2:2,5:3}[1]) || true" value: { bool_value: true } } test { name: "map_no_such_key_and_false" expr: "dyn({0:1,2:2,5:3}[1]) && false" value: { bool_value: false } } test { name: "map_no_such_key_and_true" expr: "dyn({0:1,2:2,5:3}[1]) && true" eval_error: { errors: { message: "no such key" } } } test { name: "map_bad_key_type" expr: "{0:1,2:2,5:3}[dyn(b'')]" eval_error: { errors: { message: "no such key" } } } test { name: "map_bad_key_type_or_false" expr: "dyn({0:1,2:2,5:3}[dyn(b'')]) || false" eval_error: { errors: { message: "no such key" } } } test { name: "map_bad_key_type_or_true" expr: "dyn({0:1,2:2,5:3}[dyn(b'')]) || true" value: { bool_value: true } } test { name: "map_bad_key_type_and_false" expr: "dyn({0:1,2:2,5:3}[dyn(b'')]) && false" value: { bool_value: false } } test { name: "map_bad_key_type_and_true" expr: "dyn({0:1,2:2,5:3}[dyn(b'')]) && true" eval_error: { errors: { message: "no such key" } } } test { name: "map_field_select_no_such_key" expr: "x.name" 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: "holiday" } value: { string_value: "field" } } } } } } eval_error: { errors: { message: "no such key: 'name'" } } } test { name: "map_field_select_no_such_key_or_false" expr: "dyn(x.name) || 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: "holiday" } value: { string_value: "field" } } } } } } eval_error: { errors: { message: "no such key: 'name'" } } } test { name: "map_field_select_no_such_key_or_true" expr: "dyn(x.name) || true" 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: "holiday" } value: { string_value: "field" } } } } } } value: { bool_value: true } } test { name: "map_field_select_no_such_key_and_false" expr: "dyn(x.name) && 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: "holiday" } value: { string_value: "field" } } } } } } value: { bool_value: false } } test { name: "map_field_select_no_such_key_and_true" expr: "dyn(x.name) && true" 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: "holiday" } value: { string_value: "field" } } } } } } eval_error: { errors: { message: "no such key: 'name'" } } } test { name: "map_value_null" expr: "{true:null}[true]" value: { null_value: NULL_VALUE } } test { name: "map_value_bool" expr: "{27:false}[27]" value: { bool_value: false } } test { name: "map_value_string" expr: "{'n':'x'}['n']" value: { string_value: "x" } } test { name: "map_value_float" expr: "{3:15.15}[3]" value: { double_value: 15.15 } } test { name: "map_value_uint64" expr: "{0u:1u,2u:2u,5u:3u}[0u]" value: { uint64_value: 1 } } test { name: "map_value_int64" expr: "{true:1,false:2}[true]" value: { int64_value: 1 } } test { name: "map_value_bytes" expr: "{0:b''}[0]" value: { bytes_value: "" } } test { name: "map_value_list" expr: "{0u:[1]}[0u]" value: { list_value: { values: { int64_value: 1 } } } } test { name: "map_value_map" expr: "{'map': {'k': 'v'}}['map']" value: { map_value { entries { key: { string_value: "k" } value: { string_value: "v" } } } } } test { name: "map_value_mix_type" expr: "{'map': {'k': 'v'}, 'list': [1]}['map']" value: { map_value { entries { key: { string_value: "k" } value: { string_value: "v" } } } } } } section { name: "map_has" description: "Has macro for map entries." test { name: "has" expr: "has({'a': 1, 'b': 2}.a)" value: { bool_value: true } } test { name: "has_not" expr: "has({'a': 1, 'b': 2}.c)" value: { bool_value: false } } test { name: "has_empty" expr: "has({}.a)" value: { bool_value: false } } } section { name: "quoted_map_fields" description: "Field accesses using the quote syntax" test { name: "field_access_slash" expr: "{'/api/v1': true, '/api/v2': false}.`/api/v1`" value: { bool_value: true } } test { name: "field_access_dash" expr: "{'content-type': 'application/json', 'content-length': 145}.`content-type` == 'application/json'" value: { bool_value: true } } test { name: "field_access_dot" expr: "{'foo.txt': 32, 'bar.csv': 1024}.`foo.txt`" value: { int64_value: 32 } } test { name: "has_field_slash" expr: "has({'/api/v1': true, '/api/v2': false}.`/api/v3`)" value: { bool_value: false } } test { name: "has_field_dash" expr: "has({'content-type': 'application/json', 'content-length': 145}.`content-type`)" value: { bool_value: true } } test { name: "has_field_dot" expr: "has({'foo.txt': 32, 'bar.csv': 1024}.`foo.txt`)" value: { bool_value: true } } } section { name: "qualified_identifier_resolution" description: "Tests for qualified identifier resolution." test { name: "qualified_ident" expr: "a.b.c" type_env: { name: "a.b.c" ident: { type: { primitive: STRING } } } bindings: { key: "a.b.c" value: { value: { string_value: "yeah" } } } value: { string_value: "yeah" } } test { name: "map_field_select" expr: "a.b.c" type_env: { name: "a.b" ident: { type: { map_type: { key_type: { primitive: STRING } value_type: { primitive: STRING } } } } } bindings: { key: "a.b" value: { value: { map_value: { entries { key: { string_value: "c" } value: { string_value: "yeah" } } } } } } value: { string_value: "yeah" } } test { name: "qualified_identifier_resolution_unchecked" description: "namespace resolution should try to find the longest prefix for the evaluator." expr: "a.b.c" type_env: { name: "a.b.c" ident: { type: { primitive: STRING } } } bindings: { key: "a.b.c" value: { value: { string_value: "yeah" } } } type_env: { name: "a.b" ident: { type: { map_type: { key_type: { primitive: STRING } value_type: { primitive: STRING } } } } } bindings: { key: "a.b" value: { value: { map_value: { entries { key: { string_value: "c" } value: { string_value: "oops" } } } } } } disable_check: true ## when check is disabled, the evaluator should evaluate it in the correct order value: { string_value: "yeah" } } test { name: "list_field_select_unsupported" expr: "a.b.pancakes" disable_check: true type_env: { name: "a.b" ident: { type: { list_type: { elem_type: { primitive: STRING } } } } } bindings: { key: "a.b" value: { value: { list_value: { values: { string_value: "pancakes" } } } } } eval_error: { errors: { message: "type 'list_type: > ' does not support field selection" } } } test { name: "int64_field_select_unsupported" expr: "a.pancakes" disable_check: true type_env: { name: "a" ident: { type: { primitive: INT64 } } } bindings: { key: "a" value: { value: { int64_value: 15 } } } eval_error: { errors: { message: "type 'int64_type' does not support field selection" } } } test { name: "ident_with_longest_prefix_check" description: "namespace resolution should try to find the longest prefix for the checker." expr: "a.b.c" type_env: { name: "a.b.c" ident: { type: { primitive: STRING } } } bindings: { key: "a.b.c" value: { value: { string_value: "yeah" } } } type_env: { name: "a.b" ident: { type: { map_type: { key_type: { primitive: STRING } value_type: { primitive: STRING } } } } } bindings: { key: "a.b" value: { value: { map_value: { entries { key: { string_value: "c" } value: { string_value: "oops" } } } } } } value: { string_value: "yeah" } } test { name: "map_key_float" description: "map should not support float as the key." expr: "{3.3:15.15, 1.0: 5}[1.0]" disable_check: true # need to make it fail in the evaluation phase eval_error: { errors: { message: "unsupported key type" } } ## Current behavior ## value: { int64_value: 5 } } test { name: "map_key_null" description: "map should not support null as the key." expr: "{null:false}[null]" disable_check: true # need to make it fail in the evaluation phase eval_error: { errors: { message: "unsupported key type" } } ## Current behavior ## value: { bool_value: false } } test { name: "map_value_repeat_key" description: "map should not support repeated key." expr: "{true:1,false:2,true:3}[true]" eval_error: { errors: { message: "Failed with repeated key" } } ## Current behavior: ## value: { int64_value: 1 } } test { name: "map_value_repeat_key_heterogeneous" description: "map should not support repeated key." expr: "{0: 1, 0u: 2}[0.0]" eval_error: { errors: { message: "Failed with repeated key" } } ## Current behavior: ## value: { int64_value: 1 } } } section { name: "in" description: "Tests for 'in' operator for maps." test { name: "empty" expr: "7 in {}" value: { bool_value: false } } test { name: "singleton" expr: "true in {true: 1}" value: { bool_value: true } } test { name: "present" expr: "'George' in {'John': 'smart', 'Paul': 'cute', 'George': 'quiet', 'Ringo': 'funny'}" value: { bool_value: true } } test { name: "absent" expr: "'spider' in {'ant': 6, 'fly': 6, 'centipede': 100}" value: { bool_value: false } } test { name: "mixed_numbers_and_keys_present" expr: "3.0 in {1: 1, 2: 2, 3u: 3} && 2u in {1u: 1, 2: 2} && 1 in {1u: 1, 2: 2}" value: { bool_value: true } } test { name: "mixed_numbers_and_keys_absent" expr: "3.1 in {1: 1, 2: 2, 3u: 3}" value: { bool_value: false } } }