From 66a74a4fd53710aaf54a01f668d6a895f9266fbd Mon Sep 17 00:00:00 2001 From: Josh Haberman Date: Mon, 1 Sep 2014 15:34:14 -0700 Subject: Added lua and core32 Travis builds, and rewrote README.md --- tests/bindings/lua/upb.lua | 757 --------------------------------------------- 1 file changed, 757 deletions(-) delete mode 100644 tests/bindings/lua/upb.lua (limited to 'tests/bindings/lua/upb.lua') diff --git a/tests/bindings/lua/upb.lua b/tests/bindings/lua/upb.lua deleted file mode 100644 index f32a690..0000000 --- a/tests/bindings/lua/upb.lua +++ /dev/null @@ -1,757 +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 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 -- cgit v1.2.3