commit
6ec2869102
7 changed files with 8614 additions and 0 deletions
@ -0,0 +1,129 @@ |
|||||||
|
# This file was generated from BUILD using tools/make_cmakelists.py. |
||||||
|
|
||||||
|
cmake_minimum_required(VERSION 3.10...3.24) |
||||||
|
|
||||||
|
project(upb) |
||||||
|
set(CMAKE_C_STANDARD 99) |
||||||
|
|
||||||
|
|
||||||
|
# Prevent CMake from setting -rdynamic on Linux (!!). |
||||||
|
SET(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "") |
||||||
|
SET(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "") |
||||||
|
|
||||||
|
# Set default build type. |
||||||
|
if(NOT CMAKE_BUILD_TYPE) |
||||||
|
message(STATUS "Setting build type to 'RelWithDebInfo' as none was specified.") |
||||||
|
set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING |
||||||
|
"Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." |
||||||
|
FORCE) |
||||||
|
endif() |
||||||
|
|
||||||
|
# When using Ninja, compiler output won't be colorized without this. |
||||||
|
include(CheckCXXCompilerFlag) |
||||||
|
CHECK_CXX_COMPILER_FLAG(-fdiagnostics-color=always SUPPORTS_COLOR_ALWAYS) |
||||||
|
if(SUPPORTS_COLOR_ALWAYS) |
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdiagnostics-color=always") |
||||||
|
endif() |
||||||
|
|
||||||
|
# Implement ASAN/UBSAN options |
||||||
|
if(UPB_ENABLE_ASAN) |
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address") |
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address") |
||||||
|
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address") |
||||||
|
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fsanitize=address") |
||||||
|
endif() |
||||||
|
|
||||||
|
if(UPB_ENABLE_UBSAN) |
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined") |
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address") |
||||||
|
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address") |
||||||
|
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fsanitize=address") |
||||||
|
endif() |
||||||
|
|
||||||
|
if(NOT TARGET utf8_range) |
||||||
|
if(EXISTS ../external/utf8_range) |
||||||
|
# utf8_range is already installed |
||||||
|
include_directories(../external/utf8_range) |
||||||
|
elseif(EXISTS ../../utf8_range) |
||||||
|
include_directories(../../utf8_range) |
||||||
|
else() |
||||||
|
include(FetchContent) |
||||||
|
FetchContent_Declare( |
||||||
|
utf8_range |
||||||
|
GIT_REPOSITORY "https://github.com/protocolbuffers/utf8_range.git" |
||||||
|
GIT_TAG "de0b4a8ff9b5d4c98108bdfe723291a33c52c54f" |
||||||
|
) |
||||||
|
FetchContent_GetProperties(utf8_range) |
||||||
|
if(NOT utf8_range_POPULATED) |
||||||
|
FetchContent_Populate(utf8_range) |
||||||
|
include_directories(${utf8_range_SOURCE_DIR}) |
||||||
|
endif() |
||||||
|
endif() |
||||||
|
endif() |
||||||
|
|
||||||
|
if(APPLE) |
||||||
|
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -undefined dynamic_lookup -flat_namespace") |
||||||
|
elseif(UNIX) |
||||||
|
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--build-id") |
||||||
|
endif() |
||||||
|
|
||||||
|
enable_testing() |
||||||
|
|
||||||
|
|
||||||
|
add_library(upb INTERFACE |
||||||
|
|
||||||
|
) |
||||||
|
target_include_directories(upb INTERFACE |
||||||
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/..> |
||||||
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../cmake> |
||||||
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINRARY_DIR}> |
||||||
|
) |
||||||
|
target_link_libraries(upb INTERFACE |
||||||
|
base |
||||||
|
mem) |
||||||
|
|
||||||
|
add_library(generated_code_support__only_for_generated_code_do_not_use__i_give_permission_to_break_me INTERFACE |
||||||
|
|
||||||
|
) |
||||||
|
target_include_directories(generated_code_support__only_for_generated_code_do_not_use__i_give_permission_to_break_me INTERFACE |
||||||
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/..> |
||||||
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../cmake> |
||||||
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINRARY_DIR}> |
||||||
|
) |
||||||
|
target_link_libraries(generated_code_support__only_for_generated_code_do_not_use__i_give_permission_to_break_me INTERFACE |
||||||
|
base |
||||||
|
collections |
||||||
|
collections_internal |
||||||
|
mem |
||||||
|
message |
||||||
|
message_accessors |
||||||
|
message_accessors_internal |
||||||
|
message_internal |
||||||
|
mini_descriptor |
||||||
|
mini_table |
||||||
|
wire |
||||||
|
wire_internal) |
||||||
|
|
||||||
|
add_library(generated_cpp_support__only_for_generated_code_do_not_use__i_give_permission_to_break_me INTERFACE |
||||||
|
|
||||||
|
) |
||||||
|
target_include_directories(generated_cpp_support__only_for_generated_code_do_not_use__i_give_permission_to_break_me INTERFACE |
||||||
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/..> |
||||||
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../cmake> |
||||||
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINRARY_DIR}> |
||||||
|
) |
||||||
|
|
||||||
|
add_library(generated_reflection_support__only_for_generated_code_do_not_use__i_give_permission_to_break_me INTERFACE |
||||||
|
|
||||||
|
) |
||||||
|
target_include_directories(generated_reflection_support__only_for_generated_code_do_not_use__i_give_permission_to_break_me INTERFACE |
||||||
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/..> |
||||||
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../cmake> |
||||||
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINRARY_DIR}> |
||||||
|
) |
||||||
|
target_link_libraries(generated_reflection_support__only_for_generated_code_do_not_use__i_give_permission_to_break_me INTERFACE |
||||||
|
mem |
||||||
|
mini_descriptor |
||||||
|
reflection_internal) |
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -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. |
||||||
|
|
||||||
|
======================================================================== |
||||||
|
|
@ -0,0 +1,9 @@ |
|||||||
|
URL: https://github.com/dcurrie/lunit |
||||||
|
Version: 0.5 |
||||||
|
License: MIT |
||||||
|
License File: LICENSE |
||||||
|
Description: |
||||||
|
A unit testing library for Lua. |
||||||
|
|
||||||
|
Local Modifications: |
||||||
|
Extracted the two file we actually need from the distribution. |
@ -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 |
||||||
|
|
||||||
|
|
@ -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 |
Loading…
Reference in new issue