summaryrefslogtreecommitdiff
path: root/tests/bindings/lua/test.lua
diff options
context:
space:
mode:
Diffstat (limited to 'tests/bindings/lua/test.lua')
-rw-r--r--tests/bindings/lua/test.lua303
1 files changed, 303 insertions, 0 deletions
diff --git a/tests/bindings/lua/test.lua b/tests/bindings/lua/test.lua
new file mode 100644
index 0000000..99f58f2
--- /dev/null
+++ b/tests/bindings/lua/test.lua
@@ -0,0 +1,303 @@
+
+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
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback