|
|
|
@ -42,285 +42,6 @@ function test_def_readers() |
|
|
|
|
assert_equal(2, e:value("BAZ")) |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
--[[ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function test_enumdef() |
|
|
|
|
function test_iteration() |
|
|
|
|
-- Test that we cannot crash the process even if we modify the set of fields |
|
|
|
|
-- during iteration. |
|
|
|
|
local md = upb.MessageDef{full_name = "TestMessage"} |
|
|
|
|
|
|
|
|
|
for i=1,10 do |
|
|
|
|
md:add(upb.FieldDef{ |
|
|
|
|
name = "field" .. tostring(i), |
|
|
|
|
number = 1000 - i, |
|
|
|
|
type = upb.TYPE_INT32 |
|
|
|
|
}) |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
local add = #md |
|
|
|
|
for f in md:fields() do |
|
|
|
|
if add > 0 then |
|
|
|
|
add = add - 1 |
|
|
|
|
for i=10000,11000 do |
|
|
|
|
local field_name = "field" .. tostring(i) |
|
|
|
|
-- We want to add fields to the table to trigger a table resize, |
|
|
|
|
-- but we must skip it if the field name or number already exists |
|
|
|
|
-- otherwise it will raise an error. |
|
|
|
|
if md:field(field_name) == nil and |
|
|
|
|
md:field(i) == nil then |
|
|
|
|
md:add(upb.FieldDef{ |
|
|
|
|
name = field_name, |
|
|
|
|
number = i, |
|
|
|
|
type = upb.TYPE_INT32 |
|
|
|
|
}) |
|
|
|
|
end |
|
|
|
|
end |
|
|
|
|
end |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
-- Test that iterators don't crash the process even if the MessageDef goes |
|
|
|
|
-- out of scope. |
|
|
|
|
-- |
|
|
|
|
-- Note: have previously verified that this can indeed crash the process if |
|
|
|
|
-- we do not explicitly add a reference from the iterator to the underlying |
|
|
|
|
-- MessageDef. |
|
|
|
|
local iter = md:fields() |
|
|
|
|
md = nil |
|
|
|
|
collectgarbage() |
|
|
|
|
while iter() do |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
local ed = upb.EnumDef{ |
|
|
|
|
values = { |
|
|
|
|
{"FOO", 1}, |
|
|
|
|
{"BAR", 77}, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
iter = ed:values() |
|
|
|
|
ed = nil |
|
|
|
|
collectgarbage() |
|
|
|
|
while iter() do |
|
|
|
|
end |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
function test_msgdef_setters() |
|
|
|
|
local md = upb.MessageDef() |
|
|
|
|
md:set_full_name("Message1") |
|
|
|
|
assert_equal("Message1", md:full_name()) |
|
|
|
|
local f = upb.FieldDef{name = "field1", number = 3, type = upb.TYPE_DOUBLE} |
|
|
|
|
md:add(f) |
|
|
|
|
assert_equal(1, #md) |
|
|
|
|
assert_equal(f, md:field("field1")) |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
function test_msgdef_errors() |
|
|
|
|
assert_error(function() upb.MessageDef{bad_initializer_key = 5} end) |
|
|
|
|
local md = upb.MessageDef() |
|
|
|
|
assert_error(function() |
|
|
|
|
-- Duplicate field number. |
|
|
|
|
upb.MessageDef{ |
|
|
|
|
fields = { |
|
|
|
|
upb.FieldDef{name = "field1", number = 1, type = upb.TYPE_INT32}, |
|
|
|
|
upb.FieldDef{name = "field2", number = 1, type = upb.TYPE_INT32} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
end) |
|
|
|
|
assert_error(function() |
|
|
|
|
-- Duplicate field name. |
|
|
|
|
upb.MessageDef{ |
|
|
|
|
fields = { |
|
|
|
|
upb.FieldDef{name = "field1", number = 1, type = upb.TYPE_INT32}, |
|
|
|
|
upb.FieldDef{name = "field1", number = 2, type = upb.TYPE_INT32} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
end) |
|
|
|
|
|
|
|
|
|
assert_error(function() |
|
|
|
|
-- Duplicate field name. |
|
|
|
|
upb.MessageDef{ |
|
|
|
|
fields = { |
|
|
|
|
upb.OneofDef{name = "field1", fields = { |
|
|
|
|
upb.FieldDef{name = "field2", number = 1, type = upb.TYPE_INT32}, |
|
|
|
|
}}, |
|
|
|
|
upb.FieldDef{name = "field2", number = 2, type = upb.TYPE_INT32} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
end) |
|
|
|
|
|
|
|
|
|
-- attempt to set a name with embedded NULLs. |
|
|
|
|
assert_error_match("names cannot have embedded NULLs", function() |
|
|
|
|
md:set_full_name("abc\0def") |
|
|
|
|
end) |
|
|
|
|
|
|
|
|
|
upb.freeze(md) |
|
|
|
|
-- Attempt to mutate frozen MessageDef. |
|
|
|
|
assert_error_match("frozen", function() |
|
|
|
|
md:add(upb.FieldDef{name = "field1", number = 1, type = upb.TYPE_INT32}) |
|
|
|
|
end) |
|
|
|
|
assert_error_match("frozen", function() |
|
|
|
|
md:set_full_name("abc") |
|
|
|
|
end) |
|
|
|
|
|
|
|
|
|
-- Attempt to freeze a msgdef without freezing its subdef. |
|
|
|
|
assert_error_match("is not frozen or being frozen", function() |
|
|
|
|
m1 = upb.MessageDef() |
|
|
|
|
upb.freeze( |
|
|
|
|
upb.MessageDef{ |
|
|
|
|
fields = { |
|
|
|
|
upb.FieldDef{name = "f1", number = 1, type = upb.TYPE_MESSAGE, |
|
|
|
|
subdef = m1} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
) |
|
|
|
|
end) |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
function test_symtab() |
|
|
|
|
local empty = upb.SymbolTable() |
|
|
|
|
assert_equal(0, #iter_to_array(empty:defs(upb.DEF_ANY))) |
|
|
|
|
assert_equal(0, #iter_to_array(empty:defs(upb.DEF_MSG))) |
|
|
|
|
assert_equal(0, #iter_to_array(empty:defs(upb.DEF_ENUM))) |
|
|
|
|
|
|
|
|
|
local symtab = upb.SymbolTable{ |
|
|
|
|
upb.MessageDef{full_name = "TestMessage"}, |
|
|
|
|
upb.MessageDef{full_name = "ContainingMessage", fields = { |
|
|
|
|
upb.FieldDef{name = "field1", number = 1, type = upb.TYPE_INT32}, |
|
|
|
|
upb.FieldDef{name = "field2", number = 2, type = upb.TYPE_MESSAGE, |
|
|
|
|
subdef_name = ".TestMessage"} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
local msgdef1 = symtab:lookup("TestMessage") |
|
|
|
|
local msgdef2 = symtab:lookup("ContainingMessage") |
|
|
|
|
assert_not_nil(msgdef1) |
|
|
|
|
assert_not_nil(msgdef2) |
|
|
|
|
assert_equal(msgdef1, msgdef2:field("field2"):subdef()) |
|
|
|
|
assert_true(msgdef1:is_frozen()) |
|
|
|
|
assert_true(msgdef2:is_frozen()) |
|
|
|
|
|
|
|
|
|
symtab:add{ |
|
|
|
|
upb.MessageDef{full_name = "ContainingMessage2", fields = { |
|
|
|
|
upb.FieldDef{name = "field5", number = 5, type = upb.TYPE_MESSAGE, |
|
|
|
|
subdef = msgdef2} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
local msgdef3 = symtab:lookup("ContainingMessage2") |
|
|
|
|
assert_not_nil(msgdef3) |
|
|
|
|
assert_equal(msgdef3:field("field5"):subdef(), msgdef2) |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
function test_msg_primitives() |
|
|
|
|
local function test_for_numeric_type(upb_type, val, too_big, too_small, bad3) |
|
|
|
|
local symtab = upb.SymbolTable{ |
|
|
|
|
upb.MessageDef{full_name = "TestMessage", fields = { |
|
|
|
|
upb.FieldDef{name = "f", number = 1, type = upb_type}, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
factory = upb.MessageFactory(symtab) |
|
|
|
|
TestMessage = factory:get_message_class("TestMessage") |
|
|
|
|
msg = TestMessage() |
|
|
|
|
|
|
|
|
|
-- Defaults to zero |
|
|
|
|
assert_equal(0, msg.f) |
|
|
|
|
|
|
|
|
|
msg.f = 0 |
|
|
|
|
assert_equal(0, msg.f) |
|
|
|
|
|
|
|
|
|
msg.f = val |
|
|
|
|
assert_equal(val, msg.f) |
|
|
|
|
|
|
|
|
|
local errmsg = "not an integer or out of range" |
|
|
|
|
if too_small then |
|
|
|
|
assert_error_match(errmsg, function() msg.f = too_small end) |
|
|
|
|
end |
|
|
|
|
if too_big then |
|
|
|
|
assert_error_match(errmsg, function() msg.f = too_big end) |
|
|
|
|
end |
|
|
|
|
if bad3 then |
|
|
|
|
assert_error_match(errmsg, function() msg.f = bad3 end) |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
-- Can't assign other Lua types. |
|
|
|
|
errmsg = "bad argument #3" |
|
|
|
|
assert_error_match(errmsg, function() msg.f = "abc" end) |
|
|
|
|
assert_error_match(errmsg, function() msg.f = true end) |
|
|
|
|
assert_error_match(errmsg, function() msg.f = false end) |
|
|
|
|
assert_error_match(errmsg, function() msg.f = nil end) |
|
|
|
|
assert_error_match(errmsg, function() msg.f = {} end) |
|
|
|
|
assert_error_match(errmsg, function() msg.f = print end) |
|
|
|
|
assert_error_match(errmsg, function() msg.f = array end) |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
local symtab = upb.SymbolTable{ |
|
|
|
|
upb.MessageDef{full_name = "TestMessage", fields = { |
|
|
|
|
upb.FieldDef{ |
|
|
|
|
name = "i32", number = 1, type = upb.TYPE_INT32, default = 1}, |
|
|
|
|
upb.FieldDef{ |
|
|
|
|
name = "u32", number = 2, type = upb.TYPE_UINT32, default = 2}, |
|
|
|
|
upb.FieldDef{ |
|
|
|
|
name = "i64", number = 3, type = upb.TYPE_INT64, default = 3}, |
|
|
|
|
upb.FieldDef{ |
|
|
|
|
name = "u64", number = 4, type = upb.TYPE_UINT64, default = 4}, |
|
|
|
|
upb.FieldDef{ |
|
|
|
|
name = "dbl", number = 5, type = upb.TYPE_DOUBLE, default = 5}, |
|
|
|
|
upb.FieldDef{ |
|
|
|
|
name = "flt", number = 6, type = upb.TYPE_FLOAT, default = 6}, |
|
|
|
|
upb.FieldDef{ |
|
|
|
|
name = "bool", number = 7, type = upb.TYPE_BOOL, default = true}, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
factory = upb.MessageFactory(symtab) |
|
|
|
|
TestMessage = factory:get_message_class("TestMessage") |
|
|
|
|
msg = TestMessage() |
|
|
|
|
|
|
|
|
|
-- Unset member returns default value. |
|
|
|
|
-- TODO(haberman): re-enable these when we have descriptor-based reflection. |
|
|
|
|
-- assert_equal(1, msg.i32) |
|
|
|
|
-- assert_equal(2, msg.u32) |
|
|
|
|
-- assert_equal(3, msg.i64) |
|
|
|
|
-- assert_equal(4, msg.u64) |
|
|
|
|
-- assert_equal(5, msg.dbl) |
|
|
|
|
-- assert_equal(6, msg.flt) |
|
|
|
|
-- assert_equal(true, msg.bool) |
|
|
|
|
|
|
|
|
|
-- Attempts to access non-existent fields fail. |
|
|
|
|
assert_error_match("no such field", function() msg.no_such = 1 end) |
|
|
|
|
|
|
|
|
|
msg.i32 = 10 |
|
|
|
|
msg.u32 = 20 |
|
|
|
|
msg.i64 = 30 |
|
|
|
|
msg.u64 = 40 |
|
|
|
|
msg.dbl = 50 |
|
|
|
|
msg.flt = 60 |
|
|
|
|
msg.bool = true |
|
|
|
|
|
|
|
|
|
assert_equal(10, msg.i32) |
|
|
|
|
assert_equal(20, msg.u32) |
|
|
|
|
assert_equal(30, msg.i64) |
|
|
|
|
assert_equal(40, msg.u64) |
|
|
|
|
assert_equal(50, msg.dbl) |
|
|
|
|
assert_equal(60, msg.flt) |
|
|
|
|
assert_equal(true, msg.bool) |
|
|
|
|
|
|
|
|
|
test_for_numeric_type(upb.TYPE_UINT32, 2^32 - 1, 2^32, -1, 5.1) |
|
|
|
|
test_for_numeric_type(upb.TYPE_UINT64, 2^62, 2^64, -1, bad64) |
|
|
|
|
test_for_numeric_type(upb.TYPE_INT32, 2^31 - 1, 2^31, -2^31 - 1, 5.1) |
|
|
|
|
test_for_numeric_type(upb.TYPE_INT64, 2^61, 2^63, -2^64, bad64) |
|
|
|
|
test_for_numeric_type(upb.TYPE_FLOAT, 2^20) |
|
|
|
|
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 |
|
|
|
@ -335,6 +56,21 @@ function test_msg_map() |
|
|
|
|
assert_equal(12, msg2.map_int32_int32[6]) |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
function test_msg_string_map() |
|
|
|
|
msg = test_messages_proto3.TestAllTypesProto3() |
|
|
|
|
msg.map_string_string["foo"] = "bar" |
|
|
|
|
msg.map_string_string["baz"] = "quux" |
|
|
|
|
assert_nil(msg.map_string_string["abc"]) |
|
|
|
|
assert_equal("bar", msg.map_string_string["foo"]) |
|
|
|
|
assert_equal("quux", msg.map_string_string["baz"]) |
|
|
|
|
|
|
|
|
|
local serialized = upb.encode(msg) |
|
|
|
|
assert_true(#serialized > 0) |
|
|
|
|
local msg2 = upb.decode(test_messages_proto3.TestAllTypesProto3, serialized) |
|
|
|
|
assert_equal("bar", msg2.map_string_string["foo"]) |
|
|
|
|
assert_equal("quux", msg2.map_string_string["baz"]) |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
function test_msg_array() |
|
|
|
|
msg = test_messages_proto3.TestAllTypesProto3() |
|
|
|
|
|
|
|
|
@ -472,6 +208,46 @@ local numeric_types = { |
|
|
|
|
}, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function test_msg_primitives() |
|
|
|
|
local msg = test_messages_proto3.TestAllTypesProto3{ |
|
|
|
|
optional_int32 = 10, |
|
|
|
|
optional_uint32 = 20, |
|
|
|
|
optional_int64 = 30, |
|
|
|
|
optional_uint64 = 40, |
|
|
|
|
optional_double = 50, |
|
|
|
|
optional_float = 60, |
|
|
|
|
optional_sint32 = 70, |
|
|
|
|
optional_sint64 = 80, |
|
|
|
|
optional_fixed32 = 90, |
|
|
|
|
optional_fixed64 = 100, |
|
|
|
|
optional_sfixed32 = 110, |
|
|
|
|
optional_sfixed64 = 120, |
|
|
|
|
optional_bool = true, |
|
|
|
|
optional_string = "abc", |
|
|
|
|
optional_nested_message = test_messages_proto3['TestAllTypesProto3.NestedMessage']{a = 123}, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
-- Attempts to access non-existent fields fail. |
|
|
|
|
assert_error_match("no such field", function() msg.no_such = 1 end) |
|
|
|
|
|
|
|
|
|
assert_equal(10, msg.optional_int32) |
|
|
|
|
assert_equal(20, msg.optional_uint32) |
|
|
|
|
assert_equal(30, msg.optional_int64) |
|
|
|
|
assert_equal(40, msg.optional_uint64) |
|
|
|
|
assert_equal(50, msg.optional_double) |
|
|
|
|
assert_equal(60, msg.optional_float) |
|
|
|
|
assert_equal(70, msg.optional_sint32) |
|
|
|
|
assert_equal(80, msg.optional_sint64) |
|
|
|
|
assert_equal(90, msg.optional_fixed32) |
|
|
|
|
assert_equal(100, msg.optional_fixed64) |
|
|
|
|
assert_equal(110, msg.optional_sfixed32) |
|
|
|
|
assert_equal(120, msg.optional_sfixed64) |
|
|
|
|
assert_equal(true, msg.optional_bool) |
|
|
|
|
assert_equal("abc", msg.optional_string) |
|
|
|
|
assert_equal(123, msg.optional_nested_message.a) |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function test_string_array() |
|
|
|
|
local function test_for_string_type(upb_type) |
|
|
|
|
local array = upb.Array(upb_type) |
|
|
|
|