go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/starlark/starlarkproto/testdata/map_int.star (about) 1 # Copyright 2018 The LUCI Authors. 2 # 3 # Licensed under the Apache License, Version 2.0 (the "License"); 4 # you may not use this file except in compliance with the License. 5 # You may obtain a copy of the License at 6 # 7 # http://www.apache.org/licenses/LICENSE-2.0 8 # 9 # Unless required by applicable law or agreed to in writing, software 10 # distributed under the License is distributed on an "AS IS" BASIS, 11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 # See the License for the specific language governing permissions and 13 # limitations under the License. 14 15 l = proto.new_loader(proto.new_descriptor_set(blob=read('./testprotos/all.pb'))) 16 testprotos = l.module('go.chromium.org/luci/starlark/starlarkproto/testprotos/test.proto') 17 18 msg = testprotos.MapWithPrimitiveType() 19 20 # Default value is empty typed dict. 21 assert.eq(type(msg.m1), 'dict<string,int64>') 22 assert.eq(len(msg.m1), 0) 23 24 # Setting individual keys is OK. 25 msg.m1['k'] = 1 26 assert.eq(dict(msg.m1), {'k': 1}) 27 28 # Performs type checks for both keys and values. 29 def wrong_key_type(): 30 msg.m1[123] = 123 31 assert.fails(wrong_key_type, 'bad key: got int, want string') 32 def wrong_val_type(): 33 msg.m1['zzz'] = 'zzz' 34 assert.fails(wrong_val_type, 'bad value: got string, want int') 35 36 # Overriding the value entirely is OK. 37 msg.m1 = {'v': 1} 38 assert.eq(dict(msg.m1), {'v': 1}) 39 40 # Checking that it is a dict. 41 def set_to_int(): 42 msg.m1 = 1 43 assert.fails(set_to_int, 'got int, want an iterable mapping') 44 45 # Checking that dict items have correct types. 46 def set_to_wrong_dict(): 47 msg.m1 = {'zzz': 'not an int'} 48 assert.fails(set_to_wrong_dict, 'when constructing dict<string,int64>: bad value: got string, want int') 49 50 # Clearing resets the field to its default value (empty dict). 51 msg.m1 = None 52 assert.eq(len(msg.m1), 0) 53 54 # Setting through constructor works 55 msg2 = testprotos.MapWithPrimitiveType(m1={'k': 2}) 56 assert.eq(dict(msg2.m1), {'k': 2}) 57 58 # Serialization to text proto works. 59 text = proto.to_textpb(testprotos.MapWithPrimitiveType(m1={ 60 'k1': 1, 61 'k2': 2, 62 })) 63 assert.eq(text, """m1 { 64 key: "k1" 65 value: 1 66 } 67 m1 { 68 key: "k2" 69 value: 2 70 } 71 """) 72 73 # Fields of the exact same type can point to a single object. 74 msg.m1 = {'k1': 123} 75 msg2.m1 = msg.m1 76 assert.true(msg2.m1 == msg.m1) 77 msg2.m1['k2'] = 456 78 assert.eq(dict(msg.m1), {'k1': 123, 'k2': 456}) 79 80 # Assigning a dict makes a copy. 81 dct = {'k': 555} 82 msg.m1 = dct 83 assert.true(msg.m1 != dct) 84 dct['k'] = 666 85 assert.eq(msg.m1['k'], 555) # old 86 87 # map<string, int32>, i.e. different value type. 88 msg.m2 = {'k': 111} 89 def set_to_m2(): 90 msg.m1 = msg.m2 91 assert.fails(set_to_m2, 92 'can\'t assign dict<string,int32> to field "m1" in ' + 93 'proto.Message<testprotos.MapWithPrimitiveType>: want dict<string,int64> or just dict') 94 msg.m1 = dict(msg.m2) 95 assert.eq(dict(msg.m1), {'k': 111}) 96 97 # map<int64, int64>, i.e. different key type. 98 msg.m3 = {111: 111} 99 def set_to_m3(): 100 msg.m1 = msg.m3 101 assert.fails(set_to_m3, 102 'can\'t assign dict<int64,int64> to field "m1" in ' + 103 'proto.Message<testprotos.MapWithPrimitiveType>: want dict<string,int64> or just dict') 104 105 # Ranges of ints within a map are checked. 106 TWO_POW_63 = 9223372036854775808 107 def set_big_key(): 108 msg.m3[TWO_POW_63] = 1 109 assert.fails(set_big_key, 'bad key: 9223372036854775808 doesn\'t fit into int64') 110 def set_big_val(): 111 msg.m3[1] = TWO_POW_63 112 assert.fails(set_big_val, 'bad value: 9223372036854775808 doesn\'t fit into int64')