~bigbes/tarantool

tarantool-protobuf

ref: b1d9c7581bcc6b4f299155746dc04acc2330e78c tarantool-protobuf/test/any_fieldmask_test.lua -rw-r--r-- 6.3 KiB
b1d9c758 — Eugene Blikh test: pin unknown-fields text-format conformance regressions 3 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
-- Tests for google.protobuf.Any (with type registry) and FieldMask.
local t  = require('luatest')
local pb = require('pb')
local wkt = pb.wkt

local function hex(s)
    local out = {}
    for i = 1, #s do out[i] = string.format('%02x', s:byte(i)) end
    return table.concat(out)
end

-- ---------------------------------------------------------------------------
-- FieldMask
-- ---------------------------------------------------------------------------
local gf = t.group('fieldmask.wire')

gf.test_empty = function()
    t.assert_equals(wkt.FieldMask_encode({}), '')
    t.assert_equals(#wkt.FieldMask_decode(''), 0)
end

gf.test_paths_round_trip = function()
    local mask = {'user.email', 'user.address.city', 'enabled'}
    local enc = wkt.FieldMask_encode(mask)
    local dec = wkt.FieldMask_decode(enc)
    t.assert_equals(#dec, 3)
    t.assert_equals(dec[1], mask[1])
    t.assert_equals(dec[2], mask[2])
    t.assert_equals(dec[3], mask[3])
end

local gfj = t.group('fieldmask.json')
local hello = require('full.hello.hello_pb')

local function reparse(s) return require('json').decode(s) end

gfj.test_encode_canonical_camelcase = function()
    local enc = pb.json.encode(hello.Event_descriptor, {
        update_mask = {'user_id', 'is_admin', 'created_at'},
    })
    -- snake_case → lowerCamelCase, joined by commas.
    t.assert_equals(reparse(enc).updateMask, 'userId,isAdmin,createdAt')
end

gfj.test_decode_camelcase_to_snakecase = function()
    local back = pb.json.decode(hello.Event_descriptor,
        '{"updateMask": "userId,isAdmin"}')
    t.assert_equals(back.update_mask[1], 'user_id')
    t.assert_equals(back.update_mask[2], 'is_admin')
end

-- ---------------------------------------------------------------------------
-- Any
-- ---------------------------------------------------------------------------
local ga = t.group('any.wire')

ga.test_opaque_round_trip = function()
    local opaque = {
        type_url = 'type.googleapis.com/hello.Address',
        value    = '\x0a\x05hello',
    }
    local enc = wkt.Any_encode(opaque)
    local dec = wkt.Any_decode(enc)
    t.assert_equals(dec.type_url, opaque.type_url)
    t.assert_equals(dec.value, opaque.value)
end

ga.test_pack_unpack_via_registry = function()
    pb.register(hello.Address_descriptor)
    local boxed = pb.any.pack(hello.Address_descriptor,
                              {street = 'Main', city = 'X', zip = 1})
    t.assert_str_contains(boxed.type_url, 'hello.Address')
    -- value is the wire-encoded Address payload.
    local unpacked = pb.any.unpack(boxed)
    t.assert_equals(unpacked.street, 'Main')
    t.assert_equals(unpacked.city,   'X')
    t.assert_equals(unpacked.zip,    1)
end

ga.test_unpack_unregistered_errors = function()
    t.assert_error_msg_contains(
        'no descriptor for',
        function() pb.any.unpack({type_url = 'type.unknown/Foo', value = ''}) end)
end

ga.test_unpack_with_explicit_descriptor_overrides_registry = function()
    -- Even if not registered, an explicit descriptor lets unpack succeed.
    local boxed = pb.any.pack(hello.Address_descriptor, {street = 'S'})
    local unpacked = pb.any.unpack(boxed, hello.Address_descriptor)
    t.assert_equals(unpacked.street, 'S')
end

local gaj = t.group('any.json')

gaj.test_json_round_trip_with_registered_type = function()
    pb.register(hello.Address_descriptor)
    local e = {
        extension = pb.any.pack(hello.Address_descriptor,
                                {street = 'JSON St', zip = 7}),
    }
    local enc = pb.json.encode(hello.Event_descriptor, e)
    local obj = reparse(enc)
    -- Flat form: @type plus the Address fields.
    t.assert_equals(obj.extension['@type'],
                    'type.googleapis.com/hello.Address')
    t.assert_equals(obj.extension.street, 'JSON St')
    t.assert_equals(obj.extension.zip, 7)

    -- Decode reverses.
    local back = pb.json.decode(hello.Event_descriptor, enc)
    t.assert_str_contains(back.extension.type_url, 'hello.Address')
    local inner = pb.any.unpack(back.extension)
    t.assert_equals(inner.street, 'JSON St')
    t.assert_equals(inner.zip, 7)
end

gaj.test_json_opaque_fallback_when_type_unregistered = function()
    -- Untouched: even without registry knowledge the value field survives
    -- through a base64 round-trip.
    local opaque = {type_url = 'type.opaque/Foo', value = '\x01\x02\x03'}
    local enc = pb.json.encode(hello.Event_descriptor, {extension = opaque})
    local obj = reparse(enc)
    t.assert_equals(obj.extension['@type'], 'type.opaque/Foo')
    t.assert(obj.extension.value, 'value field present as base64')
    local back = pb.json.decode(hello.Event_descriptor, enc)
    t.assert_equals(back.extension.type_url, 'type.opaque/Foo')
    t.assert_equals(back.extension.value, '\x01\x02\x03')
end

-- ---------------------------------------------------------------------------
-- End-to-end: Event message round-trip with extension + update_mask.
-- ---------------------------------------------------------------------------
for _, mode in ipairs({'full', 'runtime'}) do
    local ge = t.group('any_fieldmask.event.' .. mode)
    local h = require(mode .. '.hello.hello_pb')

    ge.test_event_with_any_and_mask = function()
        pb.register(h.Address_descriptor)
        local e = {
            title       = 'wrapped',
            extension   = pb.any.pack(h.Address_descriptor,
                                      {street = 'A', city = 'B', zip = 5}),
            update_mask = {'title', 'extension'},
        }
        local dec = h.Event_decode(h.Event_encode(e))
        t.assert_equals(dec.title, 'wrapped')
        t.assert_str_contains(dec.extension.type_url, 'hello.Address')
        local inner = pb.any.unpack(dec.extension)
        t.assert_equals(inner.street, 'A')
        t.assert_equals(inner.zip, 5)
        t.assert_equals(#dec.update_mask, 2)
        t.assert_equals(dec.update_mask[1], 'title')
    end
end

local gp = t.group('any_fieldmask.parity')
local hello_full    = require('full.hello.hello_pb')
local hello_runtime = require('runtime.hello.hello_pb')

gp.test_bytes_match_across_modes = function()
    pb.register(hello_full.Address_descriptor)
    local e = {
        extension   = pb.any.pack(hello_full.Address_descriptor,
                                  {street = 'Same', zip = 9}),
        update_mask = {'a', 'b', 'c'},
    }
    t.assert_equals(hex(hello_full.Event_encode(e)),
                    hex(hello_runtime.Event_encode(e)))
end