| # Copyright 2018 The LUCI Authors. |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); |
| # you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| |
| load("go.chromium.org/luci/starlark/starlarkproto/testprotos/test.proto", "testprotos") |
| |
| m = testprotos.Simple() |
| |
| # type() works. |
| assert.eq(type(m), "testprotos.Simple") |
| |
| # dir() works. |
| assert.eq(dir(m), ["i", "many_i"]) |
| |
| # All proto messages are truthy. |
| assert.true(bool(m)) |
| |
| # Stringification works. |
| assert.eq(str(testprotos.Simple(i=123)), "i:123 ") |
| |
| # Protobuf lib abstraction leaking fields are not accessible. |
| def get_XXX_sizecache(): |
| print(m.XXX_sizecache) |
| assert.fails(get_XXX_sizecache, 'has no field "XXX_sizecache"') |
| |
| # Broken protos also stringify, but to an error message. |
| assert.eq( |
| str(testprotos.Simple(many_i=[None])), |
| "<!Bad testprotos.Simple: bad value for field \"many_i\" of " + |
| "\"testprotos.Simple\" - list item #0 - can't assign nil to a value " + |
| "of kind \"int64\"!>") |
| |
| # Proto messages are comparable by identity, but not by value. |
| m1 = testprotos.Simple() |
| m2 = testprotos.Simple() |
| assert.true(m1 == m1) |
| assert.true(m1 != m2) |
| |
| # Assigning totally unsupported types to fields fails. |
| def set_unrelated(): |
| m.i = set([]) |
| assert.fails(set_unrelated, 'don\'t know how to handle starlark value of type "set"') |
| |
| # Grabbing unknown field fails. |
| def get_unknown(): |
| print(m.zzz) |
| assert.fails(get_unknown, 'proto message "testprotos.Simple" has no field "zzz"') |
| |
| # Setting unknown field fails. |
| def set_unknown(): |
| m.zzz = 123 |
| assert.fails(set_unknown, 'proto message "testprotos.Simple" has no field "zzz"') |
| |
| # Proto messages are non-hashable currently. |
| def use_as_key(): |
| d = {m: 123} |
| assert.fails(use_as_key, 'proto message "testprotos.Simple" is not hashable') |
| |
| # dir(...) on a message namespace works. |
| assert.eq(dir(testprotos.Complex), ["ENUM_VAL_1", "InnerMessage", "UNKNOWN"]) |
| |
| # Attempting to access undefined inner message type fails. |
| def unknown_inner(): |
| testprotos.Complex.Blah() |
| assert.fails(unknown_inner, 'testprotos.Complex has no .Blah field or method') |
| |
| # Attempting to replace inner message type fails. |
| def replace_inner(): |
| testprotos.Complex.InnerMessage = None |
| assert.fails(replace_inner, 'can\'t assign to .InnerMessage field of testprotos.Complex') |