|
|
|
@ -1,6 +1,8 @@ |
|
|
|
|
|
|
|
|
|
local upb = require "lupb" |
|
|
|
|
local lunit = require "lunit" |
|
|
|
|
local test_messages_proto3 = require "google.protobuf.test_messages_proto3_pb" |
|
|
|
|
local descriptor = require "google.protobuf.descriptor_pb" |
|
|
|
|
|
|
|
|
|
if _VERSION >= 'Lua 5.2' then |
|
|
|
|
_ENV = lunit.module("testupb", "seeall") |
|
|
|
@ -16,227 +18,34 @@ function iter_to_array(iter) |
|
|
|
|
return arr |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
--[[ |
|
|
|
|
|
|
|
|
|
function test_msgdef() |
|
|
|
|
local f2 = upb.FieldDef{name = "field2", number = 1, type = upb.TYPE_INT32} |
|
|
|
|
local o = upb.OneofDef{name = "field1", fields = {f2}} |
|
|
|
|
local f = upb.FieldDef{name = "field3", number = 2, type = upb.TYPE_INT32} |
|
|
|
|
|
|
|
|
|
local m = upb.MessageDef{fields = {o, f}} |
|
|
|
|
|
|
|
|
|
assert_equal(f, m:lookup_name("field3")) |
|
|
|
|
assert_equal(o, m:lookup_name("field1")) |
|
|
|
|
assert_equal(f2, m:lookup_name("field2")) |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
function test_fielddef() |
|
|
|
|
local f = upb.FieldDef() |
|
|
|
|
assert_false(f:is_frozen()) |
|
|
|
|
assert_nil(f:number()) |
|
|
|
|
assert_nil(f:name()) |
|
|
|
|
assert_nil(f:type()) |
|
|
|
|
function test_def_readers() |
|
|
|
|
local m = test_messages_proto3.TestAllTypesProto3 |
|
|
|
|
assert_equal("TestAllTypesProto3", m:name()) |
|
|
|
|
assert_equal("protobuf_test_messages.proto3.TestAllTypesProto3", m:full_name()) |
|
|
|
|
|
|
|
|
|
-- field |
|
|
|
|
local f = m:field("optional_int32") |
|
|
|
|
local f2 = m:field(1) |
|
|
|
|
assert_equal(f, f2) |
|
|
|
|
assert_equal(1, f:number()) |
|
|
|
|
assert_equal("optional_int32", f:name()) |
|
|
|
|
assert_equal(upb.LABEL_OPTIONAL, f:label()) |
|
|
|
|
|
|
|
|
|
f:set_name("foo_field") |
|
|
|
|
f:set_number(3) |
|
|
|
|
f:set_label(upb.LABEL_REPEATED) |
|
|
|
|
f:set_type(upb.TYPE_FLOAT) |
|
|
|
|
|
|
|
|
|
assert_equal("foo_field", f:name()) |
|
|
|
|
assert_equal(3, f:number()) |
|
|
|
|
assert_equal(upb.LABEL_REPEATED, f:label()) |
|
|
|
|
assert_equal(upb.TYPE_FLOAT, f:type()) |
|
|
|
|
|
|
|
|
|
local f2 = upb.FieldDef{ |
|
|
|
|
name = "foo", number = 5, type = upb.TYPE_DOUBLE, label = upb.LABEL_REQUIRED |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
assert_equal("foo", f2:name()) |
|
|
|
|
assert_equal(5, f2:number()) |
|
|
|
|
assert_equal(upb.TYPE_DOUBLE, f2:type()) |
|
|
|
|
assert_equal(upb.LABEL_REQUIRED, f2:label()) |
|
|
|
|
assert_equal(upb.DESCRIPTOR_TYPE_INT32, f:descriptor_type()) |
|
|
|
|
assert_equal(upb.TYPE_INT32, f:type()) |
|
|
|
|
assert_nil(f:containing_oneof()) |
|
|
|
|
assert_equal(m, f:containing_type()) |
|
|
|
|
assert_equal(0, f:default()) |
|
|
|
|
|
|
|
|
|
-- enum |
|
|
|
|
local e = test_messages_proto3['TestAllTypesProto3.NestedEnum'] |
|
|
|
|
assert_true(#e > 3 and #e < 10) |
|
|
|
|
assert_equal(2, e:value("BAZ")) |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
function test_enumdef() |
|
|
|
|
local e = upb.EnumDef() |
|
|
|
|
assert_equal(0, #e) |
|
|
|
|
assert_nil(e:value(5)) |
|
|
|
|
assert_nil(e:value("NONEXISTENT_NAME")) |
|
|
|
|
|
|
|
|
|
for name, value in e:values() do |
|
|
|
|
fail() |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
e:add("VAL1", 1) |
|
|
|
|
e:add("VAL2", 2) |
|
|
|
|
|
|
|
|
|
local values = {} |
|
|
|
|
for name, value in e:values() do |
|
|
|
|
values[name] = value |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
assert_equal(1, values["VAL1"]) |
|
|
|
|
assert_equal(2, values["VAL2"]) |
|
|
|
|
|
|
|
|
|
local e2 = upb.EnumDef{ |
|
|
|
|
values = { |
|
|
|
|
{"FOO", 1}, |
|
|
|
|
{"BAR", 77}, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
assert_equal(1, e2:value("FOO")) |
|
|
|
|
assert_equal(77, e2:value("BAR")) |
|
|
|
|
assert_equal("FOO", e2:value(1)) |
|
|
|
|
assert_equal("BAR", e2:value(77)) |
|
|
|
|
|
|
|
|
|
e2:freeze() |
|
|
|
|
|
|
|
|
|
local f = upb.FieldDef{type = upb.TYPE_ENUM} |
|
|
|
|
|
|
|
|
|
-- No default set and no EnumDef to get a default from. |
|
|
|
|
assert_equal(f:default(), nil) |
|
|
|
|
|
|
|
|
|
f:set_subdef(upb.EnumDef()) |
|
|
|
|
-- No default to pull in from the EnumDef. |
|
|
|
|
assert_equal(f:default(), nil) |
|
|
|
|
|
|
|
|
|
f:set_subdef(e2) |
|
|
|
|
-- First member added to e2. |
|
|
|
|
assert_equal(f:default(), "FOO") |
|
|
|
|
|
|
|
|
|
f:set_subdef(nil) |
|
|
|
|
assert_equal(f:default(), nil) |
|
|
|
|
|
|
|
|
|
f:set_default(1) |
|
|
|
|
assert_equal(f:default(), 1) |
|
|
|
|
|
|
|
|
|
f:set_default("YOYOYO") |
|
|
|
|
assert_equal(f:default(), "YOYOYO") |
|
|
|
|
|
|
|
|
|
f:set_subdef(e2) |
|
|
|
|
f:set_default(1) |
|
|
|
|
-- It prefers to return a string, and could resolve the explicit "1" we set |
|
|
|
|
-- it to to the string value. |
|
|
|
|
assert_equal(f:default(), "FOO") |
|
|
|
|
|
|
|
|
|
-- FieldDef can specify default value by name or number, but the value must |
|
|
|
|
-- exist at freeze time. |
|
|
|
|
local m1 = upb.build_defs{ |
|
|
|
|
upb.MessageDef{ |
|
|
|
|
full_name = "A", |
|
|
|
|
fields = { |
|
|
|
|
upb.FieldDef{ |
|
|
|
|
name = "f1", |
|
|
|
|
number = 1, |
|
|
|
|
type = upb.TYPE_ENUM, |
|
|
|
|
subdef = e2, |
|
|
|
|
default = "BAR" |
|
|
|
|
}, |
|
|
|
|
upb.FieldDef{ |
|
|
|
|
name = "f2", |
|
|
|
|
number = 2, |
|
|
|
|
type = upb.TYPE_ENUM, |
|
|
|
|
subdef = e2, |
|
|
|
|
default = 77 |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
assert_equal(m1:field("f1"):default(), "BAR") |
|
|
|
|
assert_equal(m1:field("f1"):default(), "BAR") |
|
|
|
|
|
|
|
|
|
assert_error_match( |
|
|
|
|
"enum default for field A.f1 .DOESNT_EXIST. is not in the enum", |
|
|
|
|
function() |
|
|
|
|
local m1 = upb.build_defs{ |
|
|
|
|
upb.MessageDef{ |
|
|
|
|
full_name = "A", |
|
|
|
|
fields = { |
|
|
|
|
upb.FieldDef{ |
|
|
|
|
name = "f1", |
|
|
|
|
number = 1, |
|
|
|
|
type = upb.TYPE_ENUM, |
|
|
|
|
subdef = e2, |
|
|
|
|
default = "DOESNT_EXIST" |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
end |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
assert_error_match( |
|
|
|
|
"enum default for field A.f1 .142. is not in the enum", |
|
|
|
|
function() |
|
|
|
|
local m1 = upb.build_defs{ |
|
|
|
|
upb.MessageDef{ |
|
|
|
|
full_name = "A", |
|
|
|
|
fields = { |
|
|
|
|
upb.FieldDef{ |
|
|
|
|
name = "f1", |
|
|
|
|
number = 1, |
|
|
|
|
type = upb.TYPE_ENUM, |
|
|
|
|
subdef = e2, |
|
|
|
|
default = 142 |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
end |
|
|
|
|
) |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
function test_empty_msgdef() |
|
|
|
|
local md = upb.MessageDef() |
|
|
|
|
assert_nil(md:full_name()) -- Def without name is anonymous. |
|
|
|
|
assert_false(md:is_frozen()) |
|
|
|
|
assert_equal(0, #md) |
|
|
|
|
assert_nil(md:field("nonexistent_field")) |
|
|
|
|
assert_nil(md:field(3)) |
|
|
|
|
for field in md:fields() do |
|
|
|
|
fail() |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
upb.freeze(md) |
|
|
|
|
assert_true(md:is_frozen()) |
|
|
|
|
assert_equal(0, #md) |
|
|
|
|
assert_nil(md:field("nonexistent_field")) |
|
|
|
|
assert_nil(md:field(3)) |
|
|
|
|
for field in md:fields() do |
|
|
|
|
fail() |
|
|
|
|
end |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
function test_msgdef_constructor() |
|
|
|
|
local f1 = upb.FieldDef{name = "field1", number = 7, type = upb.TYPE_INT32} |
|
|
|
|
local f2 = upb.FieldDef{name = "field2", number = 8, type = upb.TYPE_INT32} |
|
|
|
|
local md = upb.MessageDef{ |
|
|
|
|
full_name = "TestMessage", |
|
|
|
|
fields = {f1, f2} |
|
|
|
|
} |
|
|
|
|
assert_equal("TestMessage", md:full_name()) |
|
|
|
|
assert_false(md:is_frozen()) |
|
|
|
|
assert_equal(2, #md) |
|
|
|
|
assert_equal(f1, md:field("field1")) |
|
|
|
|
assert_equal(f2, md:field("field2")) |
|
|
|
|
assert_equal(f1, md:field(7)) |
|
|
|
|
assert_equal(f2, md:field(8)) |
|
|
|
|
local count = 0 |
|
|
|
|
local found = {} |
|
|
|
|
for field in md:fields() do |
|
|
|
|
count = count + 1 |
|
|
|
|
found[field] = true |
|
|
|
|
end |
|
|
|
|
assert_equal(2, count) |
|
|
|
|
assert_true(found[f1]) |
|
|
|
|
assert_true(found[f2]) |
|
|
|
|
--[[ |
|
|
|
|
|
|
|
|
|
upb.freeze(md) |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
function test_enumdef() |
|
|
|
|
function test_iteration() |
|
|
|
|
-- Test that we cannot crash the process even if we modify the set of fields |
|
|
|
|
-- during iteration. |
|
|
|
@ -510,81 +319,85 @@ function test_msg_primitives() |
|
|
|
|
test_for_numeric_type(upb.TYPE_DOUBLE, 10^101) |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
==]] |
|
|
|
|
|
|
|
|
|
function test_msg_map() |
|
|
|
|
msg = test_messages_proto3.TestAllTypesProto3() |
|
|
|
|
msg.map_int32_int32[5] = 10 |
|
|
|
|
msg.map_int32_int32[6] = 12 |
|
|
|
|
assert_equal(10, msg.map_int32_int32[5]) |
|
|
|
|
assert_equal(12, msg.map_int32_int32[6]) |
|
|
|
|
|
|
|
|
|
local serialized = upb.encode(msg) |
|
|
|
|
assert_true(#serialized > 0) |
|
|
|
|
local msg2 = upb.decode(test_messages_proto3.TestAllTypesProto3, serialized) |
|
|
|
|
assert_equal(10, msg2.map_int32_int32[5]) |
|
|
|
|
assert_equal(12, msg2.map_int32_int32[6]) |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
function test_msg_array() |
|
|
|
|
local symtab = upb.SymbolTable{ |
|
|
|
|
upb.MessageDef{full_name = "TestMessage", fields = { |
|
|
|
|
upb.FieldDef{name = "i32_array", number = 1, type = upb.TYPE_INT32, |
|
|
|
|
label = upb.LABEL_REPEATED}, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
msg = test_messages_proto3.TestAllTypesProto3() |
|
|
|
|
|
|
|
|
|
factory = upb.MessageFactory(symtab) |
|
|
|
|
TestMessage = factory:get_message_class("TestMessage") |
|
|
|
|
msg = TestMessage() |
|
|
|
|
assert_not_nil(msg.repeated_int32) |
|
|
|
|
assert_equal(msg.repeated_int32, msg.repeated_int32) |
|
|
|
|
assert_equal(0, #msg.repeated_int32) |
|
|
|
|
|
|
|
|
|
assert_nil(msg.i32_array) |
|
|
|
|
msg.repeated_int32[1] = 2 |
|
|
|
|
assert_equal(1, #msg.repeated_int32); |
|
|
|
|
assert_equal(2, msg.repeated_int32[1]); |
|
|
|
|
|
|
|
|
|
-- Can't assign a scalar; array is expected. |
|
|
|
|
assert_error_match("lupb.array expected", function() msg.i32_array = 5 end) |
|
|
|
|
assert_error_match("lupb.array expected", function() msg.repeated_int32 = 5 end) |
|
|
|
|
|
|
|
|
|
-- Can't assign array of the wrong type. |
|
|
|
|
local function assign_int64() |
|
|
|
|
msg.i32_array = upb.Array(upb.TYPE_INT64) |
|
|
|
|
msg.repeated_int32 = upb.Array(upb.TYPE_INT64) |
|
|
|
|
end |
|
|
|
|
assert_error_match("Array had incorrect type", assign_int64) |
|
|
|
|
assert_error_match("array type mismatch", assign_int64) |
|
|
|
|
|
|
|
|
|
local arr = upb.Array(upb.TYPE_INT32) |
|
|
|
|
msg.i32_array = arr |
|
|
|
|
assert_equal(arr, msg.i32_array) |
|
|
|
|
arr[1] = 6 |
|
|
|
|
assert_equal(1, #arr) |
|
|
|
|
msg.repeated_int32 = arr |
|
|
|
|
assert_equal(msg.repeated_int32, msg.repeated_int32) |
|
|
|
|
assert_equal(arr, msg.repeated_int32) |
|
|
|
|
assert_equal(1, #msg.repeated_int32) |
|
|
|
|
assert_equal(6, msg.repeated_int32[1]) |
|
|
|
|
|
|
|
|
|
-- Can't assign other Lua types. |
|
|
|
|
assert_error_match("array expected", function() msg.i32_array = "abc" end) |
|
|
|
|
assert_error_match("array expected", function() msg.i32_array = true end) |
|
|
|
|
assert_error_match("array expected", function() msg.i32_array = false end) |
|
|
|
|
assert_error_match("array expected", function() msg.i32_array = nil end) |
|
|
|
|
assert_error_match("array expected", function() msg.i32_array = {} end) |
|
|
|
|
assert_error_match("array expected", function() msg.i32_array = print end) |
|
|
|
|
assert_error_match("array expected", function() msg.repeated_int32 = "abc" end) |
|
|
|
|
assert_error_match("array expected", function() msg.repeated_int32 = true end) |
|
|
|
|
assert_error_match("array expected", function() msg.repeated_int32 = false end) |
|
|
|
|
assert_error_match("array expected", function() msg.repeated_int32 = nil end) |
|
|
|
|
assert_error_match("array expected", function() msg.repeated_int32 = {} end) |
|
|
|
|
assert_error_match("array expected", function() msg.repeated_int32 = print end) |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
function test_msg_submsg() |
|
|
|
|
local symtab = upb.SymbolTable{ |
|
|
|
|
upb.MessageDef{full_name = "TestMessage", fields = { |
|
|
|
|
upb.FieldDef{name = "submsg", number = 1, type = upb.TYPE_MESSAGE, |
|
|
|
|
subdef_name = ".SubMessage"}, |
|
|
|
|
} |
|
|
|
|
}, |
|
|
|
|
upb.MessageDef{full_name = "SubMessage"} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
factory = upb.MessageFactory(symtab) |
|
|
|
|
TestMessage = factory:get_message_class("TestMessage") |
|
|
|
|
SubMessage = factory:get_message_class("SubMessage") |
|
|
|
|
msg = TestMessage() |
|
|
|
|
--msg = test_messages_proto3.TestAllTypesProto3() |
|
|
|
|
msg = test_messages_proto3['TestAllTypesProto3']() |
|
|
|
|
|
|
|
|
|
assert_nil(msg.submsg) |
|
|
|
|
assert_nil(msg.optional_nested_message) |
|
|
|
|
|
|
|
|
|
-- Can't assign message of the wrong type. |
|
|
|
|
local function assign_int64() |
|
|
|
|
msg.submsg = TestMessage() |
|
|
|
|
msg.optional_nested_message = test_messages_proto3.TestAllTypesProto3() |
|
|
|
|
end |
|
|
|
|
assert_error_match("Message had incorrect type", assign_int64) |
|
|
|
|
assert_error_match("message type mismatch", assign_int64) |
|
|
|
|
|
|
|
|
|
local sub = SubMessage() |
|
|
|
|
msg.submsg = sub |
|
|
|
|
assert_equal(sub, msg.submsg) |
|
|
|
|
local nested = test_messages_proto3['TestAllTypesProto3.NestedMessage']() |
|
|
|
|
msg.optional_nested_message = nested |
|
|
|
|
assert_equal(nested, msg.optional_nested_message) |
|
|
|
|
|
|
|
|
|
-- Can't assign other Lua types. |
|
|
|
|
assert_error_match("msg expected", function() msg.submsg = "abc" end) |
|
|
|
|
assert_error_match("msg expected", function() msg.submsg = true end) |
|
|
|
|
assert_error_match("msg expected", function() msg.submsg = false end) |
|
|
|
|
assert_error_match("msg expected", function() msg.submsg = nil end) |
|
|
|
|
assert_error_match("msg expected", function() msg.submsg = {} end) |
|
|
|
|
assert_error_match("msg expected", function() msg.submsg = print end) |
|
|
|
|
assert_error_match("msg expected", function() msg.optional_nested_message = "abc" end) |
|
|
|
|
assert_error_match("msg expected", function() msg.optional_nested_message = true end) |
|
|
|
|
assert_error_match("msg expected", function() msg.optional_nested_message = false end) |
|
|
|
|
assert_error_match("msg expected", function() msg.optional_nested_message = nil end) |
|
|
|
|
assert_error_match("msg expected", function() msg.optional_nested_message = {} end) |
|
|
|
|
assert_error_match("msg expected", function() msg.optional_nested_message = print end) |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
--]] |
|
|
|
|
|
|
|
|
|
-- Lua 5.1 and 5.2 have slightly different semantics for how a finalizer |
|
|
|
|
-- can be defined in Lua. |
|
|
|
|
if _VERSION >= 'Lua 5.2' then |
|
|
|
@ -765,6 +578,35 @@ function test_numeric_map() |
|
|
|
|
|
|
|
|
|
map[key_vals.valid_val] = val_vals.valid_val |
|
|
|
|
assert_equal(1, #map) |
|
|
|
|
assert_equal(val_vals.valid_val, map[key_vals.valid_val]) |
|
|
|
|
|
|
|
|
|
i = 0 |
|
|
|
|
for k, v in pairs(map) do |
|
|
|
|
assert_equal(key_vals.valid_val, k) |
|
|
|
|
assert_equal(val_vals.valid_val, v) |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
-- Out of range key/val |
|
|
|
|
local errmsg = "not an integer or out of range" |
|
|
|
|
if key_vals.too_small then |
|
|
|
|
assert_error_match(errmsg, function() map[key_vals.too_small] = 1 end) |
|
|
|
|
end |
|
|
|
|
if key_vals.too_big then |
|
|
|
|
assert_error_match(errmsg, function() map[key_vals.too_big] = 1 end) |
|
|
|
|
end |
|
|
|
|
if key_vals.other_bad then |
|
|
|
|
assert_error_match(errmsg, function() map[key_vals.other_bad] = 1 end) |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
if val_vals.too_small then |
|
|
|
|
assert_error_match(errmsg, function() map[1] = val_vals.too_small end) |
|
|
|
|
end |
|
|
|
|
if val_vals.too_big then |
|
|
|
|
assert_error_match(errmsg, function() map[1] = val_vals.too_big end) |
|
|
|
|
end |
|
|
|
|
if val_vals.other_bad then |
|
|
|
|
assert_error_match(errmsg, function() map[1] = val_vals.other_bad end) |
|
|
|
|
end |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
for k in pairs(numeric_types) do |
|
|
|
|