summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorJosh Haberman <jhaberman@gmail.com>2014-06-26 20:24:32 -0700
committerJosh Haberman <jhaberman@gmail.com>2014-06-26 20:24:32 -0700
commit2d10fa33071d52d7a35ce3b13bc459cd16a0aa33 (patch)
treebf47d38e2e1cc8ddb4711b23b26e7fd10742e07d /tests
parent7d565f1e7a0f107506d3cf31ef2e33e22a504d2b (diff)
Sync from internal Google development.
Diffstat (limited to 'tests')
-rw-r--r--tests/bindings/lua/test.lua303
-rw-r--r--tests/bindings/lua/upb.lua757
-rw-r--r--tests/bindings/lua/upb.pb.lua70
-rw-r--r--tests/pb/test_decoder.cc50
-rw-r--r--tests/test_cpp.cc38
-rw-r--r--tests/test_def.c34
-rw-r--r--tests/test_handlers.c5
-rw-r--r--tests/test_table.cc23
-rw-r--r--tests/test_vs_proto2.cc5
9 files changed, 952 insertions, 333 deletions
diff --git a/tests/bindings/lua/test.lua b/tests/bindings/lua/test.lua
deleted file mode 100644
index 99f58f2..0000000
--- a/tests/bindings/lua/test.lua
+++ /dev/null
@@ -1,303 +0,0 @@
-
-local upb = require "upb"
-local lunit = require "lunit"
-
-if _VERSION >= 'Lua 5.2' then
- _ENV = lunit.module("testupb", "seeall")
-else
- module("testupb", lunit.testcase, package.seeall)
-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())
- 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())
-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))
-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_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)
-
- -- 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.
- -- TODO(haberman): better error message and test for message.
- assert_error(function()
- md:add{upb.FieldDef{name = "field1", number = 1, type = upb.TYPE_INT32}}
- end)
- assert_error(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, #empty:getdefs(upb.DEF_ANY))
-
- 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_symtab_add_extension()
- -- Adding an extension at the same time as the extendee.
- local symtab = upb.SymbolTable{
- upb.MessageDef{full_name = "M1"},
- upb.FieldDef{name = "extension1", is_extension = true, number = 1,
- type = upb.TYPE_INT32, containing_type_name = "M1"}
- }
-
- local m1 = symtab:lookup("M1")
- assert_not_nil(m1)
- assert_equal(1, #m1)
-
- local f1 = m1:field("extension1")
- assert_not_nil(f1)
- assert_true(f1:is_extension())
- assert_true(f1:is_frozen())
- assert_equal(1, f1:number())
-
- -- Adding an extension to an existing extendee.
- symtab:add{
- upb.FieldDef{name = "extension2", is_extension = true, number = 2,
- type = upb.TYPE_INT32, containing_type_name = "M1"}
- }
-
- local m1_2 = symtab:lookup("M1")
- assert_not_nil(m1_2)
- assert_true(m1 ~= m1_2)
- assert_equal(2, #m1_2)
-
- local f2 = m1_2:field("extension2")
- assert_not_nil(f2)
- assert_true(f2:is_extension())
- assert_true(f2:is_frozen())
- assert_equal(2, f2:number())
-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
- function defer(fn)
- setmetatable({}, { __gc = fn })
- end
-else
- function defer(fn)
- getmetatable(newproxy(true)).__gc = fn
- end
-end
-
-function test_finalizer()
- -- Tests that we correctly handle a call into an already-finalized object.
- -- Collectible objects are finalized in the opposite order of creation.
- do
- local t = {}
- defer(function()
- assert_error_match("called into dead def", function()
- -- Generic def call.
- t[1]:full_name()
- end)
- assert_error_match("called into dead msgdef", function()
- -- Specific msgdef call.
- t[1]:add()
- end)
- assert_error_match("called into dead enumdef", function()
- t[2]:values()
- end)
- assert_error_match("called into dead fielddef", function()
- t[3]:number()
- end)
- assert_error_match("called into dead symtab",
- function() t[4]:lookup()
- end)
- end)
- t = {
- upb.MessageDef(),
- upb.EnumDef(),
- upb.FieldDef(),
- upb.SymbolTable(),
- }
- end
- collectgarbage()
-end
-
-local stats = lunit.main()
-
-if stats.failed > 0 or stats.errors > 0 then
- error("One or more errors in test suite")
-end
diff --git a/tests/bindings/lua/upb.lua b/tests/bindings/lua/upb.lua
new file mode 100644
index 0000000..f32a690
--- /dev/null
+++ b/tests/bindings/lua/upb.lua
@@ -0,0 +1,757 @@
+
+local upb = require "upb"
+local lunit = require "lunit"
+
+if _VERSION >= 'Lua 5.2' then
+ _ENV = lunit.module("testupb", "seeall")
+else
+ module("testupb", lunit.testcase, package.seeall)
+end
+
+function iter_to_array(iter)
+ local arr = {}
+ for v in iter do
+ arr[#arr + 1] = v
+ end
+ return arr
+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())
+ 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())
+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_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)
+
+ -- 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)
+
+ -- Freeze the symtab and verify that mutating operations are not allowed.
+ assert_false(symtab:is_frozen())
+ symtab:freeze()
+ assert_true(symtab:is_frozen())
+ assert_error_match("frozen", function() symtab:freeze() end)
+ assert_error_match("frozen", function()
+ symtab:add{
+ upb.MessageDef{full_name = "Foo"}
+ }
+ end)
+end
+
+function test_symtab_add_extension()
+ -- Adding an extension at the same time as the extendee.
+ local symtab = upb.SymbolTable{
+ upb.MessageDef{full_name = "M1"},
+ upb.FieldDef{name = "extension1", is_extension = true, number = 1,
+ type = upb.TYPE_INT32, containing_type_name = "M1"}
+ }
+
+ local m1 = symtab:lookup("M1")
+ assert_not_nil(m1)
+ assert_equal(1, #m1)
+
+ local f1 = m1:field("extension1")
+ assert_not_nil(f1)
+ assert_true(f1:is_extension())
+ assert_true(f1:is_frozen())
+ assert_equal(1, f1:number())
+
+ -- Adding an extension to an existing extendee.
+ symtab:add{
+ upb.FieldDef{name = "extension2", is_extension = true, number = 2,
+ type = upb.TYPE_INT32, containing_type_name = "M1"}
+ }
+
+ local m1_2 = symtab:lookup("M1")
+ assert_not_nil(m1_2)
+ assert_true(m1 ~= m1_2)
+ assert_equal(2, #m1_2)
+
+ local f2 = m1_2:field("extension2")
+ assert_not_nil(f2)
+ assert_true(f2:is_extension())
+ assert_true(f2:is_frozen())
+ assert_equal(2, f2:number())
+end
+
+function test_numeric_array()
+ local function test_for_numeric_type(upb_type, val, too_big, too_small, bad3)
+ local array = upb.Array(upb_type)
+ assert_equal(0, #array)
+
+ -- 0 is never a valid index in Lua.
+ assert_error_match("array index", function() return array[0] end)
+ -- Past the end of the array.
+ assert_error_match("array index", function() return array[1] end)
+
+ array[1] = val
+ assert_equal(val, array[1])
+ assert_equal(1, #array)
+ -- Past the end of the array.
+ assert_error_match("array index", function() return array[2] end)
+
+ array[2] = 10
+ assert_equal(val, array[1])
+ assert_equal(10, array[2])
+ assert_equal(2, #array)
+ -- Past the end of the array.
+ assert_error_match("array index", function() return array[3] end)
+
+ local n = 1
+ for i, val in upb.ipairs(array) do
+ assert_equal(n, i)
+ n = n + 1
+ assert_equal(array[i], val)
+ end
+
+ -- Values that are out of range.
+ local errmsg = "not an integer or out of range"
+ if too_small then
+ assert_error_match(errmsg, function() array[3] = too_small end)
+ end
+ if too_big then
+ assert_error_match(errmsg, function() array[3] = too_big end)
+ end
+ if bad3 then
+ assert_error_match(errmsg, function() array[3] = bad3 end)
+ end
+
+ -- Can't assign other Lua types.
+ errmsg = "bad argument #3"
+ assert_error_match(errmsg, function() array[3] = "abc" end)
+ assert_error_match(errmsg, function() array[3] = true end)
+ assert_error_match(errmsg, function() array[3] = false end)
+ assert_error_match(errmsg, function() array[3] = nil end)
+ assert_error_match(errmsg, function() array[3] = {} end)
+ assert_error_match(errmsg, function() array[3] = print end)
+ assert_error_match(errmsg, function() array[3] = array end)
+ end
+
+ -- in-range of 64-bit types but not exactly representable as double
+ local bad64 = 2^68 - 1
+
+ test_for_numeric_type(upb.TYPE_UINT32, 2^32 - 1, 2^32, -1, 5.1)
+ test_for_numeric_type(upb.TYPE_UINT64, 2^63, 2^64, -1, bad64)
+ test_for_numeric_type(upb.TYPE_INT32, 2^31 - 1, 2^31, -2^31 - 1, 5.1)
+ -- Enums don't exist at a language level in Lua, so we just represent enum
+ -- values as int32s.
+ test_for_numeric_type(upb.TYPE_ENUM, 2^31 - 1, 2^31, -2^31 - 1, 5.1)
+ test_for_numeric_type(upb.TYPE_INT64, 2^62, 2^63, -2^64, bad64)
+ test_for_numeric_type(upb.TYPE_FLOAT, 10^38)
+ test_for_numeric_type(upb.TYPE_DOUBLE, 10^101)
+end
+
+function test_string_array()
+ local function test_for_string_type(upb_type)
+ local array = upb.Array(upb_type)
+ assert_equal(0, #array)
+
+ -- 0 is never a valid index in Lua.
+ assert_error_match("array index", function() return array[0] end)
+ -- Past the end of the array.
+ assert_error_match("array index", function() return array[1] end)
+
+ array[1] = "foo"
+ assert_equal("foo", array[1])
+ assert_equal(1, #array)
+ -- Past the end of the array.
+ assert_error_match("array index", function() return array[2] end)
+
+ local array2 = upb.Array(upb_type)
+ assert_equal(0, #array2)
+
+ array[2] = "bar"
+ assert_equal("foo", array[1])
+ assert_equal("bar", array[2])
+ assert_equal(2, #array)
+ -- Past the end of the array.
+ assert_error_match("array index", function() return array[3] end)
+
+ local n = 1
+ for i, val in upb.ipairs(array) do
+ assert_equal(n, i)
+ n = n + 1
+ assert_equal(array[i], val)
+ end
+ assert_equal(3, n)
+
+ -- Can't assign other Lua types.
+ assert_error_match("Expected string", function() array[3] = 123 end)
+ assert_error_match("Expected string", function() array[3] = true end)
+ assert_error_match("Expected string", function() array[3] = false end)
+ assert_error_match("Expected string", function() array[3] = nil end)
+ assert_error_match("Expected string", function() array[3] = {} end)
+ assert_error_match("Expected string", function() array[3] = print end)
+ assert_error_match("Expected string", function() array[3] = array end)
+ end
+
+ test_for_string_type(upb.TYPE_STRING)
+ test_for_string_type(upb.TYPE_BYTES)
+end
+
+function test_msg_primitives()
+ local function test_for_numeric_type(upb_type, val, too_big, too_small, bad3)
+
+ msg = upb.Message(
+ upb.build_defs{
+ upb.MessageDef{full_name = "TestMessage", fields = {
+ upb.FieldDef{name = "f", number = 1, type = upb_type},
+ }
+ }
+ }
+ )
+
+ -- Defaults to nil
+ assert_nil(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 msgdef = upb.build_defs{
+ upb.MessageDef{full_name = "TestMessage", fields = {
+ upb.FieldDef{name = "i32", number = 1, type = upb.TYPE_INT32},
+ upb.FieldDef{name = "u32", number = 2, type = upb.TYPE_UINT32},
+ upb.FieldDef{name = "i64", number = 3, type = upb.TYPE_INT64},
+ upb.FieldDef{name = "u64", number = 4, type = upb.TYPE_UINT64},
+ upb.FieldDef{name = "dbl", number = 5, type = upb.TYPE_DOUBLE},
+ upb.FieldDef{name = "flt", number = 6, type = upb.TYPE_FLOAT},
+ upb.FieldDef{name = "bool", number = 7, type = upb.TYPE_BOOL},
+ }
+ }
+ }
+
+ msg = upb.Message(msgdef)
+
+ -- Unset member returns nil. This is unlike C++/Java, but is more
+ -- Lua-like behavior.
+ assert_equal(nil, msg.i32)
+ assert_equal(nil, msg.u32)
+ assert_equal(nil, msg.i64)
+ assert_equal(nil, msg.u64)
+ assert_equal(nil, msg.dbl)
+ assert_equal(nil, msg.flt)
+ assert_equal(nil, 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_array()
+ local msgdef = upb.build_defs{
+ upb.MessageDef{full_name = "TestMessage", fields = {
+ upb.FieldDef{name = "i32_array", number = 1, type = upb.TYPE_INT32,
+ label = upb.LABEL_REPEATED},
+ }
+ }
+ }
+
+ msg = upb.Message(msgdef)
+
+ assert_nil(msg.i32_array)
+
+ -- Can't assign a scalar; array is expected.
+ assert_error_match("lupb.array expected", function() msg.i32_array = 5 end)
+
+ -- Can't assign array of the wrong type.
+ local function assign_int64()
+ msg.i32_array = upb.Array(upb.TYPE_INT64)
+ end
+ 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)
+
+ -- 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)
+end
+
+function test_msg_submsg()
+ local test_msgdef, submsg_msgdef = upb.build_defs{
+ upb.MessageDef{full_name = "TestMessage", fields = {
+ upb.FieldDef{name = "submsg", number = 1, type = upb.TYPE_MESSAGE,
+ subdef_name = ".SubMessage"},
+ }
+ },
+ upb.MessageDef{full_name = "SubMessage"}
+ }
+
+ msg = upb.Message(test_msgdef)
+
+ assert_nil(msg.submsg)
+
+ -- Can't assign message of the wrong type.
+ local function assign_int64()
+ msg.submsg = upb.Message(test_msgdef)
+ end
+ assert_error_match("Message type mismatch", assign_int64)
+
+ local sub = upb.Message(submsg_msgdef)
+ msg.submsg = sub
+ assert_equal(sub, msg.submsg)
+
+ -- 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)
+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
+ function defer(fn)
+ setmetatable({}, { __gc = fn })
+ end
+else
+ function defer(fn)
+ getmetatable(newproxy(true)).__gc = fn
+ end
+end
+
+function test_finalizer()
+ -- Tests that we correctly handle a call into an already-finalized object.
+ -- Collectible objects are finalized in the opposite order of creation.
+ do
+ local t = {}
+ defer(function()
+ assert_error_match("called into dead object", function()
+ -- Generic def call.
+ t[1]:full_name()
+ end)
+ assert_error_match("called into dead object", function()
+ -- Specific msgdef call.
+ t[1]:add()
+ end)
+ assert_error_match("called into dead object", function()
+ t[2]:values()
+ end)
+ assert_error_match("called into dead object", function()
+ t[3]:number()
+ end)
+ assert_error_match("called into dead object",
+ function() t[4]:lookup()
+ end)
+ end)
+ t = {
+ upb.MessageDef(),
+ upb.EnumDef(),
+ upb.FieldDef(),
+ upb.SymbolTable(),
+ }
+ end
+ collectgarbage()
+end
+
+local stats = lunit.main()
+
+if stats.failed > 0 or stats.errors > 0 then
+ error("One or more errors in test suite")
+end
diff --git a/tests/bindings/lua/upb.pb.lua b/tests/bindings/lua/upb.pb.lua
new file mode 100644
index 0000000..02b443a
--- /dev/null
+++ b/tests/bindings/lua/upb.pb.lua
@@ -0,0 +1,70 @@
+
+local upb = require "upb"
+local pb = require "upb.pb"
+local lunit = require "lunit"
+
+if _VERSION >= 'Lua 5.2' then
+ _ENV = lunit.module("testupb_pb", "seeall")
+else
+ module("testupb_pb", lunit.testcase, package.seeall)
+end
+
+local primitive_types_msg = upb.build_defs{
+ upb.MessageDef{full_name = "TestMessage", fields = {
+ upb.FieldDef{name = "i32", number = 1, type = upb.TYPE_INT32},
+ upb.FieldDef{name = "u32", number = 2, type = upb.TYPE_UINT32},
+ upb.FieldDef{name = "i64", number = 3, type = upb.TYPE_INT64},
+ upb.FieldDef{name = "u64", number = 4, type = upb.TYPE_UINT64},
+ upb.FieldDef{name = "dbl", number = 5, type = upb.TYPE_DOUBLE},
+ upb.FieldDef{name = "flt", number = 6, type = upb.TYPE_FLOAT},
+ upb.FieldDef{name = "bool", number = 7, type = upb.TYPE_BOOL},
+ }
+ }
+}
+
+function test_decodermethod()
+ local dm = pb.DecoderMethod(primitive_types_msg)
+
+ assert_error(
+ function()
+ -- Needs at least one argument to construct.
+ pb.DecoderMethod()
+ end)
+end
+
+function test_parse_primitive()
+ local binary_pb =
+ "\008\128\128\128\128\002\016\128\128\128\128\004\024\128\128"
+ .. "\128\128\128\128\128\002\032\128\128\128\128\128\128\128\001\041\000"
+ .. "\000\000\000\000\000\248\063\053\000\000\096\064\056\001"
+ local dm = pb.DecoderMethod(primitive_types_msg)
+ msg = dm:parse(binary_pb)
+ assert_equal(536870912, msg.i32)
+ assert_equal(1073741824, msg.u32)
+ assert_equal(1125899906842624, msg.i64)
+ assert_equal(562949953421312, msg.u64)
+ assert_equal(1.5, msg.dbl)
+ assert_equal(3.5, msg.flt)
+ assert_equal(true, msg.bool)
+end
+
+function test_parse_string()
+ local msgdef = upb.build_defs{
+ upb.MessageDef{full_name = "TestMessage", fields = {
+ upb.FieldDef{name = "str", number = 1, type = upb.TYPE_STRING},
+ }
+ }
+ }
+
+ local binary_pb = "\010\005Hello"
+ local dm = pb.DecoderMethod(msgdef)
+ msg = dm:parse(binary_pb)
+ assert_equal("Hello", msg.str)
+end
+
+
+local stats = lunit.main()
+
+if stats.failed > 0 or stats.errors > 0 then
+ error("One or more errors in test suite")
+end
diff --git a/tests/pb/test_decoder.cc b/tests/pb/test_decoder.cc
index 1660436..e016632 100644
--- a/tests/pb/test_decoder.cc
+++ b/tests/pb/test_decoder.cc
@@ -297,7 +297,7 @@ template<class T, bool F(int*, const uint32_t*, T)>
void doreg(upb_handlers *h, uint32_t num) {
const upb_fielddef *f = upb_msgdef_itof(upb_handlers_msgdef(h), num);
ASSERT(f);
- ASSERT(h->SetValueHandler<T>(f, UpbBindT(&F, new uint32_t(num))));
+ ASSERT(h->SetValueHandler<T>(f, UpbBindT(F, new uint32_t(num))));
if (f->IsSequence()) {
ASSERT(h->SetStartSequenceHandler(f, UpbBind(startseq, new uint32_t(num))));
ASSERT(h->SetEndSequenceHandler(f, UpbBind(endseq, new uint32_t(num))));
@@ -488,8 +488,22 @@ uint32_t Hash(const string& proto, const string* expected_output, size_t seam1,
return hash;
}
-bool parse(upb::BytesSink* s, void* subc, const char* buf, size_t start,
- size_t end, size_t* ofs, upb::Status* status) {
+void CheckBytesParsed(const upb::pb::Decoder& decoder, size_t ofs) {
+ // We could have parsed as many as 10 bytes fewer than what the decoder
+ // previously accepted, since we can buffer up to 10 partial bytes internally
+ // before accumulating an entire value.
+ const int MAX_BUFFERED = 10;
+
+ // We can't have parsed more data than the decoder callback is telling us it
+ // parsed.
+ ASSERT(decoder.BytesParsed() <= ofs);
+ ASSERT(ofs <= (decoder.BytesParsed() + MAX_BUFFERED));
+}
+
+bool parse(upb::pb::Decoder* decoder, void* subc, const char* buf,
+ size_t start, size_t end, size_t* ofs, upb::Status* status) {
+ CheckBytesParsed(*decoder, *ofs);
+ upb::BytesSink* s = decoder->input();
start = UPB_MAX(start, *ofs);
if (start <= end) {
size_t len = end - start;
@@ -532,6 +546,7 @@ bool parse(upb::BytesSink* s, void* subc, const char* buf, size_t start,
if (!status->ok())
return false;
*ofs += parsed;
+ CheckBytesParsed(*decoder, *ofs);
}
return true;
}
@@ -569,12 +584,12 @@ void run_decoder(const string& proto, const string* expected_output) {
fprintf(stderr, "Calling start()\n");
}
- bool ok =
- input->Start(proto.size(), &sub) &&
- parse(input, sub, proto.c_str(), 0, i, &ofs, &status) &&
- parse(input, sub, proto.c_str(), i, j, &ofs, &status) &&
- parse(input, sub, proto.c_str(), j, proto.size(), &ofs, &status) &&
- ofs == proto.size();
+ bool ok = input->Start(proto.size(), &sub) &&
+ parse(&decoder, sub, proto.c_str(), 0, i, &ofs, &status) &&
+ parse(&decoder, sub, proto.c_str(), i, j, &ofs, &status) &&
+ parse(&decoder, sub, proto.c_str(), j, proto.size(), &ofs,
+ &status) &&
+ ofs == proto.size();
if (ok) {
if (filter_hash) {
@@ -940,6 +955,22 @@ void test_valid() {
LINE("%u:1")
LINE(">"), UPB_DESCRIPTOR_TYPE_INT32);
+ // String inside submsg.
+ uint32_t msg_fn = UPB_DESCRIPTOR_TYPE_MESSAGE;
+ assert_successful_parse(
+ submsg(msg_fn,
+ cat ( tag(UPB_DESCRIPTOR_TYPE_STRING, UPB_WIRE_TYPE_DELIMITED),
+ delim(string("abcde"))
+ )
+ ),
+ LINE("<")
+ LINE("%u:{")
+ LINE(" <")
+ LINE(" %u:(5)\"abcde\"")
+ LINE(" >")
+ LINE("}")
+ LINE(">"), msg_fn, UPB_DESCRIPTOR_TYPE_STRING);
+
// Test implicit startseq/endseq.
uint32_t repfl_fn = rep_fn(UPB_DESCRIPTOR_TYPE_FLOAT);
uint32_t repdb_fn = rep_fn(UPB_DESCRIPTOR_TYPE_DOUBLE);
@@ -956,7 +987,6 @@ void test_valid() {
LINE(">"), repfl_fn, repfl_fn, repdb_fn, repdb_fn);
// Submessage tests.
- uint32_t msg_fn = UPB_DESCRIPTOR_TYPE_MESSAGE;
assert_successful_parse(
submsg(msg_fn, submsg(msg_fn, submsg(msg_fn, string()))),
LINE("<")
diff --git a/tests/test_cpp.cc b/tests/test_cpp.cc
index 60d6527..fe0695f 100644
--- a/tests/test_cpp.cc
+++ b/tests/test_cpp.cc
@@ -153,6 +153,9 @@ static void TestSymbolTable(const char *descriptor_file) {
std::cerr << "Couldn't load descriptor: " << status.error_message();
exit(1);
}
+ ASSERT(!s->IsFrozen());
+ s->Freeze();
+ ASSERT(s->IsFrozen());
upb::reffed_ptr<const upb::MessageDef> md(s->LookupMessage("C"));
ASSERT(md.get());
@@ -1038,6 +1041,39 @@ void TestMismatchedTypes() {
// match top-level closure of sub-handlers.
}
+class IntIncrementer {
+ public:
+ IntIncrementer(int* x) : x_(x) { (*x_)++; }
+ ~IntIncrementer() { (*x_)--; }
+
+ static void Handler(void* closure, const IntIncrementer* incrementer,
+ int32_t x) {}
+
+ private:
+ int* x_;
+};
+
+
+void TestHandlerDataDestruction() {
+ upb::reffed_ptr<upb::MessageDef> md(upb::MessageDef::New());
+ upb::reffed_ptr<upb::FieldDef> f(upb::FieldDef::New());
+ f->set_type(UPB_TYPE_INT32);
+ ASSERT(f->set_name("test", NULL));
+ ASSERT(f->set_number(1, NULL));
+ ASSERT(md->AddField(f, NULL));
+ ASSERT(md->Freeze(NULL));
+
+ int x = 0;
+ {
+ upb::reffed_ptr<upb::Handlers> h(upb::Handlers::New(md.get()));
+ h->SetInt32Handler(
+ f.get(), UpbBind(&IntIncrementer::Handler, new IntIncrementer(&x)));
+ ASSERT(x == 1);
+ }
+
+ ASSERT(x == 0);
+}
+
extern "C" {
int run_tests(int argc, char *argv[]) {
@@ -1091,6 +1127,8 @@ int run_tests(int argc, char *argv[]) {
TestMismatchedTypes();
+ TestHandlerDataDestruction();
+
#ifdef UPB_CXX11
#define ASSERT_STD_LAYOUT(type) \
static_assert(std::is_standard_layout<type>::value, \
diff --git a/tests/test_def.c b/tests/test_def.c
index bf45a73..7efd2b0 100644
--- a/tests/test_def.c
+++ b/tests/test_def.c
@@ -17,10 +17,11 @@ const char *descriptor_file;
static void test_empty_symtab() {
upb_symtab *s = upb_symtab_new(&s);
- int count;
- const upb_def **defs = upb_symtab_getdefs(s, UPB_DEF_ANY, NULL, &count);
- ASSERT(count == 0);
- free(defs);
+ upb_symtab_iter i;
+ for (upb_symtab_begin(&i, s, UPB_DEF_ANY); !upb_symtab_done(&i);
+ upb_symtab_next(&i)) {
+ ASSERT(false); // Should not get here.
+ }
upb_symtab_unref(s, &s);
}
@@ -33,6 +34,9 @@ static upb_symtab *load_test_proto(void *owner) {
upb_status_errmsg(&status));
ASSERT(false);
}
+ ASSERT(!upb_symtab_isfrozen(s));
+ upb_symtab_freeze(s);
+ ASSERT(upb_symtab_isfrozen(s));
return s;
}
@@ -41,7 +45,8 @@ static void test_cycles() {
// Test cycle detection by making a cyclic def's main refcount go to zero
// and then be incremented to one again.
- const upb_def *def = upb_symtab_lookup(s, "A", &def);
+ const upb_def *def = upb_symtab_lookup(s, "A");
+ upb_def_ref(def, &def);
ASSERT(def);
ASSERT(upb_def_isfrozen(def));
upb_symtab_unref(s, &s);
@@ -65,14 +70,12 @@ static void test_cycles() {
static void test_fielddef_unref() {
upb_symtab *s = load_test_proto(&s);
- const upb_msgdef *md = upb_symtab_lookupmsg(s, "A", &md);
+ const upb_msgdef *md = upb_symtab_lookupmsg(s, "A");
const upb_fielddef *f = upb_msgdef_itof(md, 1);
upb_fielddef_ref(f, &f);
- // Unref symtab and msgdef; now fielddef is the only thing keeping the msgdef
- // alive.
+ // Unref symtab; now fielddef is the only thing keeping the msgdef alive.
upb_symtab_unref(s, &s);
- upb_msgdef_unref(md, &md);
// Check that md is still alive.
ASSERT(strcmp(upb_msgdef_fullname(md), "A") == 0);
@@ -141,29 +144,28 @@ static void test_replacement() {
&s, NULL);
upb_msgdef *m2 = upb_msgdef_newnamed("MyMessage2", &s);
upb_enumdef *e = upb_enumdef_newnamed("MyEnum", &s);
+ upb_status status = UPB_STATUS_INIT;
+ ASSERT_STATUS(upb_enumdef_addval(e, "VAL1", 1, &status), &status);
upb_def *newdefs[] = {UPB_UPCAST(m), UPB_UPCAST(m2), UPB_UPCAST(e)};
- upb_status status = UPB_STATUS_INIT;
ASSERT_STATUS(upb_symtab_add(s, newdefs, 3, &s, &status), &status);
// Try adding a new definition of MyEnum, MyMessage should get replaced with
// a new version.
- upb_enumdef *e2 = upb_enumdef_new(&s);
- upb_enumdef_setfullname(e2, "MyEnum", NULL);
+ upb_enumdef *e2 = upb_enumdef_newnamed("MyEnum", &s);
+ ASSERT_STATUS(upb_enumdef_addval(e2, "VAL1", 1, &status), &status);
upb_def *newdefs2[] = {UPB_UPCAST(e2)};
ASSERT_STATUS(upb_symtab_add(s, newdefs2, 1, &s, &status), &status);
- const upb_msgdef *m3 = upb_symtab_lookupmsg(s, "MyMessage", &m3);
+ const upb_msgdef *m3 = upb_symtab_lookupmsg(s, "MyMessage");
ASSERT(m3);
// Must be different because it points to MyEnum which was replaced.
ASSERT(m3 != m);
- upb_msgdef_unref(m3, &m3);
- m3 = upb_symtab_lookupmsg(s, "MyMessage2", &m3);
+ m3 = upb_symtab_lookupmsg(s, "MyMessage2");
// Should be the same because it was not replaced, nor were any defs that
// are reachable from it.
ASSERT(m3 == m2);
- upb_msgdef_unref(m3, &m3);
upb_symtab_unref(s, &s);
}
diff --git a/tests/test_handlers.c b/tests/test_handlers.c
index df22b8a..ad59465 100644
--- a/tests/test_handlers.c
+++ b/tests/test_handlers.c
@@ -18,7 +18,10 @@ static bool startmsg(void *c, const void *hd) {
}
static void test_error() {
- upb_handlers *h = upb_handlers_new(GOOGLE_PROTOBUF_DESCRIPTORPROTO, &h);
+ const upb_symtab *s = upbdefs_google_protobuf_descriptor(&s);
+ upb_handlers *h =
+ upb_handlers_new(upbdefs_google_protobuf_DescriptorProto(s), &h);
+ upb_symtab_unref(s, &s);
// Attempt to set the same handler twice causes error.
ASSERT(upb_ok(upb_handlers_status(h)));
diff --git a/tests/test_table.cc b/tests/test_table.cc
index 747a97b..2d08abb 100644
--- a/tests/test_table.cc
+++ b/tests/test_table.cc
@@ -69,6 +69,25 @@ void test_strtable(const vector<std::string>& keys, uint32_t num_to_insert) {
}
ASSERT(all.empty());
+ // Test iteration with resizes.
+
+ for (int i = 0; i < 10; i++) {
+ for(upb_strtable_begin(&iter, &table); !upb_strtable_done(&iter);
+ upb_strtable_next(&iter)) {
+ // Even if we invalidate the iterator it should only return real elements.
+ const char *key = upb_strtable_iter_key(&iter);
+ std::string tmp(key, strlen(key));
+ ASSERT(upb_value_getint32(upb_strtable_iter_value(&iter)) == m[tmp]);
+
+ // Force a resize even though the size isn't changing.
+ // Also forces the table size to grow so some new buckets end up empty.
+ int new_lg2 = table.t.size_lg2 + 1;
+ // Don't use more than 64k tables, to avoid exhausting memory.
+ new_lg2 = UPB_MIN(new_lg2, 16);
+ upb_strtable_resize(&table, new_lg2);
+ }
+ }
+
upb_strtable_uninit(&table);
}
@@ -292,7 +311,9 @@ int run_tests(int argc, char *argv[]) {
keys.push_back("google.protobuf.UninterpretedOption");
keys.push_back("google.protobuf.UninterpretedOption.NamePart");
- test_strtable(keys, 18);
+ for (int i = 0; i < 10; i++) {
+ test_strtable(keys, 18);
+ }
int32_t *keys1 = get_contiguous_keys(8);
test_inttable(keys1, 8, "Table size: 8, keys: 1-8 ====");
diff --git a/tests/test_vs_proto2.cc b/tests/test_vs_proto2.cc
index dd20381..ed44a73 100644
--- a/tests/test_vs_proto2.cc
+++ b/tests/test_vs_proto2.cc
@@ -129,7 +129,8 @@ int run_tests(int argc, char *argv[])
MESSAGE_CIDENT msg1;
MESSAGE_CIDENT msg2;
- upb::reffed_ptr<const upb::Handlers> h(upb::googlepb::NewWriteHandlers(msg1));
+ upb::reffed_ptr<const upb::Handlers> h(
+ upb::googlepb::WriteHandlers::New(msg1));
compare_metadata(msg1.GetDescriptor(), h->message_def());
@@ -146,7 +147,7 @@ int run_tests(int argc, char *argv[])
factory->GetPrototype(msg1.descriptor());
google::protobuf::Message* dyn_msg1 = prototype->New();
google::protobuf::Message* dyn_msg2 = prototype->New();
- h = upb::googlepb::NewWriteHandlers(*dyn_msg1);
+ h = upb::googlepb::WriteHandlers::New(*dyn_msg1);
parse_and_compare(dyn_msg1, dyn_msg2, h.get(), str, len, false);
parse_and_compare(dyn_msg1, dyn_msg2, h.get(), str, len, true);
delete dyn_msg1;
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback