summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/bindings/lua/LICENSE32
-rw-r--r--tests/bindings/lua/lunit/console.lua156
-rw-r--r--tests/bindings/lua/lunit/lunit.lua725
-rw-r--r--tests/bindings/lua/test.lua303
-rw-r--r--tests/pb/test_decoder.cc (renamed from tests/test_decoder.cc)11
-rw-r--r--tests/pb/test_decoder_schema.proto (renamed from tests/test_decoder_schema.proto)0
-rw-r--r--tests/pb/test_varint.c (renamed from tests/test_varint.c)2
-rw-r--r--tests/test_cpp.cc448
-rw-r--r--tests/test_def.c4
-rw-r--r--tests/test_vs_proto2.cc6
10 files changed, 1619 insertions, 68 deletions
diff --git a/tests/bindings/lua/LICENSE b/tests/bindings/lua/LICENSE
new file mode 100644
index 0000000..fb720fe
--- /dev/null
+++ b/tests/bindings/lua/LICENSE
@@ -0,0 +1,32 @@
+
+Lunit License
+-------------
+
+Lunit is written by Michael Roth <mroth@nessie.de> and is licensed
+under the terms of the MIT license reproduced below.
+
+========================================================================
+
+Copyright (c) 2004-2010 Michael Roth <mroth@nessie.de>
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge,
+publish, distribute, sublicense, and/or sell copies of the Software,
+and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+========================================================================
+
diff --git a/tests/bindings/lua/lunit/console.lua b/tests/bindings/lua/lunit/console.lua
new file mode 100644
index 0000000..0ff22a4
--- /dev/null
+++ b/tests/bindings/lua/lunit/console.lua
@@ -0,0 +1,156 @@
+
+--[[--------------------------------------------------------------------------
+
+ This file is part of lunit 0.5.
+
+ For Details about lunit look at: http://www.mroth.net/lunit/
+
+ Author: Michael Roth <mroth@nessie.de>
+
+ Copyright (c) 2006-2008 Michael Roth <mroth@nessie.de>
+
+ Permission is hereby granted, free of charge, to any person
+ obtaining a copy of this software and associated documentation
+ files (the "Software"), to deal in the Software without restriction,
+ including without limitation the rights to use, copy, modify, merge,
+ publish, distribute, sublicense, and/or sell copies of the Software,
+ and to permit persons to whom the Software is furnished to do so,
+ subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+--]]--------------------------------------------------------------------------
+
+
+
+--[[
+
+ begin()
+ run(testcasename, testname)
+ err(fullname, message, traceback)
+ fail(fullname, where, message, usermessage)
+ pass(testcasename, testname)
+ done()
+
+ Fullname:
+ testcase.testname
+ testcase.testname:setupname
+ testcase.testname:teardownname
+
+--]]
+
+
+lunit = require "lunit"
+
+local lunit_console
+
+if _VERSION >= 'Lua 5.2' then
+
+ lunit_console = setmetatable({},{__index = _ENV})
+ _ENV = lunit_console
+
+else
+
+ module( "lunit-console", package.seeall )
+ lunit_console = _M
+
+end
+
+
+
+local function printformat(format, ...)
+ io.write( string.format(format, ...) )
+end
+
+
+local columns_printed = 0
+
+local function writestatus(char)
+ if columns_printed == 0 then
+ io.write(" ")
+ end
+ if columns_printed == 60 then
+ io.write("\n ")
+ columns_printed = 0
+ end
+ io.write(char)
+ io.flush()
+ columns_printed = columns_printed + 1
+end
+
+
+local msgs = {}
+
+
+function begin()
+ local total_tc = 0
+ local total_tests = 0
+
+ msgs = {} -- e
+
+ for tcname in lunit.testcases() do
+ total_tc = total_tc + 1
+ for testname, test in lunit.tests(tcname) do
+ total_tests = total_tests + 1
+ end
+ end
+
+ printformat("Loaded testsuite with %d tests in %d testcases.\n\n", total_tests, total_tc)
+end
+
+
+function run(testcasename, testname)
+ -- NOP
+end
+
+
+function err(fullname, message, traceback)
+ writestatus("E")
+ msgs[#msgs+1] = "Error! ("..fullname.."):\n"..message.."\n\t"..table.concat(traceback, "\n\t") .. "\n"
+end
+
+
+function fail(fullname, where, message, usermessage)
+ writestatus("F")
+ local text = "Failure ("..fullname.."):\n"..
+ where..": "..message.."\n"
+
+ if usermessage then
+ text = text .. where..": "..usermessage.."\n"
+ end
+
+ msgs[#msgs+1] = text
+end
+
+
+function pass(testcasename, testname)
+ writestatus(".")
+end
+
+
+
+function done()
+ printformat("\n\n%d Assertions checked.\n", lunit.stats.assertions )
+ print()
+
+ for i, msg in ipairs(msgs) do
+ printformat( "%3d) %s\n", i, msg )
+ end
+
+ printformat("Testsuite finished (%d passed, %d failed, %d errors).\n",
+ lunit.stats.passed, lunit.stats.failed, lunit.stats.errors )
+end
+
+
+return lunit_console
+
+
diff --git a/tests/bindings/lua/lunit/lunit.lua b/tests/bindings/lua/lunit/lunit.lua
new file mode 100644
index 0000000..80f43c1
--- /dev/null
+++ b/tests/bindings/lua/lunit/lunit.lua
@@ -0,0 +1,725 @@
+--[[--------------------------------------------------------------------------
+
+ This file is part of lunit 0.5.
+
+ For Details about lunit look at: http://www.mroth.net/lunit/
+
+ Author: Michael Roth <mroth@nessie.de>
+
+ Copyright (c) 2004, 2006-2010 Michael Roth <mroth@nessie.de>
+
+ Permission is hereby granted, free of charge, to any person
+ obtaining a copy of this software and associated documentation
+ files (the "Software"), to deal in the Software without restriction,
+ including without limitation the rights to use, copy, modify, merge,
+ publish, distribute, sublicense, and/or sell copies of the Software,
+ and to permit persons to whom the Software is furnished to do so,
+ subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+--]]--------------------------------------------------------------------------
+
+
+local orig_assert = assert
+
+local pairs = pairs
+local ipairs = ipairs
+local next = next
+local type = type
+local error = error
+local tostring = tostring
+local setmetatable = setmetatable
+local pcall = pcall
+local xpcall = xpcall
+local require = require
+local loadfile = loadfile
+
+local string_sub = string.sub
+local string_gsub = string.gsub
+local string_format = string.format
+local string_lower = string.lower
+local string_find = string.find
+
+local table_concat = table.concat
+
+local debug_getinfo = debug.getinfo
+
+local _G = _G
+
+local lunit
+
+if _VERSION >= 'Lua 5.2' then
+
+ lunit = {}
+ _ENV = lunit
+
+else
+
+ module("lunit")
+ lunit = _M
+
+end
+
+
+local __failure__ = {} -- Type tag for failed assertions
+
+local typenames = { "nil", "boolean", "number", "string", "table", "function", "thread", "userdata" }
+
+
+local traceback_hide -- Traceback function which hides lunit internals
+local mypcall -- Protected call to a function with own traceback
+do
+ local _tb_hide = setmetatable( {}, {__mode="k"} )
+
+ function traceback_hide(func)
+ _tb_hide[func] = true
+ end
+
+ local function my_traceback(errobj)
+ if is_table(errobj) and errobj.type == __failure__ then
+ local info = debug_getinfo(5, "Sl") -- FIXME: Hardcoded integers are bad...
+ errobj.where = string_format( "%s:%d", info.short_src, info.currentline)
+ else
+ errobj = { msg = tostring(errobj) }
+ errobj.tb = {}
+ local i = 2
+ while true do
+ local info = debug_getinfo(i, "Snlf")
+ if not is_table(info) then
+ break
+ end
+ if not _tb_hide[info.func] then
+ local line = {} -- Ripped from ldblib.c...
+ line[#line+1] = string_format("%s:", info.short_src)
+ if info.currentline > 0 then
+ line[#line+1] = string_format("%d:", info.currentline)
+ end
+ if info.namewhat ~= "" then
+ line[#line+1] = string_format(" in function '%s'", info.name)
+ else
+ if info.what == "main" then
+ line[#line+1] = " in main chunk"
+ elseif info.what == "C" or info.what == "tail" then
+ line[#line+1] = " ?"
+ else
+ line[#line+1] = string_format(" in function <%s:%d>", info.short_src, info.linedefined)
+ end
+ end
+ errobj.tb[#errobj.tb+1] = table_concat(line)
+ end
+ i = i + 1
+ end
+ end
+ return errobj
+ end
+
+ function mypcall(func)
+ orig_assert( is_function(func) )
+ local ok, errobj = xpcall(func, my_traceback)
+ if not ok then
+ return errobj
+ end
+ end
+ traceback_hide(mypcall)
+end
+
+
+-- Type check functions
+
+for _, typename in ipairs(typenames) do
+ lunit["is_"..typename] = function(x)
+ return type(x) == typename
+ end
+end
+
+local is_nil = is_nil
+local is_boolean = is_boolean
+local is_number = is_number
+local is_string = is_string
+local is_table = is_table
+local is_function = is_function
+local is_thread = is_thread
+local is_userdata = is_userdata
+
+
+local function failure(name, usermsg, defaultmsg, ...)
+ local errobj = {
+ type = __failure__,
+ name = name,
+ msg = string_format(defaultmsg,...),
+ usermsg = usermsg
+ }
+ error(errobj, 0)
+end
+traceback_hide( failure )
+
+
+local function format_arg(arg)
+ local argtype = type(arg)
+ if argtype == "string" then
+ return "'"..arg.."'"
+ elseif argtype == "number" or argtype == "boolean" or argtype == "nil" then
+ return tostring(arg)
+ else
+ return "["..tostring(arg).."]"
+ end
+end
+
+
+local function selected(map, name)
+ if not map then
+ return true
+ end
+
+ local m = {}
+ for k,v in pairs(map) do
+ m[k] = lunitpat2luapat(v)
+ end
+ return in_patternmap(m, name)
+end
+
+
+function fail(msg)
+ stats.assertions = stats.assertions + 1
+ failure( "fail", msg, "failure" )
+end
+traceback_hide( fail )
+
+
+function assert(assertion, msg)
+ stats.assertions = stats.assertions + 1
+ if not assertion then
+ failure( "assert", msg, "assertion failed" )
+ end
+ return assertion
+end
+traceback_hide( assert )
+
+
+function assert_true(actual, msg)
+ stats.assertions = stats.assertions + 1
+ if actual ~= true then
+ failure( "assert_true", msg, "true expected but was %s", format_arg(actual) )
+ end
+ return actual
+end
+traceback_hide( assert_true )
+
+
+function assert_false(actual, msg)
+ stats.assertions = stats.assertions + 1
+ if actual ~= false then
+ failure( "assert_false", msg, "false expected but was %s", format_arg(actual) )
+ end
+ return actual
+end
+traceback_hide( assert_false )
+
+
+function assert_equal(expected, actual, msg)
+ stats.assertions = stats.assertions + 1
+ if expected ~= actual then
+ failure( "assert_equal", msg, "expected %s but was %s", format_arg(expected), format_arg(actual) )
+ end
+ return actual
+end
+traceback_hide( assert_equal )
+
+
+function assert_not_equal(unexpected, actual, msg)
+ stats.assertions = stats.assertions + 1
+ if unexpected == actual then
+ failure( "assert_not_equal", msg, "%s not expected but was one", format_arg(unexpected) )
+ end
+ return actual
+end
+traceback_hide( assert_not_equal )
+
+
+function assert_match(pattern, actual, msg)
+ stats.assertions = stats.assertions + 1
+ if type(pattern) ~= "string" then
+ failure( "assert_match", msg, "expected a string as pattern but was %s", format_arg(pattern) )
+ end
+ if type(actual) ~= "string" then
+ failure( "assert_match", msg, "expected a string to match pattern '%s' but was a %s", pattern, format_arg(actual) )
+ end
+ if not string_find(actual, pattern) then
+ failure( "assert_match", msg, "expected '%s' to match pattern '%s' but doesn't", actual, pattern )
+ end
+ return actual
+end
+traceback_hide( assert_match )
+
+
+function assert_not_match(pattern, actual, msg)
+ stats.assertions = stats.assertions + 1
+ if type(pattern) ~= "string" then
+ failure( "assert_not_match", msg, "expected a string as pattern but was %s", format_arg(pattern) )
+ end
+ if type(actual) ~= "string" then
+ failure( "assert_not_match", msg, "expected a string to not match pattern '%s' but was %s", pattern, format_arg(actual) )
+ end
+ if string_find(actual, pattern) then
+ failure( "assert_not_match", msg, "expected '%s' to not match pattern '%s' but it does", actual, pattern )
+ end
+ return actual
+end
+traceback_hide( assert_not_match )
+
+
+function assert_error(msg, func)
+ stats.assertions = stats.assertions + 1
+ if func == nil then
+ func, msg = msg, nil
+ end
+ if type(func) ~= "function" then
+ failure( "assert_error", msg, "expected a function as last argument but was %s", format_arg(func) )
+ end
+ local ok, errmsg = pcall(func)
+ if ok then
+ failure( "assert_error", msg, "error expected but no error occurred" )
+ end
+end
+traceback_hide( assert_error )
+
+
+function assert_error_match(msg, pattern, func)
+ stats.assertions = stats.assertions + 1
+ if func == nil then
+ msg, pattern, func = nil, msg, pattern
+ end
+ if type(pattern) ~= "string" then
+ failure( "assert_error_match", msg, "expected the pattern as a string but was %s", format_arg(pattern) )
+ end
+ if type(func) ~= "function" then
+ failure( "assert_error_match", msg, "expected a function as last argument but was %s", format_arg(func) )
+ end
+ local ok, errmsg = pcall(func)
+ if ok then
+ failure( "assert_error_match", msg, "error expected but no error occurred" )
+ end
+ if type(errmsg) ~= "string" then
+ failure( "assert_error_match", msg, "error as string expected but was %s", format_arg(errmsg) )
+ end
+ if not string_find(errmsg, pattern) then
+ failure( "assert_error_match", msg, "expected error '%s' to match pattern '%s' but doesn't", errmsg, pattern )
+ end
+end
+traceback_hide( assert_error_match )
+
+
+function assert_pass(msg, func)
+ stats.assertions = stats.assertions + 1
+ if func == nil then
+ func, msg = msg, nil
+ end
+ if type(func) ~= "function" then
+ failure( "assert_pass", msg, "expected a function as last argument but was %s", format_arg(func) )
+ end
+ local ok, errmsg = pcall(func)
+ if not ok then
+ failure( "assert_pass", msg, "no error expected but error was: '%s'", errmsg )
+ end
+end
+traceback_hide( assert_pass )
+
+
+-- lunit.assert_typename functions
+
+for _, typename in ipairs(typenames) do
+ local assert_typename = "assert_"..typename
+ lunit[assert_typename] = function(actual, msg)
+ stats.assertions = stats.assertions + 1
+ if type(actual) ~= typename then
+ failure( assert_typename, msg, "%s expected but was %s", typename, format_arg(actual) )
+ end
+ return actual
+ end
+ traceback_hide( lunit[assert_typename] )
+end
+
+
+-- lunit.assert_not_typename functions
+
+for _, typename in ipairs(typenames) do
+ local assert_not_typename = "assert_not_"..typename
+ lunit[assert_not_typename] = function(actual, msg)
+ stats.assertions = stats.assertions + 1
+ if type(actual) == typename then
+ failure( assert_not_typename, msg, typename.." not expected but was one" )
+ end
+ end
+ traceback_hide( lunit[assert_not_typename] )
+end
+
+
+function lunit.clearstats()
+ stats = {
+ assertions = 0;
+ passed = 0;
+ failed = 0;
+ errors = 0;
+ }
+end
+
+
+local report, reporterrobj
+do
+ local testrunner
+
+ function lunit.setrunner(newrunner)
+ if not ( is_table(newrunner) or is_nil(newrunner) ) then
+ return error("lunit.setrunner: Invalid argument", 0)
+ end
+ local oldrunner = testrunner
+ testrunner = newrunner
+ return oldrunner
+ end
+
+ function lunit.loadrunner(name)
+ if not is_string(name) then
+ return error("lunit.loadrunner: Invalid argument", 0)
+ end
+ local ok, runner = pcall( require, name )
+ if not ok then
+ return error("lunit.loadrunner: Can't load test runner: "..runner, 0)
+ end
+ return setrunner(runner)
+ end
+
+ function lunit.getrunner()
+ return testrunner
+ end
+
+ function report(event, ...)
+ local f = testrunner and testrunner[event]
+ if is_function(f) then
+ pcall(f, ...)
+ end
+ end
+
+ function reporterrobj(context, tcname, testname, errobj)
+ local fullname = tcname .. "." .. testname
+ if context == "setup" then
+ fullname = fullname .. ":" .. setupname(tcname, testname)
+ elseif context == "teardown" then
+ fullname = fullname .. ":" .. teardownname(tcname, testname)
+ end
+ if errobj.type == __failure__ then
+ stats.failed = stats.failed + 1
+ report("fail", fullname, errobj.where, errobj.msg, errobj.usermsg)
+ else
+ stats.errors = stats.errors + 1
+ report("err", fullname, errobj.msg, errobj.tb)
+ end
+ end
+end
+
+
+
+local function key_iter(t, k)
+ return (next(t,k))
+end
+
+
+local testcase
+do
+ -- Array with all registered testcases
+ local _testcases = {}
+
+ -- Marks a module as a testcase.
+ -- Applied over a module from module("xyz", lunit.testcase).
+ function lunit.testcase(m)
+ orig_assert( is_table(m) )
+ --orig_assert( m._M == m )
+ orig_assert( is_string(m._NAME) )
+ --orig_assert( is_string(m._PACKAGE) )
+
+ -- Register the module as a testcase
+ _testcases[m._NAME] = m
+
+ -- Import lunit, fail, assert* and is_* function to the module/testcase
+ m.lunit = lunit
+ m.fail = lunit.fail
+ for funcname, func in pairs(lunit) do
+ if "assert" == string_sub(funcname, 1, 6) or "is_" == string_sub(funcname, 1, 3) then
+ m[funcname] = func
+ end
+ end
+ end
+
+ function lunit.module(name,seeall)
+ local m = {}
+ if seeall == "seeall" then
+ setmetatable(m, { __index = _G })
+ end
+ m._NAME = name
+ lunit.testcase(m)
+ return m
+ end
+
+ -- Iterator (testcasename) over all Testcases
+ function lunit.testcases()
+ -- Make a copy of testcases to prevent confusing the iterator when
+ -- new testcase are defined
+ local _testcases2 = {}
+ for k,v in pairs(_testcases) do
+ _testcases2[k] = true
+ end
+ return key_iter, _testcases2, nil
+ end
+
+ function testcase(tcname)
+ return _testcases[tcname]
+ end
+end
+
+
+do
+ -- Finds a function in a testcase case insensitive
+ local function findfuncname(tcname, name)
+ for key, value in pairs(testcase(tcname)) do
+ if is_string(key) and is_function(value) and string_lower(key) == name then
+ return key
+ end
+ end
+ end
+
+ function lunit.setupname(tcname)
+ return findfuncname(tcname, "setup")
+ end
+
+ function lunit.teardownname(tcname)
+ return findfuncname(tcname, "teardown")
+ end
+
+ -- Iterator over all test names in a testcase.
+ -- Have to collect the names first in case one of the test
+ -- functions creates a new global and throws off the iteration.
+ function lunit.tests(tcname)
+ local testnames = {}
+ for key, value in pairs(testcase(tcname)) do
+ if is_string(key) and is_function(value) then
+ local lfn = string_lower(key)
+ if string_sub(lfn, 1, 4) == "test" or string_sub(lfn, -4) == "test" then
+ testnames[key] = true
+ end
+ end
+ end
+ return key_iter, testnames, nil
+ end
+end
+
+
+
+
+function lunit.runtest(tcname, testname)
+ orig_assert( is_string(tcname) )
+ orig_assert( is_string(testname) )
+
+ if (not getrunner()) then
+ loadrunner("console")
+ end
+
+ local function callit(context, func)
+ if func then
+ local err = mypcall(func)
+ if err then
+ reporterrobj(context, tcname, testname, err)
+ return false
+ end
+ end
+ return true
+ end
+ traceback_hide(callit)
+
+ report("run", tcname, testname)
+
+ local tc = testcase(tcname)
+ local setup = tc[setupname(tcname)]
+ local test = tc[testname]
+ local teardown = tc[teardownname(tcname)]
+
+ local setup_ok = callit( "setup", setup )
+ local test_ok = setup_ok and callit( "test", test )
+ local teardown_ok = setup_ok and callit( "teardown", teardown )
+
+ if setup_ok and test_ok and teardown_ok then
+ stats.passed = stats.passed + 1
+ report("pass", tcname, testname)
+ end
+end
+traceback_hide(runtest)
+
+
+
+function lunit.run(testpatterns)
+ clearstats()
+ report("begin")
+ for testcasename in lunit.testcases() do
+ -- Run tests in the testcases
+ for testname in lunit.tests(testcasename) do
+ if selected(testpatterns, testname) then
+ runtest(testcasename, testname)
+ end
+ end
+ end
+ report("done")
+ return stats
+end
+traceback_hide(run)
+
+
+function lunit.loadonly()
+ clearstats()
+ report("begin")
+ report("done")
+ return stats
+end
+
+
+
+
+
+
+
+
+
+local lunitpat2luapat
+do
+ local conv = {
+ ["^"] = "%^",
+ ["$"] = "%$",
+ ["("] = "%(",
+ [")"] = "%)",
+ ["%"] = "%%",
+ ["."] = "%.",
+ ["["] = "%[",
+ ["]"] = "%]",
+ ["+"] = "%+",
+ ["-"] = "%-",
+ ["?"] = ".",
+ ["*"] = ".*"
+ }
+ function lunitpat2luapat(str)
+ --return "^" .. string.gsub(str, "%W", conv) .. "$"
+ -- Above was very annoying, if I want to run all the tests having to do with
+ -- RSS, I want to be able to do "-t rss" not "-t \*rss\*".
+ return string_gsub(str, "%W", conv)
+ end
+end
+
+
+
+local function in_patternmap(map, name)
+ if map[name] == true then
+ return true
+ else
+ for _, pat in ipairs(map) do
+ if string_find(name, pat) then
+ return true
+ end
+ end
+ end
+ return false
+end
+
+
+
+
+
+
+
+
+-- Called from 'lunit' shell script.
+
+function main(argv)
+ argv = argv or {}
+
+ -- FIXME: Error handling and error messages aren't nice.
+
+ local function checkarg(optname, arg)
+ if not is_string(arg) then
+ return error("lunit.main: option "..optname..": argument missing.", 0)
+ end
+ end
+
+ local function loadtestcase(filename)
+ if not is_string(filename) then
+ return error("lunit.main: invalid argument")
+ end
+ local chunk, err = loadfile(filename)
+ if err then
+ return error(err)
+ else
+ chunk()
+ end
+ end
+
+ local testpatterns = nil
+ local doloadonly = false
+
+ local i = 0
+ while i < #argv do
+ i = i + 1
+ local arg = argv[i]
+ if arg == "--loadonly" then
+ doloadonly = true
+ elseif arg == "--runner" or arg == "-r" then
+ local optname = arg; i = i + 1; arg = argv[i]
+ checkarg(optname, arg)
+ loadrunner(arg)
+ elseif arg == "--test" or arg == "-t" then
+ local optname = arg; i = i + 1; arg = argv[i]
+ checkarg(optname, arg)
+ testpatterns = testpatterns or {}
+ testpatterns[#testpatterns+1] = arg
+ elseif arg == "--help" or arg == "-h" then
+ print[[
+lunit 0.5
+Copyright (c) 2004-2009 Michael Roth <mroth@nessie.de>
+This program comes WITHOUT WARRANTY OF ANY KIND.
+
+Usage: lua test [OPTIONS] [--] scripts
+
+Options:
+
+ -r, --runner RUNNER Testrunner to use, defaults to 'lunit-console'.
+ -t, --test PATTERN Which tests to run, may contain * or ? wildcards.
+ --loadonly Only load the tests.
+ -h, --help Print this help screen.
+
+Please report bugs to <mroth@nessie.de>.
+]]
+ return
+ elseif arg == "--" then
+ while i < #argv do
+ i = i + 1; arg = argv[i]
+ loadtestcase(arg)
+ end
+ else
+ loadtestcase(arg)
+ end
+ end
+
+ if doloadonly then
+ return loadonly()
+ else
+ return run(testpatterns)
+ end
+end
+
+clearstats()
+
+return lunit
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
diff --git a/tests/test_decoder.cc b/tests/pb/test_decoder.cc
index f1ee510..eb95580 100644
--- a/tests/test_decoder.cc
+++ b/tests/pb/test_decoder.cc
@@ -35,12 +35,13 @@
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
+
+#include "tests/upb_test.h"
+#include "third_party/upb/tests/pb/test_decoder_schema.upb.h"
#include "upb/handlers.h"
#include "upb/pb/decoder.h"
#include "upb/pb/varint.int.h"
-#include "upb_test.h"
#include "upb/upb.h"
-#include "third_party/upb/tests/test_decoder_schema.upb.h"
#undef PRINT_FAILURE
#define PRINT_FAILURE(expr) \
@@ -59,6 +60,7 @@ double completed;
double total;
double *count;
bool count_only;
+upb::BufferHandle global_handle;
// Copied from decoder.c, since this is not a public interface.
typedef struct {
@@ -235,9 +237,10 @@ int* startstr(int* depth, const uint32_t* num, size_t size_hint) {
}
size_t value_string(int* depth, const uint32_t* num, const char* buf,
- size_t n) {
+ size_t n, const upb::BufferHandle* handle) {
UPB_UNUSED(num);
output.append(buf, n);
+ ASSERT(handle == &global_handle);
return n;
}
@@ -407,7 +410,7 @@ bool parse(upb::BytesSink* s, void* subc, const char* buf, size_t start,
start = UPB_MAX(start, *ofs);
if (start <= end) {
size_t len = end - start;
- size_t parsed = s->PutBuffer(subc, buf + start, len);
+ size_t parsed = s->PutBuffer(subc, buf + start, len, &global_handle);
if (status->ok() != (parsed >= len)) {
fprintf(stderr, "Status: %s, parsed=%zu, len=%zu\n",
status->error_message(), parsed, len);
diff --git a/tests/test_decoder_schema.proto b/tests/pb/test_decoder_schema.proto
index 50bfca9..50bfca9 100644
--- a/tests/test_decoder_schema.proto
+++ b/tests/pb/test_decoder_schema.proto
diff --git a/tests/test_varint.c b/tests/pb/test_varint.c
index fc7eb40..84ff831 100644
--- a/tests/test_varint.c
+++ b/tests/pb/test_varint.c
@@ -6,7 +6,7 @@
#include <stdio.h>
#include "upb/pb/varint.int.h"
-#include "upb_test.h"
+#include "tests/upb_test.h"
// Test that we can round-trip from int->varint->int.
static void test_varint_for_num(upb_decoderet (*decoder)(const char*),
diff --git a/tests/test_cpp.cc b/tests/test_cpp.cc
index 8d06135..c4313e1 100644
--- a/tests/test_cpp.cc
+++ b/tests/test_cpp.cc
@@ -12,7 +12,10 @@
#include <iostream>
#include <set>
+
+#ifdef UPB_CXX11
#include <type_traits>
+#endif
#include "upb/def.h"
#include "upb/descriptor/reader.h"
@@ -231,9 +234,10 @@ class StringBufTesterBase {
upb::Sink sub;
sink->StartMessage();
sink->StartString(start, 0, &sub);
- sub.PutStringBuffer(str, NULL, 5);
+ size_t ret = sub.PutStringBuffer(str, &buf_, 5, &handle_);
ASSERT(seen_);
ASSERT(len_ == 5);
+ ASSERT(ret == 5);
ASSERT(handler_data_val_ == kExpectedHandlerData);
}
@@ -241,115 +245,139 @@ class StringBufTesterBase {
bool seen_;
int handler_data_val_;
size_t len_;
+ char buf_;
+ upb::BufferHandle handle_;
};
-// Test all 8 combinations of:
-// (handler data?) x (function/method) x (returns {void, size_t})
+// Test 8 combinations of:
+// (handler data?) x (buffer handle?) x (function/method)
+//
+// Then we add one test each for this variation: to prevent combinatorial
+// explosion of these tests we don't test the full 16 combinations, but
+// rely on our knowledge that the implementation processes the return wrapping
+// in a second separate and independent stage:
+//
+// (function/method)
-class StringBufTesterVoidFunctionNoHandlerData : public StringBufTesterBase {
+class StringBufTesterVoidMethodNoHandlerDataNoHandle
+ : public StringBufTesterBase {
public:
- typedef StringBufTesterVoidFunctionNoHandlerData ME;
+ typedef StringBufTesterVoidMethodNoHandlerDataNoHandle ME;
void Register(upb::Handlers* h, const upb::FieldDef* f) {
UPB_UNUSED(f);
- ASSERT(h->SetStringHandler(f, UpbMakeHandler(&Handler)));
+ ASSERT(h->SetStringHandler(f, UpbMakeHandler(&ME::Handler)));
handler_data_val_ = kExpectedHandlerData;
}
private:
- static void Handler(ME* t, const char *buf, size_t len) {
- t->seen_ = true;
- t->len_ = len;
+ void Handler(const char *buf, size_t len) {
+ ASSERT(buf == &buf_);
+ seen_ = true;
+ len_ = len;
}
};
-class StringBufTesterSizeTFunctionNoHandlerData : public StringBufTesterBase {
+class StringBufTesterVoidMethodNoHandlerDataWithHandle
+ : public StringBufTesterBase {
public:
- typedef StringBufTesterSizeTFunctionNoHandlerData ME;
+ typedef StringBufTesterVoidMethodNoHandlerDataWithHandle ME;
void Register(upb::Handlers* h, const upb::FieldDef* f) {
UPB_UNUSED(f);
- ASSERT(h->SetStringHandler(f, UpbMakeHandler(&Handler)));
+ ASSERT(h->SetStringHandler(f, UpbMakeHandler(&ME::Handler)));
handler_data_val_ = kExpectedHandlerData;
}
private:
- static size_t Handler(ME* t, const char *buf, size_t len) {
- t->seen_ = true;
- t->len_ = len;
- return len;
+ void Handler(const char *buf, size_t len, const upb::BufferHandle* handle) {
+ ASSERT(buf == &buf_);
+ ASSERT(handle == &handle_);
+ seen_ = true;
+ len_ = len;
}
};
-class StringBufTesterVoidMethodNoHandlerData : public StringBufTesterBase {
+class StringBufTesterVoidMethodWithHandlerDataNoHandle
+ : public StringBufTesterBase {
public:
- typedef StringBufTesterVoidMethodNoHandlerData ME;
+ typedef StringBufTesterVoidMethodWithHandlerDataNoHandle ME;
void Register(upb::Handlers* h, const upb::FieldDef* f) {
UPB_UNUSED(f);
- ASSERT(h->SetStringHandler(f, UpbMakeHandler(&ME::Handler)));
- handler_data_val_ = kExpectedHandlerData;
+ ASSERT(h->SetStringHandler(
+ f, UpbBind(&ME::Handler, new int(kExpectedHandlerData))));
}
private:
- void Handler(const char *buf, size_t len) {
+ void Handler(const int* hd, const char *buf, size_t len) {
+ ASSERT(buf == &buf_);
+ handler_data_val_ = *hd;
seen_ = true;
len_ = len;
}
};
-class StringBufTesterSizeTMethodNoHandlerData : public StringBufTesterBase {
+class StringBufTesterVoidMethodWithHandlerDataWithHandle
+ : public StringBufTesterBase {
public:
- typedef StringBufTesterSizeTMethodNoHandlerData ME;
+ typedef StringBufTesterVoidMethodWithHandlerDataWithHandle ME;
void Register(upb::Handlers* h, const upb::FieldDef* f) {
UPB_UNUSED(f);
- ASSERT(h->SetStringHandler(f, UpbMakeHandler(&ME::Handler)));
- handler_data_val_ = kExpectedHandlerData;
+ ASSERT(h->SetStringHandler(
+ f, UpbBind(&ME::Handler, new int(kExpectedHandlerData))));
}
private:
- size_t Handler(const char *buf, size_t len) {
+ void Handler(const int* hd, const char* buf, size_t len,
+ const upb::BufferHandle* handle) {
+ ASSERT(buf == &buf_);
+ ASSERT(handle == &handle_);
+ handler_data_val_ = *hd;
seen_ = true;
len_ = len;
- return len;
}
};
-class StringBufTesterVoidFunctionWithHandlerData : public StringBufTesterBase {
+class StringBufTesterVoidFunctionNoHandlerDataNoHandle
+ : public StringBufTesterBase {
public:
- typedef StringBufTesterVoidFunctionWithHandlerData ME;
+ typedef StringBufTesterVoidFunctionNoHandlerDataNoHandle ME;
void Register(upb::Handlers* h, const upb::FieldDef* f) {
UPB_UNUSED(f);
- ASSERT(h->SetStringHandler(
- f, UpbBind(&Handler, new int(kExpectedHandlerData))));
+ ASSERT(h->SetStringHandler(f, UpbMakeHandler(&ME::Handler)));
+ handler_data_val_ = kExpectedHandlerData;
}
private:
- static void Handler(ME* t, const int* hd, const char *buf, size_t len) {
- t->handler_data_val_ = *hd;
+ static void Handler(ME* t, const char *buf, size_t len) {
+ ASSERT(buf == &t->buf_);
t->seen_ = true;
t->len_ = len;
}
};
-class StringBufTesterSizeTFunctionWithHandlerData : public StringBufTesterBase {
+class StringBufTesterVoidFunctionNoHandlerDataWithHandle
+ : public StringBufTesterBase {
public:
- typedef StringBufTesterSizeTFunctionWithHandlerData ME;
+ typedef StringBufTesterVoidFunctionNoHandlerDataWithHandle ME;
void Register(upb::Handlers* h, const upb::FieldDef* f) {
UPB_UNUSED(f);
- ASSERT(h->SetStringHandler(
- f, UpbBind(&Handler, new int(kExpectedHandlerData))));
+ ASSERT(h->SetStringHandler(f, UpbMakeHandler(&ME::Handler)));
+ handler_data_val_ = kExpectedHandlerData;
}
private:
- static size_t Handler(ME* t, const int* hd, const char *buf, size_t len) {
- t->handler_data_val_ = *hd;
+ static void Handler(ME* t, const char* buf, size_t len,
+ const upb::BufferHandle* handle) {
+ ASSERT(buf == &t->buf_);
+ ASSERT(handle == &t->handle_);
t->seen_ = true;
t->len_ = len;
- return len;
}
};
-class StringBufTesterVoidMethodWithHandlerData : public StringBufTesterBase {
+class StringBufTesterVoidFunctionWithHandlerDataNoHandle
+ : public StringBufTesterBase {
public:
- typedef StringBufTesterVoidMethodWithHandlerData ME;
+ typedef StringBufTesterVoidFunctionWithHandlerDataNoHandle ME;
void Register(upb::Handlers* h, const upb::FieldDef* f) {
UPB_UNUSED(f);
ASSERT(h->SetStringHandler(
@@ -357,16 +385,18 @@ class StringBufTesterVoidMethodWithHandlerData : public StringBufTesterBase {
}
private:
- void Handler(const int* hd, const char *buf, size_t len) {
- handler_data_val_ = *hd;
- seen_ = true;
- len_ = len;
+ static void Handler(ME* t, const int* hd, const char *buf, size_t len) {
+ ASSERT(buf == &t->buf_);
+ t->handler_data_val_ = *hd;
+ t->seen_ = true;
+ t->len_ = len;
}
};
-class StringBufTesterSizeTMethodWithHandlerData : public StringBufTesterBase {
+class StringBufTesterVoidFunctionWithHandlerDataWithHandle
+ : public StringBufTesterBase {
public:
- typedef StringBufTesterSizeTMethodWithHandlerData ME;
+ typedef StringBufTesterVoidFunctionWithHandlerDataWithHandle ME;
void Register(upb::Handlers* h, const upb::FieldDef* f) {
UPB_UNUSED(f);
ASSERT(h->SetStringHandler(
@@ -374,8 +404,29 @@ class StringBufTesterSizeTMethodWithHandlerData : public StringBufTesterBase {
}
private:
- size_t Handler(const int* hd, const char *buf, size_t len) {
- handler_data_val_ = *hd;
+ static void Handler(ME* t, const int* hd, const char* buf, size_t len,
+ const upb::BufferHandle* handle) {
+ ASSERT(buf == &t->buf_);
+ ASSERT(handle == &t->handle_);
+ t->handler_data_val_ = *hd;
+ t->seen_ = true;
+ t->len_ = len;
+ }
+};
+
+class StringBufTesterSizeTMethodNoHandlerDataNoHandle
+ : public StringBufTesterBase {
+ public:
+ typedef StringBufTesterSizeTMethodNoHandlerDataNoHandle ME;
+ void Register(upb::Handlers* h, const upb::FieldDef* f) {
+ UPB_UNUSED(f);
+ ASSERT(h->SetStringHandler(f, UpbMakeHandler(&ME::Handler)));
+ handler_data_val_ = kExpectedHandlerData;
+ }
+
+ private:
+ size_t Handler(const char *buf, size_t len) {
+ ASSERT(buf == &buf_);
seen_ = true;
len_ = len;
return len;
@@ -712,6 +763,284 @@ void TestHandler() {
tester.CallAndVerify(&sink, f.get());
}
+class T1 {};
+class T2 {};
+
+template <class C>
+void DoNothingHandler(C* closure) {
+ UPB_UNUSED(closure);
+}
+
+template <class C>
+void DoNothingInt32Handler(C* closure, int32_t val) {
+ UPB_UNUSED(closure);
+ UPB_UNUSED(val);
+}
+
+template <class R, class C>
+R* DoNothingStartHandler(C* closure) {
+ UPB_UNUSED(closure);
+ return NULL;
+}
+
+template <class R, class C>
+R* DoNothingStartStringHandler(C* closure, size_t size_len) {
+ UPB_UNUSED(closure);
+ UPB_UNUSED(size_len);
+ return NULL;
+}
+
+template <class C>
+void DoNothingStringBufHandler(C* closure, const char *buf, size_t len) {
+ UPB_UNUSED(closure);
+ UPB_UNUSED(buf);
+ UPB_UNUSED(len);
+}
+
+template <class C>
+void DoNothingEndMessageHandler(C* closure, upb::Status *status) {
+ UPB_UNUSED(closure);
+ UPB_UNUSED(status);
+}
+
+void TestMismatchedTypes() {
+ // First create a schema for our test.
+ 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("i32", NULL));
+ ASSERT(f->set_number(1, NULL));
+ ASSERT(md->AddField(f, NULL));
+ const upb::FieldDef* i32 = f.get();
+
+ f = upb::FieldDef::New();
+ f->set_type(UPB_TYPE_INT32);
+ ASSERT(f->set_name("r_i32", NULL));
+ ASSERT(f->set_number(2, NULL));
+ f->set_label(UPB_LABEL_REPEATED);
+ ASSERT(md->AddField(f, NULL));
+ const upb::FieldDef* r_i32 = f.get();
+
+ f = upb::FieldDef::New();
+ f->set_type(UPB_TYPE_STRING);
+ ASSERT(f->set_name("str", NULL));
+ ASSERT(f->set_number(3, NULL));
+ ASSERT(md->AddField(f, NULL));
+ const upb::FieldDef* str = f.get();
+
+ f = upb::FieldDef::New();
+ f->set_type(UPB_TYPE_STRING);
+ ASSERT(f->set_name("r_str", NULL));
+ ASSERT(f->set_number(4, NULL));
+ f->set_label(UPB_LABEL_REPEATED);
+ ASSERT(md->AddField(f, NULL));
+ const upb::FieldDef* r_str = f.get();
+
+ f = upb::FieldDef::New();
+ f->set_type(UPB_TYPE_MESSAGE);
+ ASSERT(f->set_name("msg", NULL));
+ ASSERT(f->set_number(5, NULL));
+ ASSERT(f->set_message_subdef(md.get(), NULL));
+ ASSERT(md->AddField(f, NULL));
+ const upb::FieldDef* msg = f.get();
+
+ f = upb::FieldDef::New();
+ f->set_type(UPB_TYPE_MESSAGE);
+ ASSERT(f->set_name("r_msg", NULL));
+ ASSERT(f->set_number(6, NULL));
+ ASSERT(f->set_message_subdef(md.get(), NULL));
+ f->set_label(UPB_LABEL_REPEATED);
+ ASSERT(md->AddField(f, NULL));
+ const upb::FieldDef* r_msg = f.get();
+
+ ASSERT(md->Freeze(NULL));
+
+ // Now test the type-checking in handler registration.
+ upb::reffed_ptr<upb::Handlers> h(upb::Handlers::New(md.get()));
+
+ // Establish T1 as the top-level closure type.
+ ASSERT(h->SetInt32Handler(i32, UpbMakeHandler(DoNothingInt32Handler<T1>)));
+
+ // Now any other attempt to set another handler with T2 as the top-level
+ // closure should fail. But setting these same handlers with T1 as the
+ // top-level closure will succeed.
+ ASSERT(!h->SetStartMessageHandler(UpbMakeHandler(DoNothingHandler<T2>)));
+ ASSERT(h->SetStartMessageHandler(UpbMakeHandler(DoNothingHandler<T1>)));
+
+ ASSERT(
+ !h->SetEndMessageHandler(UpbMakeHandler(DoNothingEndMessageHandler<T2>)));
+ ASSERT(
+ h->SetEndMessageHandler(UpbMakeHandler(DoNothingEndMessageHandler<T1>)));
+
+ ASSERT(!h->SetStartStringHandler(
+ str, UpbMakeHandler((DoNothingStartStringHandler<T1, T2>))));
+ ASSERT(h->SetStartStringHandler(
+ str, UpbMakeHandler((DoNothingStartStringHandler<T1, T1>))));
+
+ ASSERT(!h->SetEndStringHandler(str, UpbMakeHandler((DoNothingHandler<T2>))));
+ ASSERT(h->SetEndStringHandler(str, UpbMakeHandler((DoNothingHandler<T1>))));
+
+ ASSERT(!h->SetStartSubMessageHandler(
+ msg, UpbMakeHandler((DoNothingStartHandler<T1, T2>))));
+ ASSERT(h->SetStartSubMessageHandler(
+ msg, UpbMakeHandler((DoNothingStartHandler<T1, T1>))));
+
+ ASSERT(
+ !h->SetEndSubMessageHandler(msg, UpbMakeHandler((DoNothingHandler<T2>))));
+ ASSERT(
+ h->SetEndSubMessageHandler(msg, UpbMakeHandler((DoNothingHandler<T1>))));
+
+ ASSERT(!h->SetStartSequenceHandler(
+ r_i32, UpbMakeHandler((DoNothingStartHandler<T1, T2>))));
+ ASSERT(h->SetStartSequenceHandler(
+ r_i32, UpbMakeHandler((DoNothingStartHandler<T1, T1>))));
+
+ ASSERT(!h->SetEndSequenceHandler(
+ r_i32, UpbMakeHandler((DoNothingHandler<T2>))));
+ ASSERT(h->SetEndSequenceHandler(
+ r_i32, UpbMakeHandler((DoNothingHandler<T1>))));
+
+ ASSERT(!h->SetStartSequenceHandler(
+ r_msg, UpbMakeHandler((DoNothingStartHandler<T1, T2>))));
+ ASSERT(h->SetStartSequenceHandler(
+ r_msg, UpbMakeHandler((DoNothingStartHandler<T1, T1>))));
+
+ ASSERT(!h->SetEndSequenceHandler(
+ r_msg, UpbMakeHandler((DoNothingHandler<T2>))));
+ ASSERT(h->SetEndSequenceHandler(
+ r_msg, UpbMakeHandler((DoNothingHandler<T1>))));
+
+ ASSERT(!h->SetStartSequenceHandler(
+ r_str, UpbMakeHandler((DoNothingStartHandler<T1, T2>))));
+ ASSERT(h->SetStartSequenceHandler(
+ r_str, UpbMakeHandler((DoNothingStartHandler<T1, T1>))));
+
+ ASSERT(!h->SetEndSequenceHandler(
+ r_str, UpbMakeHandler((DoNothingHandler<T2>))));
+ ASSERT(h->SetEndSequenceHandler(
+ r_str, UpbMakeHandler((DoNothingHandler<T1>))));
+
+ // By setting T1 as the return type for the Start* handlers we have
+ // established T1 as the type of the sequence and string frames.
+ // Setting callbacks that use T2 should fail, but T1 should succeed.
+ ASSERT(
+ !h->SetStringHandler(str, UpbMakeHandler(DoNothingStringBufHandler<T2>)));
+ ASSERT(
+ h->SetStringHandler(str, UpbMakeHandler(DoNothingStringBufHandler<T1>)));
+
+ ASSERT(!h->SetInt32Handler(r_i32, UpbMakeHandler(DoNothingInt32Handler<T2>)));
+ ASSERT(h->SetInt32Handler(r_i32, UpbMakeHandler(DoNothingInt32Handler<T1>)));
+
+ ASSERT(!h->SetStartSubMessageHandler(
+ r_msg, UpbMakeHandler((DoNothingStartHandler<T1, T2>))));
+ ASSERT(h->SetStartSubMessageHandler(
+ r_msg, UpbMakeHandler((DoNothingStartHandler<T1, T1>))));
+
+ ASSERT(!h->SetEndSubMessageHandler(r_msg,
+ UpbMakeHandler((DoNothingHandler<T2>))));
+ ASSERT(h->SetEndSubMessageHandler(r_msg,
+ UpbMakeHandler((DoNothingHandler<T1>))));
+
+ ASSERT(!h->SetStartStringHandler(
+ r_str, UpbMakeHandler((DoNothingStartStringHandler<T1, T2>))));
+ ASSERT(h->SetStartStringHandler(
+ r_str, UpbMakeHandler((DoNothingStartStringHandler<T1, T1>))));
+
+ ASSERT(
+ !h->SetEndStringHandler(r_str, UpbMakeHandler((DoNothingHandler<T2>))));
+ ASSERT(h->SetEndStringHandler(r_str, UpbMakeHandler((DoNothingHandler<T1>))));
+
+ ASSERT(!h->SetStringHandler(r_str,
+ UpbMakeHandler(DoNothingStringBufHandler<T2>)));
+ ASSERT(h->SetStringHandler(r_str,
+ UpbMakeHandler(DoNothingStringBufHandler<T1>)));
+
+ h->ClearError();
+ ASSERT(h->Freeze(NULL));
+
+ // For our second test we do the same in reverse. We directly set the type of
+ // the frame and then observe failures at registering a Start* handler that
+ // returns a different type.
+ h = upb::Handlers::New(md.get());
+
+ // First establish the type of a sequence frame directly.
+ ASSERT(h->SetInt32Handler(r_i32, UpbMakeHandler(DoNothingInt32Handler<T1>)));
+
+ // Now setting a StartSequence callback that returns a different type should
+ // fail.
+ ASSERT(!h->SetStartSequenceHandler(
+ r_i32, UpbMakeHandler((DoNothingStartHandler<T2, T1>))));
+ ASSERT(h->SetStartSequenceHandler(
+ r_i32, UpbMakeHandler((DoNothingStartHandler<T1, T1>))));
+
+ // Establish a string frame directly.
+ ASSERT(h->SetStringHandler(r_str,
+ UpbMakeHandler(DoNothingStringBufHandler<T1>)));
+
+ // Fail setting a StartString callback that returns a different type.
+ ASSERT(!h->SetStartStringHandler(
+ r_str, UpbMakeHandler((DoNothingStartStringHandler<T2, T1>))));
+ ASSERT(h->SetStartStringHandler(
+ r_str, UpbMakeHandler((DoNothingStartStringHandler<T1, T1>))));
+
+ // The previous established T1 as the frame for the r_str sequence.
+ ASSERT(!h->SetStartSequenceHandler(
+ r_str, UpbMakeHandler((DoNothingStartHandler<T2, T1>))));
+ ASSERT(h->SetStartSequenceHandler(
+ r_str, UpbMakeHandler((DoNothingStartHandler<T1, T1>))));
+
+ // Now test for this error that is not caught until freeze time:
+ // Change-of-closure-type implies that a StartSequence or StartString handler
+ // should exist to return the closure type of the inner frame but no
+ // StartSequence/StartString handler is registered.
+
+ h = upb::Handlers::New(md.get());
+
+ // Establish T1 as top-level closure type.
+ ASSERT(h->SetInt32Handler(i32, UpbMakeHandler(DoNothingInt32Handler<T1>)));
+
+ // Establish T2 as closure type of sequence frame.
+ ASSERT(
+ h->SetInt32Handler(r_i32, UpbMakeHandler((DoNothingInt32Handler<T2>))));
+
+ // Now attempt to freeze; this should fail because a StartSequence handler
+ // needs to be registered that takes a T1 and returns a T2.
+ ASSERT(!h->Freeze(NULL));
+
+ // Now if we register the necessary StartSequence handler, the freezing should
+ // work.
+ ASSERT(h->SetStartSequenceHandler(
+ r_i32, UpbMakeHandler((DoNothingStartHandler<T2, T1>))));
+ h->ClearError();
+ ASSERT(h->Freeze(NULL));
+
+ // Test for a broken chain that is two deep.
+ h = upb::Handlers::New(md.get());
+
+ // Establish T1 as top-level closure type.
+ ASSERT(h->SetInt32Handler(i32, UpbMakeHandler(DoNothingInt32Handler<T1>)));
+
+ // Establish T2 as the closure type of the string frame inside a sequence
+ // frame.
+ ASSERT(h->SetStringHandler(r_str,
+ UpbMakeHandler(DoNothingStringBufHandler<T2>)));
+
+ // Now attempt to freeze; this should fail because a StartSequence or
+ // StartString handler needs to be registered that takes a T1 and returns a
+ // T2.
+ ASSERT(!h->Freeze(NULL));
+
+ // Now if we register a StartSequence handler it succeeds.
+ ASSERT(h->SetStartSequenceHandler(
+ r_str, UpbMakeHandler((DoNothingStartHandler<T2, T1>))));
+ h->ClearError();
+ ASSERT(h->Freeze(NULL));
+
+ // TODO(haberman): test that closure returned by StartSubMessage does not
+ // match top-level closure of sub-handlers.
+}
+
extern "C" {
int run_tests(int argc, char *argv[]) {
@@ -753,14 +1082,17 @@ int run_tests(int argc, char *argv[]) {
TestHandler<StartMsgTesterVoidMethodWithHandlerData>();
TestHandler<StartMsgTesterBoolMethodWithHandlerData>();
- TestHandler<StringBufTesterVoidFunctionNoHandlerData>();
- TestHandler<StringBufTesterSizeTFunctionNoHandlerData>();
- TestHandler<StringBufTesterVoidMethodNoHandlerData>();
- TestHandler<StringBufTesterSizeTMethodNoHandlerData>();
- TestHandler<StringBufTesterVoidFunctionWithHandlerData>();
- TestHandler<StringBufTesterSizeTFunctionWithHandlerData>();
- TestHandler<StringBufTesterVoidMethodWithHandlerData>();
- TestHandler<StringBufTesterSizeTMethodWithHandlerData>();
+ TestHandler<StringBufTesterVoidMethodNoHandlerDataNoHandle>();
+ TestHandler<StringBufTesterVoidMethodNoHandlerDataWithHandle>();
+ TestHandler<StringBufTesterVoidMethodWithHandlerDataNoHandle>();
+ TestHandler<StringBufTesterVoidMethodWithHandlerDataWithHandle>();
+ TestHandler<StringBufTesterVoidFunctionNoHandlerDataNoHandle>();
+ TestHandler<StringBufTesterVoidFunctionNoHandlerDataWithHandle>();
+ TestHandler<StringBufTesterVoidFunctionWithHandlerDataNoHandle>();
+ TestHandler<StringBufTesterVoidFunctionWithHandlerDataWithHandle>();
+ TestHandler<StringBufTesterSizeTMethodNoHandlerDataNoHandle>();
+
+ TestMismatchedTypes();
#ifdef UPB_CXX11
#define ASSERT_STD_LAYOUT(type) \
diff --git a/tests/test_def.c b/tests/test_def.c
index fb33871..bf45a73 100644
--- a/tests/test_def.c
+++ b/tests/test_def.c
@@ -93,10 +93,10 @@ static void test_fielddef_accessors() {
ASSERT(!upb_fielddef_isfrozen(f2));
ASSERT(upb_fielddef_setname(f2, "f2", NULL));
- ASSERT(upb_fielddef_setnumber(f2, 1572, NULL));
+ ASSERT(upb_fielddef_setnumber(f2, 123456789, NULL));
upb_fielddef_settype(f2, UPB_TYPE_BYTES);
upb_fielddef_setlabel(f2, UPB_LABEL_REPEATED);
- ASSERT(upb_fielddef_number(f2) == 1572);
+ ASSERT(upb_fielddef_number(f2) == 123456789);
upb_fielddef_unref(f1, &f1);
upb_fielddef_unref(f2, &f2);
diff --git a/tests/test_vs_proto2.cc b/tests/test_vs_proto2.cc
index 07946dd..22683c3 100644
--- a/tests/test_vs_proto2.cc
+++ b/tests/test_vs_proto2.cc
@@ -19,8 +19,8 @@
#include <stdio.h>
#include <stdlib.h>
#include "benchmarks/google_messages.pb.h"
+#include "upb/bindings/googlepb/bridge.h"
#include "upb/def.h"
-#include "upb/google/bridge.h"
#include "upb/handlers.h"
#include "upb/pb/decoder.h"
#include "upb/pb/glue.h"
@@ -125,7 +125,7 @@ int run_tests(int argc, char *argv[])
MESSAGE_CIDENT msg1;
MESSAGE_CIDENT msg2;
- upb::reffed_ptr<const upb::Handlers> h(upb::google::NewWriteHandlers(msg1));
+ upb::reffed_ptr<const upb::Handlers> h(upb::googlepb::NewWriteHandlers(msg1));
compare_metadata(msg1.GetDescriptor(), h->message_def());
@@ -142,7 +142,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::google::NewWriteHandlers(*dyn_msg1);
+ h = upb::googlepb::NewWriteHandlers(*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