diff --git a/CMakeLists.txt b/CMakeLists.txt index 764519350..7858164f7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -48,7 +48,7 @@ SET(INSTALL_INC include CACHE PATH "Where to install headers to.") OPTION (BUILD_SHARED_LIBS "Build Shared Library (OFF for Static)" ON) OPTION (THREADSAFE "Build libgit2 as threadsafe" OFF) OPTION (BUILD_TESTS "Build Tests" ON) -OPTION (BUILD_CLAY "Build Tests using the Clay suite" OFF) +OPTION (BUILD_CLAR "Build Tests using the Clar suite" OFF) OPTION (TAGS "Generate tags" OFF) # Platform specific compilation flags @@ -142,32 +142,32 @@ IF (BUILD_TESTS) ADD_TEST(libgit2_test libgit2_test) ENDIF () -IF (BUILD_CLAY) +IF (BUILD_CLAR) FIND_PACKAGE(PythonInterp REQUIRED) - SET(CLAY_FIXTURES "${CMAKE_CURRENT_SOURCE_DIR}/tests/resources/") - SET(CLAY_PATH "${CMAKE_CURRENT_SOURCE_DIR}/tests-clay") - ADD_DEFINITIONS(-DCLAY_FIXTURE_PATH=\"${CLAY_FIXTURES}\") + SET(CLAR_FIXTURES "${CMAKE_CURRENT_SOURCE_DIR}/tests/resources/") + SET(CLAR_PATH "${CMAKE_CURRENT_SOURCE_DIR}/tests-clar") + ADD_DEFINITIONS(-DCLAR_FIXTURE_PATH=\"${CLAR_FIXTURES}\") - INCLUDE_DIRECTORIES(${CLAY_PATH}) - FILE(GLOB_RECURSE SRC_TEST ${CLAY_PATH}/*/*.c ${CLAY_PATH}/clay_helpers.c ${CLAY_PATH}/testlib.c) + INCLUDE_DIRECTORIES(${CLAR_PATH}) + FILE(GLOB_RECURSE SRC_TEST ${CLAR_PATH}/*/*.c ${CLAR_PATH}/clar_helpers.c ${CLAR_PATH}/testlib.c) ADD_CUSTOM_COMMAND( - OUTPUT ${CLAY_PATH}/clay_main.c ${CLAY_PATH}/clay.h - COMMAND ${PYTHON_EXECUTABLE} clay -vtap . - DEPENDS ${CLAY_PATH}/clay ${SRC_TEST} - WORKING_DIRECTORY ${CLAY_PATH} + OUTPUT ${CLAR_PATH}/clar_main.c ${CLAR_PATH}/clar.h + COMMAND ${PYTHON_EXECUTABLE} clar -vtap . + DEPENDS ${CLAR_PATH}/clar ${SRC_TEST} + WORKING_DIRECTORY ${CLAR_PATH} ) - ADD_EXECUTABLE(libgit2_clay ${SRC} ${CLAY_PATH}/clay_main.c ${SRC_TEST} ${SRC_ZLIB} ${SRC_HTTP}) - TARGET_LINK_LIBRARIES(libgit2_clay ${CMAKE_THREAD_LIBS_INIT}) + ADD_EXECUTABLE(libgit2_clar ${SRC} ${CLAR_PATH}/clar_main.c ${SRC_TEST} ${SRC_ZLIB} ${SRC_HTTP}) + TARGET_LINK_LIBRARIES(libgit2_clar ${CMAKE_THREAD_LIBS_INIT}) IF (WIN32) - TARGET_LINK_LIBRARIES(libgit2_clay ws2_32) + TARGET_LINK_LIBRARIES(libgit2_clar ws2_32) ELSEIF (CMAKE_SYSTEM_NAME MATCHES "(Solaris|SunOS)") - TARGET_LINK_LIBRARIES(libgit2_clay socket nsl) + TARGET_LINK_LIBRARIES(libgit2_clar socket nsl) ENDIF () ENABLE_TESTING() - ADD_TEST(libgit2_clay libgit2_clay) + ADD_TEST(libgit2_clar libgit2_clar) ENDIF () IF (TAGS) diff --git a/tests-clay/README.md b/tests-clar/README.md similarity index 57% rename from tests-clay/README.md rename to tests-clar/README.md index f7720610a..03a4d54d3 100644 --- a/tests-clay/README.md +++ b/tests-clar/README.md @@ -1,21 +1,21 @@ -Writing Clay tests for libgit2 +Writing Clar tests for libgit2 ============================== -For information on the Clay testing framework and a detailed introduction +For information on the Clar testing framework and a detailed introduction please visit: -https://github.com/tanoku/clay +https://github.com/tanoku/clar * Write your modules and tests. Use good, meaningful names. * Make sure you actually build the tests by setting: - cmake -DBUILD_CLAY=ON build/ + cmake -DBUILD_CLAR=ON build/ * Test: - ./build/libgit2_clay + ./build/libgit2_clar * Make sure everything is fine. diff --git a/tests-clay/attr/file.c b/tests-clar/attr/file.c similarity index 99% rename from tests-clay/attr/file.c rename to tests-clar/attr/file.c index 652ee273c..af50cd38e 100644 --- a/tests-clay/attr/file.c +++ b/tests-clar/attr/file.c @@ -1,4 +1,4 @@ -#include "clay_libgit2.h" +#include "clar_libgit2.h" #include "attr_file.h" #define get_rule(X) ((git_attr_rule *)git_vector_get(&file->rules,(X))) diff --git a/tests-clay/attr/lookup.c b/tests-clar/attr/lookup.c similarity index 99% rename from tests-clay/attr/lookup.c rename to tests-clar/attr/lookup.c index b251562ba..7779e046f 100644 --- a/tests-clay/attr/lookup.c +++ b/tests-clar/attr/lookup.c @@ -1,4 +1,4 @@ -#include "clay_libgit2.h" +#include "clar_libgit2.h" #include "attr_file.h" void test_attr_lookup__simple(void) diff --git a/tests-clay/attr/repo.c b/tests-clar/attr/repo.c similarity index 99% rename from tests-clay/attr/repo.c rename to tests-clar/attr/repo.c index 13f28ca84..6fc36d2b6 100644 --- a/tests-clay/attr/repo.c +++ b/tests-clar/attr/repo.c @@ -1,4 +1,4 @@ -#include "clay_libgit2.h" +#include "clar_libgit2.h" #include "fileops.h" #include "git2/attr.h" diff --git a/tests-clay/buf/basic.c b/tests-clar/buf/basic.c similarity index 96% rename from tests-clay/buf/basic.c rename to tests-clar/buf/basic.c index 860564d13..b025c9915 100644 --- a/tests-clay/buf/basic.c +++ b/tests-clar/buf/basic.c @@ -1,4 +1,4 @@ -#include "clay_libgit2.h" +#include "clar_libgit2.h" #include "buffer.h" static const char *test_string = "Have you seen that? Have you seeeen that??"; @@ -26,4 +26,4 @@ void test_buf_basic__printf(void) cl_assert(git_buf_oom(&buf2) == 0); cl_assert(strcmp(git_buf_cstr(&buf2), "shoop da 23 woop 42") == 0); git_buf_free(&buf2); -} \ No newline at end of file +} diff --git a/tests-clar/clar b/tests-clar/clar new file mode 100755 index 000000000..a718a00ec --- /dev/null +++ b/tests-clar/clar @@ -0,0 +1,309 @@ +#!/usr/bin/env python + +from __future__ import with_statement +from string import Template +import re, fnmatch, os + +VERSION = "0.10.0" + +TEST_FUNC_REGEX = r"^(void\s+(test_%s__(\w+))\(\s*void\s*\))\s*\{" + +EVENT_CB_REGEX = re.compile( + r"^(void\s+clar_on_(\w+)\(\s*void\s*\))\s*\{", + re.MULTILINE) + +SKIP_COMMENTS_REGEX = re.compile( + r'//.*?$|/\*.*?\*/|\'(?:\\.|[^\\\'])*\'|"(?:\\.|[^\\"])*"', + re.DOTALL | re.MULTILINE) + +CLAR_HEADER = """ +/* + * Clar v%s + * + * This is an autogenerated file. Do not modify. + * To add new unit tests or suites, regenerate the whole + * file with `./clar` + */ +""" % VERSION + +CLAR_EVENTS = [ + 'init', + 'shutdown', + 'test', + 'suite' +] + +def main(): + from optparse import OptionParser + + parser = OptionParser() + + parser.add_option('-c', '--clar-path', dest='clar_path') + parser.add_option('-v', '--report-to', dest='print_mode', default='default') + + options, args = parser.parse_args() + + for folder in args or ['.']: + builder = ClarTestBuilder(folder, + clar_path = options.clar_path, + print_mode = options.print_mode) + + builder.render() + + +class ClarTestBuilder: + def __init__(self, path, clar_path = None, print_mode = 'default'): + self.declarations = [] + self.suite_names = [] + self.callback_data = {} + self.suite_data = {} + self.event_callbacks = [] + + self.clar_path = os.path.abspath(clar_path) if clar_path else None + + self.path = os.path.abspath(path) + self.modules = [ + "clar_sandbox.c", + "clar_fixtures.c", + "clar_fs.c" + ] + + self.modules.append("clar_print_%s.c" % print_mode) + + print("Loading test suites...") + + for root, dirs, files in os.walk(self.path): + module_root = root[len(self.path):] + module_root = [c for c in module_root.split(os.sep) if c] + + tests_in_module = fnmatch.filter(files, "*.c") + + for test_file in tests_in_module: + full_path = os.path.join(root, test_file) + test_name = "_".join(module_root + [test_file[:-2]]) + + with open(full_path) as f: + self._process_test_file(test_name, f.read()) + + if not self.suite_data: + raise RuntimeError( + 'No tests found under "%s"' % folder_name) + + def render(self): + main_file = os.path.join(self.path, 'clar_main.c') + with open(main_file, "w") as out: + out.write(self._render_main()) + + header_file = os.path.join(self.path, 'clar.h') + with open(header_file, "w") as out: + out.write(self._render_header()) + + print ('Written Clar suite to "%s"' % self.path) + + ##################################################### + # Internal methods + ##################################################### + + def _render_cb(self, cb): + return '{"%s", &%s}' % (cb['short_name'], cb['symbol']) + + def _render_suite(self, suite): + template = Template( +r""" + { + "${clean_name}", + ${initialize}, + ${cleanup}, + ${cb_ptr}, ${cb_count} + } +""") + + callbacks = {} + for cb in ['initialize', 'cleanup']: + callbacks[cb] = (self._render_cb(suite[cb]) + if suite[cb] else "{NULL, NULL}") + + return template.substitute( + clean_name = suite['name'].replace("_", "::"), + initialize = callbacks['initialize'], + cleanup = callbacks['cleanup'], + cb_ptr = "_clar_cb_%s" % suite['name'], + cb_count = suite['cb_count'] + ).strip() + + def _render_callbacks(self, suite_name, callbacks): + template = Template( +r""" +static const struct clar_func _clar_cb_${suite_name}[] = { + ${callbacks} +}; +""") + callbacks = [ + self._render_cb(cb) + for cb in callbacks + if cb['short_name'] not in ('initialize', 'cleanup') + ] + + return template.substitute( + suite_name = suite_name, + callbacks = ",\n\t".join(callbacks) + ).strip() + + def _render_event_overrides(self): + overrides = [] + for event in CLAR_EVENTS: + if event in self.event_callbacks: + continue + + overrides.append( + "#define clar_on_%s() /* nop */" % event + ) + + return '\n'.join(overrides) + + def _render_header(self): + template = Template(self._load_file('clar.h')) + + declarations = "\n".join( + "extern %s;" % decl + for decl in sorted(self.declarations) + ) + + return template.substitute( + extern_declarations = declarations, + ) + + def _render_main(self): + template = Template(self._load_file('clar.c')) + suite_names = sorted(self.suite_names) + + suite_data = [ + self._render_suite(self.suite_data[s]) + for s in suite_names + ] + + callbacks = [ + self._render_callbacks(s, self.callback_data[s]) + for s in suite_names + ] + + callback_count = sum( + len(cbs) for cbs in self.callback_data.values() + ) + + return template.substitute( + clar_modules = self._get_modules(), + clar_callbacks = "\n".join(callbacks), + clar_suites = ",\n\t".join(suite_data), + clar_suite_count = len(suite_data), + clar_callback_count = callback_count, + clar_event_overrides = self._render_event_overrides(), + ) + + def _load_file(self, filename): + if self.clar_path: + filename = os.path.join(self.clar_path, filename) + with open(filename) as cfile: + return cfile.read() + + else: + import zlib, base64, sys + content = CLAR_FILES[filename] + + if sys.version_info >= (3, 0): + content = bytearray(content, 'utf_8') + content = base64.b64decode(content) + content = zlib.decompress(content) + return str(content) + else: + content = base64.b64decode(content) + return zlib.decompress(content) + + def _get_modules(self): + return "\n".join(self._load_file(f) for f in self.modules) + + def _skip_comments(self, text): + def _replacer(match): + s = match.group(0) + return "" if s.startswith('/') else s + + return re.sub(SKIP_COMMENTS_REGEX, _replacer, text) + + def _process_test_file(self, suite_name, contents): + contents = self._skip_comments(contents) + + self._process_events(contents) + self._process_declarations(suite_name, contents) + + def _process_events(self, contents): + for (decl, event) in EVENT_CB_REGEX.findall(contents): + if event not in CLAR_EVENTS: + continue + + self.declarations.append(decl) + self.event_callbacks.append(event) + + def _process_declarations(self, suite_name, contents): + callbacks = [] + initialize = cleanup = None + + regex_string = TEST_FUNC_REGEX % suite_name + regex = re.compile(regex_string, re.MULTILINE) + + for (declaration, symbol, short_name) in regex.findall(contents): + data = { + "short_name" : short_name, + "declaration" : declaration, + "symbol" : symbol + } + + if short_name == 'initialize': + initialize = data + elif short_name == 'cleanup': + cleanup = data + else: + callbacks.append(data) + + if not callbacks: + return + + tests_in_suite = len(callbacks) + + suite = { + "name" : suite_name, + "initialize" : initialize, + "cleanup" : cleanup, + "cb_count" : tests_in_suite + } + + if initialize: + self.declarations.append(initialize['declaration']) + + if cleanup: + self.declarations.append(cleanup['declaration']) + + self.declarations += [ + callback['declaration'] + for callback in callbacks + ] + + callbacks.sort(key=lambda x: x['short_name']) + self.callback_data[suite_name] = callbacks + self.suite_data[suite_name] = suite + self.suite_names.append(suite_name) + + print(" %s (%d tests)" % (suite_name, tests_in_suite)) + + + +CLAR_FILES = { +"clar.c" : r"""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""", +"clar_print_default.c" : r"""eJyFU01P4zAQPSe/YqgU1a5Cuadi98ap4rLaE6DIxA5YSu3InnQPK/479jgFB9FycuZ53vObj5QeBeoOjlZL6Abh2tFpg602Gln4AFQe285OBmuIsZ80qhPQWeMRulfhYJMujDgoz8v/ZcGiJP+k78qCpHu22lshlYRKJjXfQOUfzaqG+CJfvJCrZgp/UDhUMpAC+laWZ6rwrxNK+8/8XEkElHPWJeBcBQnKmB9YRt6Vn0YfTfJYkCunRuuwpVzPLlqnHPJtpsOp0x7d1GFKowTY0EF2T09CaCyHO6GHyamG+hokeO6q8k1TeWCV5/AQgko+wcM1hiOml0VBqte/qNAsjr2I4cpYkMp3To+o7YLS6yFnDNqE8U2HZ+W+6MzowhecFmHOS009+BfK0j2w+SJ7HK5u4f7vfs+D/DmdLJ0vp3N5f6yJTlm+5sl62Me0M1klCehD35X8uj+RsFsixMlWuuqC38SG37C+W0MD6+36B380Ifb9f0gmbjZgrB1hc7Pc3uTokrR4Dru6kA6DqGG73ZLwUbSDDlfCvYw7Cn38KVmMa0gzK479XJ5HGWZBeE0UnjjKSDaHb+U7mrWGAw==""", +"clar_print_tap.c" : r"""eJyNVMFu2zAMPVtfwbgIYBu2gWK3BmuxnYthh+02wFBtORXmSIYkZxiG/vso2m6lJF12skk9ko+PlJh13MkWjlp20A7cNKORyjVSSZfhDzhhXdPqSbkSvG0n6cTqaLWyDtpnbqCYDxQ/CJuzPyzJfMr8LXy3ugLgiW/FEYU+S799+gpHYazUCm4//FBpvmMvjL1D2T5PrtO/1HXa3iGM0WZ2/A/d2BcE7xhLZA/ZJkqYvPZwAyO3VnTAhwG2HRHLbI7NlAFJbCwRgxVRYM/lgIEYxA9a7U+jg4IlxiVxtjXNbV1vu/Nq78tIaUlDNR3WEVtnptbNMAJAQZ9AOkR7Lda6AFVVzSMLfDhzy/cC7mBr35qo7udeDnYfw63A8Uv3+460OMtGowE4y0b+GOqbhwtQ74+RPYp+Cen9MXKQakV2IdL7G5TjSZh8XY/lqBO2NXJ0fqM3H+HL98fHcFkAAsApgeAoj5Wu6/ra5dCKVie8sLQP/hrOF2I2ifXsmNePJryW2lq/hNVCDIkvK/oAqdIO9M8UxUjx48/ChK8mlmMJ0SdyRozaLDtnsysd0Fizy29ORPMGiqJAkv5DCga4f5fgT0gnKoE7WXqBqcCRN4PEI272445MzIQB3i5hWd9+oWHxNZrwtUk/o0iAvxug/T2eAqiET5HPOYXqssV8YX8BFTvXlQ==""", +"clar_sandbox.c" : r"""eJyNVV1P20AQfLZ/xRIkYpNATItaVSkPlaBVVEoiEgQSRJaxz+SEfY7uLmkD4r931+fEHwRahBST3Zudmb0xSgeahxDOAgl+mATSnwd6dnvsffk07du2MmUutM2VvwwSHvk6nedNTpgJpc3RffrCtZ9tazz5NvEnoDSetngMDkE4VO7CntIu7JyA59qWJZleSAHeum9n7A/Gp4NLPHCotJ9mEXObfcWzE4QhU6pAvfaHP104Idi+/VLjHHNR5ZszvV/EMZNdUPyJ+RoSJh4M9V0ei4jF4F8PLj5+sK0Cx6gsupdoUJgthIYTOO43egw+E0s0SqrbKfagIVZr8muEulpdoKf848x8Xo3PLkeXw++D87OWDdYLSgSrmMRJb5xJcDjieH3g8LUc34dOh7s5fGM2Nj8wjQ/OhgifojGWMRm/JFPplOZiwWhKXnm9Xmo1I1CmFOF85ay9w1J37RxBV5ZkWS82/tpWbx8GMegZo24uM5EytC3KmBJt9DNYQSBWesbFQxe0XIHOYKEY9HA+7PfsN0i1qN4qeDVpmWKNWYUYktpliWIG+gfTE5bORwTqnF4PL09dc6wLBq5x+XaZiHhsdE1mXIFaKc3SjaCEPzIUUNNC4sOFlLlwLlmoMyy+I+7wTWWH78la/3lwVA3AMuMR5JFeCBWI6D7749B3eUyJQCXv3pQC1L7z2qVqvBoYiWoiwhmqQJZIs2JIrHyZVsCaKUQ/eRL5BQWjdMOjcnup4OuAJ3lyWjkeWXOT/7QobZvIrl8a9YCXHEy8s7hKy8UAVd885JZtIRhOQ7/xoS6iqf4ZcPUikyku7YnldGnRo+F4cAOY1N+BjEAlgZoxlS+5EmXrVZRJRBni5j54sY+7fB+W1ShBu9feRG2ziAYGKTuAoym9cbHfDKrXO50SjO7R+tqVXdAhpt1yOducxTHYtMUyYpQ+Ykzmvvrndhr/GMx6DAJdu+px77PnbT1QCTieosE1nujpxdX5+atDhYFlquoXOEf4/wjB3t62O7/9/hGKyVWV6FYvavT+AhbcW38=""", +"clar_fixtures.c" : r"""eJyFUV1LwzAUfW5+xZU9rLUVJ4ggZQ9DFAUfZEwQSglZmrBAl5Qkk6n43236tWbKfMvNOfecc+81llhBgSppLNAN0XCOuNjbnWa4InYTjpE1MSzxuD1Vki2L0BcKTKfn0EYgu57d3uRpjYhPhi1opSwumUwRCvo3zMFYXT9C5xA5stWSVh9hI5FAa+wUFG//osgJCA5tmQ1SF3CVw9kcppfTCAWBj8ZxDg3UN4/zZ7MaHBrHSBw7vpcJ4mGS5Ijtai9qnannNqk1q7myXU+KvhGaCF4wDnfPiyV+eHpbvS7v8cti9YjGq6Yl7lzCkxfo1L0j/lJOwOtrUrwrUcDBBRsii7Xan3bjBlNVL2WUzuMkgGlJdLuIP21oyYjcVf/a6G3ozXTQPRqmsZkwWQiOfgAVGffP""", +"clar_fs.c" : r"""eJylVdtu20YQfSa/YkAD8TKWY8dJX6L0wXDEVqgsBhINN7UFhiGX1qIkl9hd+dLG/57ZCynJUWEkfZE0s7NnZufMGe2xsqAlpJfj6ZsT399DgzUUojhKo8npb3Mg+ud8PBlNE/hq/NP4LJ5G49n5aTKOp71zNJvFs4vx06DzPz6MZ6HvS5UplkO+zAS89EtWUd7KtM3UkuS8kcqdGE/o/+t71tYm/ArTi8lk6HuS/UNTBRVtbtRyAGzo+x4rgaQ2zMaFvucJqlaicdd8z15AHKkE/rbxIQI6+DqrKp4TF3YAJ2GH/AxwTeu8fTBRA0jtl0Xp0K+sucAsx9suzPPauX2v5AIIMxYweO9AhnBwwELAbvTFXLGFrmf/aF+X4/Uu2L++3scEjwjmitRnQ/+x7/0tZ0XXecIaBTUv6AC22i/5SuRPnQWVynAy/z3CSYg/zpPZxVkCJQLp4m2YvYqVbJHrEHU7bJgG+y7IZNBQf1HBz2nNxQN5oeEHoDnnJdlOHYa2aa18dRetmlxziI8ZOl8bCV5ruk3u3ptw9OlUnaeMquxGorOfd/OcKs2kpEKlBFuMibHUuKUCm8gbW1aoOTge4HFwyZqC30l4EgdlhmYR+J4tVVBK1q0wpnv0U4JkKmqygxTDQEdfFKcfRpNRMsKx6zgzM7oLL+c4oz9A80aSs/jjp40U6bpmA46t0vgVzZpVS7TLApg3lOwe55A6ivMqE04hwcsgtCB7tJK0KxdH0pdLWlUpXylii3IVZuLm9mphsPXg6gsrqeXECtwH+Kl7jF96sLj4m6z1i773cGw1VLYCb5dEqoIKodnzgvmDVLQGtLl4B5/t7c+Q40ZwFL66bgLNmUfvmSKHr0Onsg5eT4LFp/c0vyWm1uPFwBTdBd9lTGGwvjCAF7b+Ad4b9mq9HP05TubJaXIxJ/b8f3DZU2lNU9Ivi+G2VNcL1dopLh3dt17IuC0LpHVDwuvA9TLtT21LrHm1EXlo9ly/s/4rwC5C1z00g6MvrDnK22DovCYoOJz1jpPFpsaN6412udkJndTNwdtF/zdiFF6vpMJxlNKIfD12hjQj7MiwD4qD7jkovbfcSEvtlVlTfOH3uxX+rKg3NL3B0dvFrh6I+rselNtN6F68oxk/+2araVBLuv3SZ6RvZL5q3BVi9r52bTgeUfZNwUr/G9kaoSs=""", +"clar.h" : r"""eJy9Vctu2zAQPEdfwVo9WIIQp9c0DWAENmLACIrUQXojaHIVEZVJlaQaAUX/vSQlP/Rw3PTgk6nlDmd2d0iHPBUMUoTx3XL6iFezbyt8j3EQ2iAX0IsHIRc0LxmgG21YzteX2W0Q/JKcIZoThTHRGpQZBxdcGESlYNxwKZLgwq61jWREoTjlOSR1Sm5ZOruglFSdGANNFS+asxxQZ7LMGSZrqUz0eacBazCY5kBEWYx9bBw3n1H9HUcJqheyID9LsOAtNtUtqDs25Knrj+/CfPF99fQ4w1+nq/vgUJ2D8sqUCsbtMn0MC7JpsTRhTQRby+o9kK26NyAh2J6nQTCJ4wDFaOrnYduGNoQqqdErNxmCqsg55Qb5XqMNaE1ewOZPdpO3rJtSG1zYieKxBagEuSlE7UH7nQjdfkFXiXXLfLGcYexWy8WDX43mpaBeACV5jlJiZ8+u0QiF+zMT9CnqEbvM08Q3R3lnVQHUAENpS4CRXsMJBTXJafoPx+u2/Mr21RFzjYQ0yKgShni3s7rLgP74jzlRhzvToK6iPvOZJzUk4QyDuopOXCoh//E6NZKGbtjD03I5fBU6oMOe90BN6TtE2811+nHTnapjb7c9Q9+CPVF7r3Rhb9biU7qIwUrmUlFnInuafQ8nr0QJLl666r2AAZ8cc8cK7EtbX4bL0fBj0TC959TnGoJYqdyPcSRQAS2dq65HA57zOjZgMsnspiMhLlf7+j7+hsqAEvhw50+w/TP4C4S1nfY=""" +} +if __name__ == '__main__': + main() diff --git a/tests-clar/clar.h b/tests-clar/clar.h new file mode 100644 index 000000000..790003131 --- /dev/null +++ b/tests-clar/clar.h @@ -0,0 +1,248 @@ +#ifndef __CLAR_TEST_H__ +#define __CLAR_TEST_H__ + +#include + +void clar__assert( + int condition, + const char *file, + int line, + const char *error, + const char *description, + int should_abort); + +void cl_set_cleanup(void (*cleanup)(void *), void *opaque); +void cl_fs_cleanup(void); + +#ifdef CLAR_FIXTURE_PATH +const char *cl_fixture(const char *fixture_name); +void cl_fixture_sandbox(const char *fixture_name); +void cl_fixture_cleanup(const char *fixture_name); +#endif + +/** + * Assertion macros with explicit error message + */ +#define cl_must_pass_(expr, desc) clar__assert((expr) >= 0, __FILE__, __LINE__, "Function call failed: " #expr, desc, 1) +#define cl_must_fail_(expr, desc) clar__assert((expr) < 0, __FILE__, __LINE__, "Expected function call to fail: " #expr, desc, 1) +#define cl_assert_(expr, desc) clar__assert((expr) != 0, __FILE__, __LINE__, "Expression is not true: " #expr, desc, 1) + +/** + * Check macros with explicit error message + */ +#define cl_check_pass_(expr, desc) clar__assert((expr) >= 0, __FILE__, __LINE__, "Function call failed: " #expr, desc, 0) +#define cl_check_fail_(expr, desc) clar__assert((expr) < 0, __FILE__, __LINE__, "Expected function call to fail: " #expr, desc, 0) +#define cl_check_(expr, desc) clar__assert((expr) != 0, __FILE__, __LINE__, "Expression is not true: " #expr, desc, 0) + +/** + * Assertion macros with no error message + */ +#define cl_must_pass(expr) cl_must_pass_(expr, NULL) +#define cl_must_fail(expr) cl_must_fail_(expr, NULL) +#define cl_assert(expr) cl_assert_(expr, NULL) + +/** + * Check macros with no error message + */ +#define cl_check_pass(expr) cl_check_pass_(expr, NULL) +#define cl_check_fail(expr) cl_check_fail_(expr, NULL) +#define cl_check(expr) cl_check_(expr, NULL) + +/** + * Forced failure/warning + */ +#define cl_fail(desc) clar__assert(0, __FILE__, __LINE__, "Test failed.", desc, 1) +#define cl_warning(desc) clar__assert(0, __FILE__, __LINE__, "Warning during test execution:", desc, 0) + +/** + * Test method declarations + */ +extern void clar_on_init(void); +extern void clar_on_shutdown(void); +extern void test_attr_file__assign_variants(void); +extern void test_attr_file__check_attr_examples(void); +extern void test_attr_file__match_variants(void); +extern void test_attr_file__simple_read(void); +extern void test_attr_lookup__assign_variants(void); +extern void test_attr_lookup__check_attr_examples(void); +extern void test_attr_lookup__from_buffer(void); +extern void test_attr_lookup__match_variants(void); +extern void test_attr_lookup__simple(void); +extern void test_attr_repo__bad_macros(void); +extern void test_attr_repo__cleanup(void); +extern void test_attr_repo__foreach(void); +extern void test_attr_repo__get_many(void); +extern void test_attr_repo__get_one(void); +extern void test_attr_repo__initialize(void); +extern void test_attr_repo__macros(void); +extern void test_attr_repo__manpage_example(void); +extern void test_buf_basic__printf(void); +extern void test_buf_basic__resize(void); +extern void test_config_add__cleanup(void); +extern void test_config_add__initialize(void); +extern void test_config_add__to_existing_section(void); +extern void test_config_add__to_new_section(void); +extern void test_config_new__write_new_config(void); +extern void test_config_read__blank_lines(void); +extern void test_config_read__case_sensitive(void); +extern void test_config_read__empty_files(void); +extern void test_config_read__header_in_last_line(void); +extern void test_config_read__invalid_ext_headers(void); +extern void test_config_read__lone_variable(void); +extern void test_config_read__multiline_value(void); +extern void test_config_read__number_suffixes(void); +extern void test_config_read__prefixes(void); +extern void test_config_read__simple_read(void); +extern void test_config_read__subsection_header(void); +extern void test_config_stress__cleanup(void); +extern void test_config_stress__dont_break_on_invalid_input(void); +extern void test_config_stress__initialize(void); +extern void test_config_write__cleanup(void); +extern void test_config_write__delete_inexistent(void); +extern void test_config_write__delete_value(void); +extern void test_config_write__initialize(void); +extern void test_config_write__replace_value(void); +extern void test_core_buffer__0(void); +extern void test_core_buffer__1(void); +extern void test_core_buffer__2(void); +extern void test_core_buffer__3(void); +extern void test_core_buffer__4(void); +extern void test_core_buffer__5(void); +extern void test_core_buffer__6(void); +extern void test_core_buffer__7(void); +extern void test_core_buffer__8(void); +extern void test_core_buffer__9(void); +extern void test_core_dirent__dont_traverse_dot(void); +extern void test_core_dirent__dont_traverse_empty_folders(void); +extern void test_core_dirent__traverse_slash_terminated_folder(void); +extern void test_core_dirent__traverse_subfolder(void); +extern void test_core_dirent__traverse_weird_filenames(void); +extern void test_core_filebuf__0(void); +extern void test_core_filebuf__1(void); +extern void test_core_filebuf__2(void); +extern void test_core_filebuf__3(void); +extern void test_core_filebuf__4(void); +extern void test_core_filebuf__5(void); +extern void test_core_hex__fromhex(void); +extern void test_core_oid__initialize(void); +extern void test_core_oid__streq(void); +extern void test_core_path__00_dirname(void); +extern void test_core_path__01_basename(void); +extern void test_core_path__02_topdir(void); +extern void test_core_path__05_joins(void); +extern void test_core_path__06_long_joins(void); +extern void test_core_path__07_path_to_dir(void); +extern void test_core_path__08_self_join(void); +extern void test_core_path__09_percent_decode(void); +extern void test_core_path__10_fromurl(void); +extern void test_core_path__11_walkup(void); +extern void test_core_rmdir__delete_recursive(void); +extern void test_core_rmdir__fail_to_delete_non_empty_dir(void); +extern void test_core_rmdir__initialize(void); +extern void test_core_string__0(void); +extern void test_core_string__1(void); +extern void test_core_strtol__int32(void); +extern void test_core_strtol__int64(void); +extern void test_core_vector__0(void); +extern void test_core_vector__1(void); +extern void test_core_vector__2(void); +extern void test_core_vector__3(void); +extern void test_core_vector__4(void); +extern void test_core_vector__5(void); +extern void test_index_read_tree__read_write_involution(void); +extern void test_index_rename__single_file(void); +extern void test_network_createremotethenload__cleanup(void); +extern void test_network_createremotethenload__initialize(void); +extern void test_network_createremotethenload__parsing(void); +extern void test_network_remotelocal__cleanup(void); +extern void test_network_remotelocal__initialize(void); +extern void test_network_remotelocal__retrieve_advertised_references(void); +extern void test_network_remotelocal__retrieve_advertised_references_from_spaced_repository(void); +extern void test_network_remotes__cleanup(void); +extern void test_network_remotes__fnmatch(void); +extern void test_network_remotes__initialize(void); +extern void test_network_remotes__parsing(void); +extern void test_network_remotes__refspec_parsing(void); +extern void test_network_remotes__transform(void); +extern void test_object_commit_commitstagedfile__cleanup(void); +extern void test_object_commit_commitstagedfile__generate_predictable_object_ids(void); +extern void test_object_commit_commitstagedfile__initialize(void); +extern void test_object_raw_chars__build_valid_oid_from_raw_bytes(void); +extern void test_object_raw_chars__find_invalid_chars_in_oid(void); +extern void test_object_raw_compare__compare_allocfmt_oids(void); +extern void test_object_raw_compare__compare_fmt_oids(void); +extern void test_object_raw_compare__compare_pathfmt_oids(void); +extern void test_object_raw_compare__succeed_on_copy_oid(void); +extern void test_object_raw_compare__succeed_on_oid_comparison_equal(void); +extern void test_object_raw_compare__succeed_on_oid_comparison_greater(void); +extern void test_object_raw_compare__succeed_on_oid_comparison_lesser(void); +extern void test_object_raw_convert__succeed_on_oid_to_string_conversion(void); +extern void test_object_raw_convert__succeed_on_oid_to_string_conversion_big(void); +extern void test_object_raw_fromstr__fail_on_invalid_oid_string(void); +extern void test_object_raw_fromstr__succeed_on_valid_oid_string(void); +extern void test_object_raw_hash__hash_buffer_in_single_call(void); +extern void test_object_raw_hash__hash_by_blocks(void); +extern void test_object_raw_hash__hash_commit_object(void); +extern void test_object_raw_hash__hash_junk_data(void); +extern void test_object_raw_hash__hash_multi_byte_object(void); +extern void test_object_raw_hash__hash_one_byte_object(void); +extern void test_object_raw_hash__hash_tag_object(void); +extern void test_object_raw_hash__hash_tree_object(void); +extern void test_object_raw_hash__hash_two_byte_object(void); +extern void test_object_raw_hash__hash_vector(void); +extern void test_object_raw_hash__hash_zero_length_object(void); +extern void test_object_raw_short__oid_shortener_no_duplicates(void); +extern void test_object_raw_short__oid_shortener_stresstest_git_oid_shorten(void); +extern void test_object_raw_size__validate_oid_size(void); +extern void test_object_raw_type2string__check_type_is_loose(void); +extern void test_object_raw_type2string__convert_string_to_type(void); +extern void test_object_raw_type2string__convert_type_to_string(void); +extern void test_object_tree_diff__addition(void); +extern void test_object_tree_diff__cleanup(void); +extern void test_object_tree_diff__deletion(void); +extern void test_object_tree_diff__initialize(void); +extern void test_object_tree_diff__modification(void); +extern void test_object_tree_diff__more(void); +extern void test_object_tree_frompath__cleanup(void); +extern void test_object_tree_frompath__fail_when_processing_an_invalid_path(void); +extern void test_object_tree_frompath__fail_when_processing_an_unknown_tree_segment(void); +extern void test_object_tree_frompath__initialize(void); +extern void test_object_tree_frompath__retrieve_tree_from_path_to_treeentry(void); +extern void test_odb_loose__cleanup(void); +extern void test_odb_loose__exists(void); +extern void test_odb_loose__initialize(void); +extern void test_odb_loose__simple_reads(void); +extern void test_odb_packed__cleanup(void); +extern void test_odb_packed__initialize(void); +extern void test_odb_packed__mass_read(void); +extern void test_odb_packed__read_header_0(void); +extern void test_odb_packed__read_header_1(void); +extern void test_odb_sorting__alternate_backends_sorting(void); +extern void test_odb_sorting__basic_backends_sorting(void); +extern void test_odb_sorting__cleanup(void); +extern void test_odb_sorting__initialize(void); +extern void test_refs_crashes__double_free(void); +extern void test_repo_getters__cleanup(void); +extern void test_repo_getters__empty(void); +extern void test_repo_getters__head_detached(void); +extern void test_repo_getters__head_orphan(void); +extern void test_repo_getters__initialize(void); +extern void test_repo_init__bare_repo(void); +extern void test_repo_init__bare_repo_noslash(void); +extern void test_repo_init__initialize(void); +extern void test_repo_init__standard_repo(void); +extern void test_repo_init__standard_repo_noslash(void); +extern void test_repo_open__bare_empty_repo(void); +extern void test_repo_open__standard_empty_repo(void); +extern void test_status_ignore__0(void); +extern void test_status_ignore__cleanup(void); +extern void test_status_ignore__initialize(void); +extern void test_status_single__hash_single_file(void); +extern void test_status_worktree__cleanup(void); +extern void test_status_worktree__empty_repository(void); +extern void test_status_worktree__ignores(void); +extern void test_status_worktree__initialize(void); +extern void test_status_worktree__single_file(void); +extern void test_status_worktree__whole_repository(void); + +#endif diff --git a/tests-clay/clay_helpers.c b/tests-clar/clar_helpers.c similarity index 84% rename from tests-clay/clay_helpers.c rename to tests-clar/clar_helpers.c index 081fb087e..eea8bc87d 100644 --- a/tests-clay/clay_helpers.c +++ b/tests-clar/clar_helpers.c @@ -1,12 +1,12 @@ -#include "clay_libgit2.h" +#include "clar_libgit2.h" #include "posix.h" -void clay_on_init(void) +void clar_on_init(void) { git_threads_init(); } -void clay_on_shutdown(void) +void clar_on_shutdown(void) { git_threads_shutdown(); } diff --git a/tests-clay/clay_libgit2.h b/tests-clar/clar_libgit2.h similarity index 82% rename from tests-clay/clay_libgit2.h rename to tests-clar/clar_libgit2.h index 1364eb06b..73ef66844 100644 --- a/tests-clay/clay_libgit2.h +++ b/tests-clar/clar_libgit2.h @@ -1,12 +1,12 @@ -#ifndef __CLAY_LIBGIT2__ -#define __CLAY_LIBGIT2__ +#ifndef __CLAR_LIBGIT2__ +#define __CLAR_LIBGIT2__ -#include "clay.h" +#include "clar.h" #include #include "common.h" /** - * Special wrapper for `clay_must_pass` that passes + * Special wrapper for `clar_must_pass` that passes * the last library error as the test failure message. * * Use this wrapper around all `git_` library calls that @@ -15,11 +15,11 @@ #define cl_git_pass(expr) do { \ git_clearerror(); \ if ((expr) != GIT_SUCCESS) \ - clay__assert(0, __FILE__, __LINE__, "Function call failed: " #expr, git_lasterror(), 1); \ + clar__assert(0, __FILE__, __LINE__, "Function call failed: " #expr, git_lasterror(), 1); \ } while(0) /** - * Wrapper for `clay_must_fail` -- this one is + * Wrapper for `clar_must_fail` -- this one is * just for consistency. Use with `git_` library * calls that are supposed to fail! */ @@ -38,7 +38,7 @@ GIT_INLINE(void) cl_assert_strequal_internal( if (!match) { char buf[4096]; snprintf(buf, 4096, "'%s' != '%s'", a, b); - clay__assert(0, file, line, buf, err, 1); + clar__assert(0, file, line, buf, err, 1); } } diff --git a/tests-clar/clar_main.c b/tests-clar/clar_main.c new file mode 100644 index 000000000..16e627041 --- /dev/null +++ b/tests-clar/clar_main.c @@ -0,0 +1,1230 @@ +#include +#include +#include +#include +#include +#include +#include + +/* required for sandboxing */ +#include +#include + +#ifdef _WIN32 +# include +# include +# include +# include + +# define _MAIN_CC __cdecl + +# define stat(path, st) _stat(path, st) +# define mkdir(path, mode) _mkdir(path) +# define chdir(path) _chdir(path) +# define access(path, mode) _access(path, mode) +# define strdup(str) _strdup(str) + +# ifndef __MINGW32__ +# pragma comment(lib, "shell32") +# define strncpy(to, from, to_size) strncpy_s(to, to_size, from, _TRUNCATE) +# define W_OK 02 +# define S_ISDIR(x) ((x & _S_IFDIR) != 0) +# define mktemp_s(path, len) _mktemp_s(path, len) +# endif + typedef struct _stat STAT_T; +#else +# include /* waitpid(2) */ +# include +# define _MAIN_CC + typedef struct stat STAT_T; +#endif + +#include "clar.h" + +static void fs_rm(const char *_source); +static void fs_copy(const char *_source, const char *dest); + +static const char * +fixture_path(const char *base, const char *fixture_name); + +struct clar_error { + const char *test; + int test_number; + const char *suite; + const char *file; + int line_number; + const char *error_msg; + char *description; + + struct clar_error *next; +}; + +static struct { + const char *active_test; + const char *active_suite; + + int suite_errors; + int total_errors; + + int test_count; + + struct clar_error *errors; + struct clar_error *last_error; + + void (*local_cleanup)(void *); + void *local_cleanup_payload; + + jmp_buf trampoline; + int trampoline_enabled; +} _clar; + +struct clar_func { + const char *name; + void (*ptr)(void); +}; + +struct clar_suite { + const char *name; + struct clar_func initialize; + struct clar_func cleanup; + const struct clar_func *tests; + size_t test_count; +}; + +/* From clar_print_*.c */ +static void clar_print_init(int test_count, int suite_count, const char *suite_names); +static void clar_print_shutdown(int test_count, int suite_count, int error_count); +static void clar_print_error(int num, const struct clar_error *error); +static void clar_print_ontest(const char *test_name, int test_number, int failed); +static void clar_print_onsuite(const char *suite_name); +static void clar_print_onabort(const char *msg, ...); + +/* From clar_sandbox.c */ +static void clar_unsandbox(void); +static int clar_sandbox(void); + +/* Event callback overrides */ +#define clar_on_test() /* nop */ +#define clar_on_suite() /* nop */ + +/* Autogenerated test data by clar */ +static const struct clar_func _clar_cb_attr_file[] = { + {"assign_variants", &test_attr_file__assign_variants}, + {"check_attr_examples", &test_attr_file__check_attr_examples}, + {"match_variants", &test_attr_file__match_variants}, + {"simple_read", &test_attr_file__simple_read} +}; +static const struct clar_func _clar_cb_attr_lookup[] = { + {"assign_variants", &test_attr_lookup__assign_variants}, + {"check_attr_examples", &test_attr_lookup__check_attr_examples}, + {"from_buffer", &test_attr_lookup__from_buffer}, + {"match_variants", &test_attr_lookup__match_variants}, + {"simple", &test_attr_lookup__simple} +}; +static const struct clar_func _clar_cb_attr_repo[] = { + {"bad_macros", &test_attr_repo__bad_macros}, + {"foreach", &test_attr_repo__foreach}, + {"get_many", &test_attr_repo__get_many}, + {"get_one", &test_attr_repo__get_one}, + {"macros", &test_attr_repo__macros}, + {"manpage_example", &test_attr_repo__manpage_example} +}; +static const struct clar_func _clar_cb_buf_basic[] = { + {"printf", &test_buf_basic__printf}, + {"resize", &test_buf_basic__resize} +}; +static const struct clar_func _clar_cb_config_add[] = { + {"to_existing_section", &test_config_add__to_existing_section}, + {"to_new_section", &test_config_add__to_new_section} +}; +static const struct clar_func _clar_cb_config_new[] = { + {"write_new_config", &test_config_new__write_new_config} +}; +static const struct clar_func _clar_cb_config_read[] = { + {"blank_lines", &test_config_read__blank_lines}, + {"case_sensitive", &test_config_read__case_sensitive}, + {"empty_files", &test_config_read__empty_files}, + {"header_in_last_line", &test_config_read__header_in_last_line}, + {"invalid_ext_headers", &test_config_read__invalid_ext_headers}, + {"lone_variable", &test_config_read__lone_variable}, + {"multiline_value", &test_config_read__multiline_value}, + {"number_suffixes", &test_config_read__number_suffixes}, + {"prefixes", &test_config_read__prefixes}, + {"simple_read", &test_config_read__simple_read}, + {"subsection_header", &test_config_read__subsection_header} +}; +static const struct clar_func _clar_cb_config_stress[] = { + {"dont_break_on_invalid_input", &test_config_stress__dont_break_on_invalid_input} +}; +static const struct clar_func _clar_cb_config_write[] = { + {"delete_inexistent", &test_config_write__delete_inexistent}, + {"delete_value", &test_config_write__delete_value}, + {"replace_value", &test_config_write__replace_value} +}; +static const struct clar_func _clar_cb_core_buffer[] = { + {"0", &test_core_buffer__0}, + {"1", &test_core_buffer__1}, + {"2", &test_core_buffer__2}, + {"3", &test_core_buffer__3}, + {"4", &test_core_buffer__4}, + {"5", &test_core_buffer__5}, + {"6", &test_core_buffer__6}, + {"7", &test_core_buffer__7}, + {"8", &test_core_buffer__8}, + {"9", &test_core_buffer__9} +}; +static const struct clar_func _clar_cb_core_dirent[] = { + {"dont_traverse_dot", &test_core_dirent__dont_traverse_dot}, + {"dont_traverse_empty_folders", &test_core_dirent__dont_traverse_empty_folders}, + {"traverse_slash_terminated_folder", &test_core_dirent__traverse_slash_terminated_folder}, + {"traverse_subfolder", &test_core_dirent__traverse_subfolder}, + {"traverse_weird_filenames", &test_core_dirent__traverse_weird_filenames} +}; +static const struct clar_func _clar_cb_core_filebuf[] = { + {"0", &test_core_filebuf__0}, + {"1", &test_core_filebuf__1}, + {"2", &test_core_filebuf__2}, + {"3", &test_core_filebuf__3}, + {"4", &test_core_filebuf__4}, + {"5", &test_core_filebuf__5} +}; +static const struct clar_func _clar_cb_core_hex[] = { + {"fromhex", &test_core_hex__fromhex} +}; +static const struct clar_func _clar_cb_core_oid[] = { + {"streq", &test_core_oid__streq} +}; +static const struct clar_func _clar_cb_core_path[] = { + {"00_dirname", &test_core_path__00_dirname}, + {"01_basename", &test_core_path__01_basename}, + {"02_topdir", &test_core_path__02_topdir}, + {"05_joins", &test_core_path__05_joins}, + {"06_long_joins", &test_core_path__06_long_joins}, + {"07_path_to_dir", &test_core_path__07_path_to_dir}, + {"08_self_join", &test_core_path__08_self_join}, + {"09_percent_decode", &test_core_path__09_percent_decode}, + {"10_fromurl", &test_core_path__10_fromurl}, + {"11_walkup", &test_core_path__11_walkup} +}; +static const struct clar_func _clar_cb_core_rmdir[] = { + {"delete_recursive", &test_core_rmdir__delete_recursive}, + {"fail_to_delete_non_empty_dir", &test_core_rmdir__fail_to_delete_non_empty_dir} +}; +static const struct clar_func _clar_cb_core_string[] = { + {"0", &test_core_string__0}, + {"1", &test_core_string__1} +}; +static const struct clar_func _clar_cb_core_strtol[] = { + {"int32", &test_core_strtol__int32}, + {"int64", &test_core_strtol__int64} +}; +static const struct clar_func _clar_cb_core_vector[] = { + {"0", &test_core_vector__0}, + {"1", &test_core_vector__1}, + {"2", &test_core_vector__2}, + {"3", &test_core_vector__3}, + {"4", &test_core_vector__4}, + {"5", &test_core_vector__5} +}; +static const struct clar_func _clar_cb_index_read_tree[] = { + {"read_write_involution", &test_index_read_tree__read_write_involution} +}; +static const struct clar_func _clar_cb_index_rename[] = { + {"single_file", &test_index_rename__single_file} +}; +static const struct clar_func _clar_cb_network_createremotethenload[] = { + {"parsing", &test_network_createremotethenload__parsing} +}; +static const struct clar_func _clar_cb_network_remotelocal[] = { + {"retrieve_advertised_references", &test_network_remotelocal__retrieve_advertised_references}, + {"retrieve_advertised_references_from_spaced_repository", &test_network_remotelocal__retrieve_advertised_references_from_spaced_repository} +}; +static const struct clar_func _clar_cb_network_remotes[] = { + {"fnmatch", &test_network_remotes__fnmatch}, + {"parsing", &test_network_remotes__parsing}, + {"refspec_parsing", &test_network_remotes__refspec_parsing}, + {"transform", &test_network_remotes__transform} +}; +static const struct clar_func _clar_cb_object_commit_commitstagedfile[] = { + {"generate_predictable_object_ids", &test_object_commit_commitstagedfile__generate_predictable_object_ids} +}; +static const struct clar_func _clar_cb_object_raw_chars[] = { + {"build_valid_oid_from_raw_bytes", &test_object_raw_chars__build_valid_oid_from_raw_bytes}, + {"find_invalid_chars_in_oid", &test_object_raw_chars__find_invalid_chars_in_oid} +}; +static const struct clar_func _clar_cb_object_raw_compare[] = { + {"compare_allocfmt_oids", &test_object_raw_compare__compare_allocfmt_oids}, + {"compare_fmt_oids", &test_object_raw_compare__compare_fmt_oids}, + {"compare_pathfmt_oids", &test_object_raw_compare__compare_pathfmt_oids}, + {"succeed_on_copy_oid", &test_object_raw_compare__succeed_on_copy_oid}, + {"succeed_on_oid_comparison_equal", &test_object_raw_compare__succeed_on_oid_comparison_equal}, + {"succeed_on_oid_comparison_greater", &test_object_raw_compare__succeed_on_oid_comparison_greater}, + {"succeed_on_oid_comparison_lesser", &test_object_raw_compare__succeed_on_oid_comparison_lesser} +}; +static const struct clar_func _clar_cb_object_raw_convert[] = { + {"succeed_on_oid_to_string_conversion", &test_object_raw_convert__succeed_on_oid_to_string_conversion}, + {"succeed_on_oid_to_string_conversion_big", &test_object_raw_convert__succeed_on_oid_to_string_conversion_big} +}; +static const struct clar_func _clar_cb_object_raw_fromstr[] = { + {"fail_on_invalid_oid_string", &test_object_raw_fromstr__fail_on_invalid_oid_string}, + {"succeed_on_valid_oid_string", &test_object_raw_fromstr__succeed_on_valid_oid_string} +}; +static const struct clar_func _clar_cb_object_raw_hash[] = { + {"hash_buffer_in_single_call", &test_object_raw_hash__hash_buffer_in_single_call}, + {"hash_by_blocks", &test_object_raw_hash__hash_by_blocks}, + {"hash_commit_object", &test_object_raw_hash__hash_commit_object}, + {"hash_junk_data", &test_object_raw_hash__hash_junk_data}, + {"hash_multi_byte_object", &test_object_raw_hash__hash_multi_byte_object}, + {"hash_one_byte_object", &test_object_raw_hash__hash_one_byte_object}, + {"hash_tag_object", &test_object_raw_hash__hash_tag_object}, + {"hash_tree_object", &test_object_raw_hash__hash_tree_object}, + {"hash_two_byte_object", &test_object_raw_hash__hash_two_byte_object}, + {"hash_vector", &test_object_raw_hash__hash_vector}, + {"hash_zero_length_object", &test_object_raw_hash__hash_zero_length_object} +}; +static const struct clar_func _clar_cb_object_raw_short[] = { + {"oid_shortener_no_duplicates", &test_object_raw_short__oid_shortener_no_duplicates}, + {"oid_shortener_stresstest_git_oid_shorten", &test_object_raw_short__oid_shortener_stresstest_git_oid_shorten} +}; +static const struct clar_func _clar_cb_object_raw_size[] = { + {"validate_oid_size", &test_object_raw_size__validate_oid_size} +}; +static const struct clar_func _clar_cb_object_raw_type2string[] = { + {"check_type_is_loose", &test_object_raw_type2string__check_type_is_loose}, + {"convert_string_to_type", &test_object_raw_type2string__convert_string_to_type}, + {"convert_type_to_string", &test_object_raw_type2string__convert_type_to_string} +}; +static const struct clar_func _clar_cb_object_tree_diff[] = { + {"addition", &test_object_tree_diff__addition}, + {"deletion", &test_object_tree_diff__deletion}, + {"modification", &test_object_tree_diff__modification}, + {"more", &test_object_tree_diff__more} +}; +static const struct clar_func _clar_cb_object_tree_frompath[] = { + {"fail_when_processing_an_invalid_path", &test_object_tree_frompath__fail_when_processing_an_invalid_path}, + {"fail_when_processing_an_unknown_tree_segment", &test_object_tree_frompath__fail_when_processing_an_unknown_tree_segment}, + {"retrieve_tree_from_path_to_treeentry", &test_object_tree_frompath__retrieve_tree_from_path_to_treeentry} +}; +static const struct clar_func _clar_cb_odb_loose[] = { + {"exists", &test_odb_loose__exists}, + {"simple_reads", &test_odb_loose__simple_reads} +}; +static const struct clar_func _clar_cb_odb_packed[] = { + {"mass_read", &test_odb_packed__mass_read}, + {"read_header_0", &test_odb_packed__read_header_0}, + {"read_header_1", &test_odb_packed__read_header_1} +}; +static const struct clar_func _clar_cb_odb_sorting[] = { + {"alternate_backends_sorting", &test_odb_sorting__alternate_backends_sorting}, + {"basic_backends_sorting", &test_odb_sorting__basic_backends_sorting} +}; +static const struct clar_func _clar_cb_refs_crashes[] = { + {"double_free", &test_refs_crashes__double_free} +}; +static const struct clar_func _clar_cb_repo_getters[] = { + {"empty", &test_repo_getters__empty}, + {"head_detached", &test_repo_getters__head_detached}, + {"head_orphan", &test_repo_getters__head_orphan} +}; +static const struct clar_func _clar_cb_repo_init[] = { + {"bare_repo", &test_repo_init__bare_repo}, + {"bare_repo_noslash", &test_repo_init__bare_repo_noslash}, + {"standard_repo", &test_repo_init__standard_repo}, + {"standard_repo_noslash", &test_repo_init__standard_repo_noslash} +}; +static const struct clar_func _clar_cb_repo_open[] = { + {"bare_empty_repo", &test_repo_open__bare_empty_repo}, + {"standard_empty_repo", &test_repo_open__standard_empty_repo} +}; +static const struct clar_func _clar_cb_status_ignore[] = { + {"0", &test_status_ignore__0} +}; +static const struct clar_func _clar_cb_status_single[] = { + {"hash_single_file", &test_status_single__hash_single_file} +}; +static const struct clar_func _clar_cb_status_worktree[] = { + {"empty_repository", &test_status_worktree__empty_repository}, + {"ignores", &test_status_worktree__ignores}, + {"single_file", &test_status_worktree__single_file}, + {"whole_repository", &test_status_worktree__whole_repository} +}; + +static const struct clar_suite _clar_suites[] = { + { + "attr::file", + {NULL, NULL}, + {NULL, NULL}, + _clar_cb_attr_file, 4 + }, + { + "attr::lookup", + {NULL, NULL}, + {NULL, NULL}, + _clar_cb_attr_lookup, 5 + }, + { + "attr::repo", + {"initialize", &test_attr_repo__initialize}, + {"cleanup", &test_attr_repo__cleanup}, + _clar_cb_attr_repo, 6 + }, + { + "buf::basic", + {NULL, NULL}, + {NULL, NULL}, + _clar_cb_buf_basic, 2 + }, + { + "config::add", + {"initialize", &test_config_add__initialize}, + {"cleanup", &test_config_add__cleanup}, + _clar_cb_config_add, 2 + }, + { + "config::new", + {NULL, NULL}, + {NULL, NULL}, + _clar_cb_config_new, 1 + }, + { + "config::read", + {NULL, NULL}, + {NULL, NULL}, + _clar_cb_config_read, 11 + }, + { + "config::stress", + {"initialize", &test_config_stress__initialize}, + {"cleanup", &test_config_stress__cleanup}, + _clar_cb_config_stress, 1 + }, + { + "config::write", + {"initialize", &test_config_write__initialize}, + {"cleanup", &test_config_write__cleanup}, + _clar_cb_config_write, 3 + }, + { + "core::buffer", + {NULL, NULL}, + {NULL, NULL}, + _clar_cb_core_buffer, 10 + }, + { + "core::dirent", + {NULL, NULL}, + {NULL, NULL}, + _clar_cb_core_dirent, 5 + }, + { + "core::filebuf", + {NULL, NULL}, + {NULL, NULL}, + _clar_cb_core_filebuf, 6 + }, + { + "core::hex", + {NULL, NULL}, + {NULL, NULL}, + _clar_cb_core_hex, 1 + }, + { + "core::oid", + {"initialize", &test_core_oid__initialize}, + {NULL, NULL}, + _clar_cb_core_oid, 1 + }, + { + "core::path", + {NULL, NULL}, + {NULL, NULL}, + _clar_cb_core_path, 10 + }, + { + "core::rmdir", + {"initialize", &test_core_rmdir__initialize}, + {NULL, NULL}, + _clar_cb_core_rmdir, 2 + }, + { + "core::string", + {NULL, NULL}, + {NULL, NULL}, + _clar_cb_core_string, 2 + }, + { + "core::strtol", + {NULL, NULL}, + {NULL, NULL}, + _clar_cb_core_strtol, 2 + }, + { + "core::vector", + {NULL, NULL}, + {NULL, NULL}, + _clar_cb_core_vector, 6 + }, + { + "index::read::tree", + {NULL, NULL}, + {NULL, NULL}, + _clar_cb_index_read_tree, 1 + }, + { + "index::rename", + {NULL, NULL}, + {NULL, NULL}, + _clar_cb_index_rename, 1 + }, + { + "network::createremotethenload", + {"initialize", &test_network_createremotethenload__initialize}, + {"cleanup", &test_network_createremotethenload__cleanup}, + _clar_cb_network_createremotethenload, 1 + }, + { + "network::remotelocal", + {"initialize", &test_network_remotelocal__initialize}, + {"cleanup", &test_network_remotelocal__cleanup}, + _clar_cb_network_remotelocal, 2 + }, + { + "network::remotes", + {"initialize", &test_network_remotes__initialize}, + {"cleanup", &test_network_remotes__cleanup}, + _clar_cb_network_remotes, 4 + }, + { + "object::commit::commitstagedfile", + {"initialize", &test_object_commit_commitstagedfile__initialize}, + {"cleanup", &test_object_commit_commitstagedfile__cleanup}, + _clar_cb_object_commit_commitstagedfile, 1 + }, + { + "object::raw::chars", + {NULL, NULL}, + {NULL, NULL}, + _clar_cb_object_raw_chars, 2 + }, + { + "object::raw::compare", + {NULL, NULL}, + {NULL, NULL}, + _clar_cb_object_raw_compare, 7 + }, + { + "object::raw::convert", + {NULL, NULL}, + {NULL, NULL}, + _clar_cb_object_raw_convert, 2 + }, + { + "object::raw::fromstr", + {NULL, NULL}, + {NULL, NULL}, + _clar_cb_object_raw_fromstr, 2 + }, + { + "object::raw::hash", + {NULL, NULL}, + {NULL, NULL}, + _clar_cb_object_raw_hash, 11 + }, + { + "object::raw::short", + {NULL, NULL}, + {NULL, NULL}, + _clar_cb_object_raw_short, 2 + }, + { + "object::raw::size", + {NULL, NULL}, + {NULL, NULL}, + _clar_cb_object_raw_size, 1 + }, + { + "object::raw::type2string", + {NULL, NULL}, + {NULL, NULL}, + _clar_cb_object_raw_type2string, 3 + }, + { + "object::tree::diff", + {"initialize", &test_object_tree_diff__initialize}, + {"cleanup", &test_object_tree_diff__cleanup}, + _clar_cb_object_tree_diff, 4 + }, + { + "object::tree::frompath", + {"initialize", &test_object_tree_frompath__initialize}, + {"cleanup", &test_object_tree_frompath__cleanup}, + _clar_cb_object_tree_frompath, 3 + }, + { + "odb::loose", + {"initialize", &test_odb_loose__initialize}, + {"cleanup", &test_odb_loose__cleanup}, + _clar_cb_odb_loose, 2 + }, + { + "odb::packed", + {"initialize", &test_odb_packed__initialize}, + {"cleanup", &test_odb_packed__cleanup}, + _clar_cb_odb_packed, 3 + }, + { + "odb::sorting", + {"initialize", &test_odb_sorting__initialize}, + {"cleanup", &test_odb_sorting__cleanup}, + _clar_cb_odb_sorting, 2 + }, + { + "refs::crashes", + {NULL, NULL}, + {NULL, NULL}, + _clar_cb_refs_crashes, 1 + }, + { + "repo::getters", + {"initialize", &test_repo_getters__initialize}, + {"cleanup", &test_repo_getters__cleanup}, + _clar_cb_repo_getters, 3 + }, + { + "repo::init", + {"initialize", &test_repo_init__initialize}, + {NULL, NULL}, + _clar_cb_repo_init, 4 + }, + { + "repo::open", + {NULL, NULL}, + {NULL, NULL}, + _clar_cb_repo_open, 2 + }, + { + "status::ignore", + {"initialize", &test_status_ignore__initialize}, + {"cleanup", &test_status_ignore__cleanup}, + _clar_cb_status_ignore, 1 + }, + { + "status::single", + {NULL, NULL}, + {NULL, NULL}, + _clar_cb_status_single, 1 + }, + { + "status::worktree", + {"initialize", &test_status_worktree__initialize}, + {"cleanup", &test_status_worktree__cleanup}, + _clar_cb_status_worktree, 4 + } +}; + +static size_t _clar_suite_count = 45; +static size_t _clar_callback_count = 150; + +/* Core test functions */ +static void +clar_run_test( + const struct clar_func *test, + const struct clar_func *initialize, + const struct clar_func *cleanup) +{ + int error_st = _clar.suite_errors; + + clar_on_test(); + _clar.trampoline_enabled = 1; + + if (setjmp(_clar.trampoline) == 0) { + if (initialize->ptr != NULL) + initialize->ptr(); + + test->ptr(); + } + + _clar.trampoline_enabled = 0; + + if (_clar.local_cleanup != NULL) + _clar.local_cleanup(_clar.local_cleanup_payload); + + if (cleanup->ptr != NULL) + cleanup->ptr(); + + _clar.test_count++; + + /* remove any local-set cleanup methods */ + _clar.local_cleanup = NULL; + _clar.local_cleanup_payload = NULL; + + clar_print_ontest( + test->name, + _clar.test_count, + (_clar.suite_errors > error_st) + ); +} + +static void +clar_report_errors(void) +{ + int i = 1; + struct clar_error *error, *next; + + error = _clar.errors; + while (error != NULL) { + next = error->next; + clar_print_error(i++, error); + free(error->description); + free(error); + error = next; + } + + _clar.errors = _clar.last_error = NULL; +} + +static void +clar_run_suite(const struct clar_suite *suite) +{ + const struct clar_func *test = suite->tests; + size_t i; + + clar_print_onsuite(suite->name); + clar_on_suite(); + + _clar.active_suite = suite->name; + _clar.suite_errors = 0; + + for (i = 0; i < suite->test_count; ++i) { + _clar.active_test = test[i].name; + clar_run_test(&test[i], &suite->initialize, &suite->cleanup); + } +} + +#if 0 /* temporarily disabled */ +static void +clar_run_single(const struct clar_func *test, + const struct clar_suite *suite) +{ + _clar.suite_errors = 0; + _clar.active_suite = suite->name; + _clar.active_test = test->name; + + clar_run_test(test, &suite->initialize, &suite->cleanup); +} +#endif + +static void +clar_usage(const char *arg) +{ + printf("Usage: %s [options]\n\n", arg); + printf("Options:\n"); +// printf(" -tXX\t\tRun only the test number XX\n"); + printf(" -sXX\t\tRun only the suite number XX\n"); + exit(-1); +} + +static void +clar_parse_args(int argc, char **argv) +{ + int i; + + for (i = 1; i < argc; ++i) { + char *argument = argv[i]; + char action; + int num; + + if (argument[0] != '-') + clar_usage(argv[0]); + + action = argument[1]; + num = strtol(argument + 2, &argument, 10); + + if (*argument != '\0' || num < 0) + clar_usage(argv[0]); + + switch (action) { + case 's': + if ((size_t)num >= _clar_suite_count) { + clar_print_onabort("Suite number %d does not exist.\n", num); + exit(-1); + } + + clar_run_suite(&_clar_suites[num]); + break; + + default: + clar_usage(argv[0]); + } + } +} + +static int +clar_test(int argc, char **argv) +{ + clar_print_init( + (int)_clar_callback_count, + (int)_clar_suite_count, + "" + ); + + if (clar_sandbox() < 0) { + clar_print_onabort("Failed to sandbox the test runner.\n"); + exit(-1); + } + + clar_on_init(); + + if (argc > 1) { + clar_parse_args(argc, argv); + } else { + size_t i; + for (i = 0; i < _clar_suite_count; ++i) + clar_run_suite(&_clar_suites[i]); + } + + clar_print_shutdown( + _clar.test_count, + (int)_clar_suite_count, + _clar.total_errors + ); + + clar_on_shutdown(); + + clar_unsandbox(); + return _clar.total_errors; +} + +void +clar__assert( + int condition, + const char *file, + int line, + const char *error_msg, + const char *description, + int should_abort) +{ + struct clar_error *error; + + if (condition) + return; + + error = calloc(1, sizeof(struct clar_error)); + + if (_clar.errors == NULL) + _clar.errors = error; + + if (_clar.last_error != NULL) + _clar.last_error->next = error; + + _clar.last_error = error; + + error->test = _clar.active_test; + error->test_number = _clar.test_count; + error->suite = _clar.active_suite; + error->file = file; + error->line_number = line; + error->error_msg = error_msg; + + if (description != NULL) + error->description = strdup(description); + + _clar.suite_errors++; + _clar.total_errors++; + + if (should_abort) { + if (!_clar.trampoline_enabled) { + clar_print_onabort( + "Fatal error: a cleanup method raised an exception."); + exit(-1); + } + + longjmp(_clar.trampoline, -1); + } +} + +void cl_set_cleanup(void (*cleanup)(void *), void *opaque) +{ + _clar.local_cleanup = cleanup; + _clar.local_cleanup_payload = opaque; +} + +static char _clar_path[4096]; + +static int +is_valid_tmp_path(const char *path) +{ + STAT_T st; + + if (stat(path, &st) != 0) + return 0; + + if (!S_ISDIR(st.st_mode)) + return 0; + + return (access(path, W_OK) == 0); +} + +static int +find_tmp_path(char *buffer, size_t length) +{ +#ifndef _WIN32 + static const size_t var_count = 4; + static const char *env_vars[] = { + "TMPDIR", "TMP", "TEMP", "USERPROFILE" + }; + + size_t i; + + for (i = 0; i < var_count; ++i) { + const char *env = getenv(env_vars[i]); + if (!env) + continue; + + if (is_valid_tmp_path(env)) { + strncpy(buffer, env, length); + return 0; + } + } + + /* If the environment doesn't say anything, try to use /tmp */ + if (is_valid_tmp_path("/tmp")) { + strncpy(buffer, "/tmp", length); + return 0; + } + +#else + if (GetTempPath((DWORD)length, buffer)) + return 0; +#endif + + /* This system doesn't like us, try to use the current directory */ + if (is_valid_tmp_path(".")) { + strncpy(buffer, ".", length); + return 0; + } + + return -1; +} + +static void clar_unsandbox(void) +{ + if (_clar_path[0] == '\0') + return; + +#ifdef _WIN32 + chdir(".."); +#endif + + fs_rm(_clar_path); +} + +static int build_sandbox_path(void) +{ + const char path_tail[] = "clar_tmp_XXXXXX"; + size_t len; + + if (find_tmp_path(_clar_path, sizeof(_clar_path)) < 0) + return -1; + + len = strlen(_clar_path); + +#ifdef _WIN32 + { /* normalize path to POSIX forward slashes */ + size_t i; + for (i = 0; i < len; ++i) { + if (_clar_path[i] == '\\') + _clar_path[i] = '/'; + } + } +#endif + + if (_clar_path[len - 1] != '/') { + _clar_path[len++] = '/'; + } + + strncpy(_clar_path + len, path_tail, sizeof(_clar_path) - len); + +#ifdef _WIN32 + if (mktemp_s(_clar_path, sizeof(_clar_path)) != 0) + return -1; + + if (mkdir(_clar_path, 0700) != 0) + return -1; +#else + if (mkdtemp(_clar_path) == NULL) + return -1; +#endif + + return 0; +} + +static int clar_sandbox(void) +{ + if (_clar_path[0] == '\0' && build_sandbox_path() < 0) + return -1; + + if (chdir(_clar_path) != 0) + return -1; + + return 0; +} + + +static const char * +fixture_path(const char *base, const char *fixture_name) +{ + static char _path[4096]; + size_t root_len; + + root_len = strlen(base); + strncpy(_path, base, sizeof(_path)); + + if (_path[root_len - 1] != '/') + _path[root_len++] = '/'; + + if (fixture_name[0] == '/') + fixture_name++; + + strncpy(_path + root_len, + fixture_name, + sizeof(_path) - root_len); + + return _path; +} + +#ifdef CLAR_FIXTURE_PATH +const char *cl_fixture(const char *fixture_name) +{ + return fixture_path(CLAR_FIXTURE_PATH, fixture_name); +} + +void cl_fixture_sandbox(const char *fixture_name) +{ + fs_copy(cl_fixture(fixture_name), _clar_path); +} + +void cl_fixture_cleanup(const char *fixture_name) +{ + fs_rm(fixture_path(_clar_path, fixture_name)); +} +#endif + +#ifdef _WIN32 + +#define FOF_FLAGS (FOF_SILENT | FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_NOCONFIRMMKDIR) + +static char * +fileops_path(const char *_path) +{ + char *path = NULL; + size_t length, i; + + if (_path == NULL) + return NULL; + + length = strlen(_path); + path = malloc(length + 2); + + if (path == NULL) + return NULL; + + memcpy(path, _path, length); + path[length] = 0; + path[length + 1] = 0; + + for (i = 0; i < length; ++i) { + if (path[i] == '/') + path[i] = '\\'; + } + + return path; +} + +static void +fileops(int mode, const char *_source, const char *_dest) +{ + SHFILEOPSTRUCT fops; + + char *source = fileops_path(_source); + char *dest = fileops_path(_dest); + + ZeroMemory(&fops, sizeof(SHFILEOPSTRUCT)); + + fops.wFunc = mode; + fops.pFrom = source; + fops.pTo = dest; + fops.fFlags = FOF_FLAGS; + + cl_assert_( + SHFileOperation(&fops) == 0, + "Windows SHFileOperation failed" + ); + + free(source); + free(dest); +} + +static void +fs_rm(const char *_source) +{ + fileops(FO_DELETE, _source, NULL); +} + +static void +fs_copy(const char *_source, const char *_dest) +{ + fileops(FO_COPY, _source, _dest); +} + +void +cl_fs_cleanup(void) +{ + fs_rm(fixture_path(_clar_path, "*")); +} + +#else +static int +shell_out(char * const argv[]) +{ + int status; + pid_t pid; + + pid = fork(); + + if (pid < 0) { + fprintf(stderr, + "System error: `fork()` call failed.\n"); + exit(-1); + } + + if (pid == 0) { + execv(argv[0], argv); + } + + waitpid(pid, &status, 0); + return WEXITSTATUS(status); +} + +static void +fs_copy(const char *_source, const char *dest) +{ + char *argv[5]; + char *source; + size_t source_len; + + source = strdup(_source); + source_len = strlen(source); + + if (source[source_len - 1] == '/') + source[source_len - 1] = 0; + + argv[0] = "/bin/cp"; + argv[1] = "-R"; + argv[2] = source; + argv[3] = (char *)dest; + argv[4] = NULL; + + cl_must_pass_( + shell_out(argv), + "Failed to copy test fixtures to sandbox" + ); + + free(source); +} + +static void +fs_rm(const char *source) +{ + char *argv[4]; + + argv[0] = "/bin/rm"; + argv[1] = "-Rf"; + argv[2] = (char *)source; + argv[3] = NULL; + + cl_must_pass_( + shell_out(argv), + "Failed to cleanup the sandbox" + ); +} + +void +cl_fs_cleanup(void) +{ + clar_unsandbox(); + clar_sandbox(); +} +#endif + + +static void clar_print_init(int test_count, int suite_count, const char *suite_names) +{ + (void)test_count; + (void)suite_names; + (void)suite_count; + printf("TAP version 13\n"); +} + +static void clar_print_shutdown(int test_count, int suite_count, int error_count) +{ + (void)test_count; + (void)suite_count; + (void)error_count; + + if (!error_count) + printf("# passed all %d test(s)\n", test_count); + else + printf("# failed %d among %d test(s)\n", error_count, + test_count); + printf("1..%d\n", test_count); +} + +static void clar_print_error(int num, const struct clar_error *error) +{ + (void)num; + + printf(" ---\n"); + printf(" message : %s\n", error->error_msg); + printf(" severity: fail\n"); + printf(" suite : %s\n", error->suite); + printf(" test : %s\n", error->test); + printf(" file : %s\n", error->file); + printf(" line : %d\n", error->line_number); + + if (error->description != NULL) + printf(" description: %s\n", error->description); + + printf(" ...\n"); +} + +static void clar_print_ontest(const char *test_name, int test_number, int failed) +{ + printf("%s %d - %s\n", + failed ? "not ok" : "ok", + test_number, + test_name + ); + + clar_report_errors(); +} + +static void clar_print_onsuite(const char *suite_name) +{ + printf("# *** %s ***\n", suite_name); +} + +static void clar_print_onabort(const char *msg, ...) +{ + va_list argp; + va_start(argp, msg); + fprintf(stdout, "Bail out! "); + vfprintf(stdout, msg, argp); + va_end(argp); +} + + +int _MAIN_CC main(int argc, char *argv[]) +{ + return clar_test(argc, argv); +} diff --git a/tests-clay/config/add.c b/tests-clar/config/add.c similarity index 97% rename from tests-clay/config/add.c rename to tests-clar/config/add.c index de549af15..b58029951 100644 --- a/tests-clay/config/add.c +++ b/tests-clar/config/add.c @@ -1,4 +1,4 @@ -#include "clay_libgit2.h" +#include "clar_libgit2.h" void test_config_add__initialize(void) { diff --git a/tests-clay/config/new.c b/tests-clar/config/new.c similarity index 97% rename from tests-clay/config/new.c rename to tests-clar/config/new.c index 285cc4af8..96aed2bb3 100644 --- a/tests-clay/config/new.c +++ b/tests-clar/config/new.c @@ -1,4 +1,4 @@ -#include "clay_libgit2.h" +#include "clar_libgit2.h" #include "filebuf.h" #include "fileops.h" diff --git a/tests-clay/config/read.c b/tests-clar/config/read.c similarity index 99% rename from tests-clay/config/read.c rename to tests-clar/config/read.c index 08dc03a88..26e6f4248 100644 --- a/tests-clay/config/read.c +++ b/tests-clar/config/read.c @@ -1,4 +1,4 @@ -#include "clay_libgit2.h" +#include "clar_libgit2.h" void test_config_read__simple_read(void) { diff --git a/tests-clay/config/stress.c b/tests-clar/config/stress.c similarity index 97% rename from tests-clay/config/stress.c rename to tests-clar/config/stress.c index 3d3729c41..e3b1114f0 100644 --- a/tests-clay/config/stress.c +++ b/tests-clar/config/stress.c @@ -1,4 +1,4 @@ -#include "clay_libgit2.h" +#include "clar_libgit2.h" #include "filebuf.h" #include "fileops.h" diff --git a/tests-clay/config/write.c b/tests-clar/config/write.c similarity index 98% rename from tests-clay/config/write.c rename to tests-clar/config/write.c index 57610ab63..d22c6f2cf 100644 --- a/tests-clay/config/write.c +++ b/tests-clar/config/write.c @@ -1,4 +1,4 @@ -#include "clay_libgit2.h" +#include "clar_libgit2.h" void test_config_write__initialize(void) { diff --git a/tests-clay/core/buffer.c b/tests-clar/core/buffer.c similarity index 99% rename from tests-clay/core/buffer.c rename to tests-clar/core/buffer.c index 2f376c50a..740cd8578 100644 --- a/tests-clay/core/buffer.c +++ b/tests-clar/core/buffer.c @@ -1,4 +1,4 @@ -#include "clay_libgit2.h" +#include "clar_libgit2.h" #include "buffer.h" #define TESTSTR "Have you seen that? Have you seeeen that??" diff --git a/tests-clay/core/dirent.c b/tests-clar/core/dirent.c similarity index 99% rename from tests-clay/core/dirent.c rename to tests-clar/core/dirent.c index c9ab1c103..edd04471e 100644 --- a/tests-clay/core/dirent.c +++ b/tests-clar/core/dirent.c @@ -1,4 +1,4 @@ -#include "clay_libgit2.h" +#include "clar_libgit2.h" #include "fileops.h" typedef struct name_data { diff --git a/tests-clay/core/filebuf.c b/tests-clar/core/filebuf.c similarity index 98% rename from tests-clay/core/filebuf.c rename to tests-clar/core/filebuf.c index 6a87902fe..29d6bca74 100644 --- a/tests-clay/core/filebuf.c +++ b/tests-clar/core/filebuf.c @@ -1,4 +1,4 @@ -#include "clay_libgit2.h" +#include "clar_libgit2.h" #include "filebuf.h" /* make sure git_filebuf_open doesn't delete an existing lock */ diff --git a/tests-clay/core/hex.c b/tests-clar/core/hex.c similarity index 95% rename from tests-clay/core/hex.c rename to tests-clar/core/hex.c index 391a286be..930af1670 100644 --- a/tests-clay/core/hex.c +++ b/tests-clar/core/hex.c @@ -1,4 +1,4 @@ -#include "clay_libgit2.h" +#include "clar_libgit2.h" #include "util.h" void test_core_hex__fromhex(void) diff --git a/tests-clay/core/oid.c b/tests-clar/core/oid.c similarity index 94% rename from tests-clay/core/oid.c rename to tests-clar/core/oid.c index 44597c5ae..60361c42c 100644 --- a/tests-clay/core/oid.c +++ b/tests-clar/core/oid.c @@ -1,4 +1,4 @@ -#include "clay_libgit2.h" +#include "clar_libgit2.h" static git_oid id; const char *str_oid = "ae90f12eea699729ed24555e40b9fd669da12a12"; @@ -15,4 +15,4 @@ void test_core_oid__streq(void) cl_assert(git_oid_streq(&id, "deadbeef") == GIT_ENOTOID); cl_assert(git_oid_streq(&id, "I'm not an oid.... :)") == GIT_ENOTOID); -} \ No newline at end of file +} diff --git a/tests-clay/core/path.c b/tests-clar/core/path.c similarity index 99% rename from tests-clay/core/path.c rename to tests-clar/core/path.c index 1a77a1f15..3ff5d7daf 100644 --- a/tests-clay/core/path.c +++ b/tests-clar/core/path.c @@ -1,4 +1,4 @@ -#include "clay_libgit2.h" +#include "clar_libgit2.h" #include static void diff --git a/tests-clay/core/rmdir.c b/tests-clar/core/rmdir.c similarity index 98% rename from tests-clay/core/rmdir.c rename to tests-clar/core/rmdir.c index 369c0232a..66b647587 100644 --- a/tests-clay/core/rmdir.c +++ b/tests-clar/core/rmdir.c @@ -1,4 +1,4 @@ -#include "clay_libgit2.h" +#include "clar_libgit2.h" #include "fileops.h" static const char *empty_tmp_dir = "test_gitfo_rmdir_recurs_test"; diff --git a/tests-clay/core/string.c b/tests-clar/core/string.c similarity index 96% rename from tests-clay/core/string.c rename to tests-clar/core/string.c index c154aaf18..bf6ec0a80 100644 --- a/tests-clay/core/string.c +++ b/tests-clar/core/string.c @@ -1,4 +1,4 @@ -#include "clay_libgit2.h" +#include "clar_libgit2.h" /* compare prefixes */ void test_core_string__0(void) diff --git a/tests-clay/core/strtol.c b/tests-clar/core/strtol.c similarity index 97% rename from tests-clay/core/strtol.c rename to tests-clar/core/strtol.c index 41bf7f835..8765e042b 100644 --- a/tests-clay/core/strtol.c +++ b/tests-clar/core/strtol.c @@ -1,4 +1,4 @@ -#include "clay_libgit2.h" +#include "clar_libgit2.h" void test_core_strtol__int32(void) { diff --git a/tests-clay/core/vector.c b/tests-clar/core/vector.c similarity index 99% rename from tests-clay/core/vector.c rename to tests-clar/core/vector.c index fdcfb3a77..ef3d6c36d 100644 --- a/tests-clay/core/vector.c +++ b/tests-clar/core/vector.c @@ -1,4 +1,4 @@ -#include "clay_libgit2.h" +#include "clar_libgit2.h" #include "vector.h" /* initial size of 1 would cause writing past array bounds */ diff --git a/tests-clay/index/read_tree.c b/tests-clar/index/read_tree.c similarity index 97% rename from tests-clay/index/read_tree.c rename to tests-clar/index/read_tree.c index 09a1d94c4..c657d4f71 100644 --- a/tests-clay/index/read_tree.c +++ b/tests-clar/index/read_tree.c @@ -1,4 +1,4 @@ -#include "clay_libgit2.h" +#include "clar_libgit2.h" #include "posix.h" /* Test that reading and writing a tree is a no-op */ diff --git a/tests-clay/index/rename.c b/tests-clar/index/rename.c similarity index 98% rename from tests-clay/index/rename.c rename to tests-clar/index/rename.c index 104982a15..eecd257fd 100644 --- a/tests-clay/index/rename.c +++ b/tests-clar/index/rename.c @@ -1,4 +1,4 @@ -#include "clay_libgit2.h" +#include "clar_libgit2.h" #include "posix.h" void test_index_rename__single_file(void) diff --git a/tests-clay/network/createremotethenload.c b/tests-clar/network/createremotethenload.c similarity index 97% rename from tests-clay/network/createremotethenload.c rename to tests-clar/network/createremotethenload.c index 16d430e7e..68ba9291e 100644 --- a/tests-clay/network/createremotethenload.c +++ b/tests-clar/network/createremotethenload.c @@ -1,4 +1,4 @@ -#include "clay_libgit2.h" +#include "clar_libgit2.h" static git_remote *_remote; static git_repository *_repo; diff --git a/tests-clay/network/remotelocal.c b/tests-clar/network/remotelocal.c similarity index 98% rename from tests-clay/network/remotelocal.c rename to tests-clar/network/remotelocal.c index 961c623a1..81af77756 100644 --- a/tests-clay/network/remotelocal.c +++ b/tests-clar/network/remotelocal.c @@ -1,4 +1,4 @@ -#include "clay_libgit2.h" +#include "clar_libgit2.h" #include "transport.h" #include "buffer.h" #include "path.h" diff --git a/tests-clay/network/remotes.c b/tests-clar/network/remotes.c similarity index 98% rename from tests-clay/network/remotes.c rename to tests-clar/network/remotes.c index 2c3a32e7f..2abaccb07 100644 --- a/tests-clay/network/remotes.c +++ b/tests-clar/network/remotes.c @@ -1,4 +1,4 @@ -#include "clay_libgit2.h" +#include "clar_libgit2.h" static git_remote *_remote; static git_repository *_repo; diff --git a/tests-clay/object/commit/commitstagedfile.c b/tests-clar/object/commit/commitstagedfile.c similarity index 99% rename from tests-clay/object/commit/commitstagedfile.c rename to tests-clar/object/commit/commitstagedfile.c index 764013b38..de69b4496 100644 --- a/tests-clay/object/commit/commitstagedfile.c +++ b/tests-clar/object/commit/commitstagedfile.c @@ -1,4 +1,4 @@ -#include "clay_libgit2.h" +#include "clar_libgit2.h" #include "posix.h" static git_repository *repo; diff --git a/tests-clay/object/raw/chars.c b/tests-clar/object/raw/chars.c similarity index 97% rename from tests-clay/object/raw/chars.c rename to tests-clar/object/raw/chars.c index 83bcbeb79..206bf7119 100644 --- a/tests-clay/object/raw/chars.c +++ b/tests-clar/object/raw/chars.c @@ -1,5 +1,5 @@ -#include "clay_libgit2.h" +#include "clar_libgit2.h" #include "odb.h" diff --git a/tests-clay/object/raw/compare.c b/tests-clar/object/raw/compare.c similarity index 99% rename from tests-clay/object/raw/compare.c rename to tests-clar/object/raw/compare.c index 94b196945..22f958098 100644 --- a/tests-clay/object/raw/compare.c +++ b/tests-clar/object/raw/compare.c @@ -1,5 +1,5 @@ -#include "clay_libgit2.h" +#include "clar_libgit2.h" #include "odb.h" diff --git a/tests-clay/object/raw/convert.c b/tests-clar/object/raw/convert.c similarity index 98% rename from tests-clay/object/raw/convert.c rename to tests-clar/object/raw/convert.c index f69f5f924..b9715a5da 100644 --- a/tests-clay/object/raw/convert.c +++ b/tests-clar/object/raw/convert.c @@ -1,5 +1,5 @@ -#include "clay_libgit2.h" +#include "clar_libgit2.h" #include "odb.h" diff --git a/tests-clay/object/raw/data.h b/tests-clar/object/raw/data.h similarity index 100% rename from tests-clay/object/raw/data.h rename to tests-clar/object/raw/data.h diff --git a/tests-clay/object/raw/fromstr.c b/tests-clar/object/raw/fromstr.c similarity index 96% rename from tests-clay/object/raw/fromstr.c rename to tests-clar/object/raw/fromstr.c index 6d732d4eb..8c11c105f 100644 --- a/tests-clay/object/raw/fromstr.c +++ b/tests-clar/object/raw/fromstr.c @@ -1,5 +1,5 @@ -#include "clay_libgit2.h" +#include "clar_libgit2.h" #include "odb.h" diff --git a/tests-clay/object/raw/hash.c b/tests-clar/object/raw/hash.c similarity index 99% rename from tests-clay/object/raw/hash.c rename to tests-clar/object/raw/hash.c index 9974ed6ef..2375851bb 100644 --- a/tests-clay/object/raw/hash.c +++ b/tests-clar/object/raw/hash.c @@ -1,5 +1,5 @@ -#include "clay_libgit2.h" +#include "clar_libgit2.h" #include "odb.h" #include "hash.h" diff --git a/tests-clay/object/raw/short.c b/tests-clar/object/raw/short.c similarity index 98% rename from tests-clay/object/raw/short.c rename to tests-clar/object/raw/short.c index 996f3f7b4..14b1ae219 100644 --- a/tests-clay/object/raw/short.c +++ b/tests-clar/object/raw/short.c @@ -1,5 +1,5 @@ -#include "clay_libgit2.h" +#include "clar_libgit2.h" #include "odb.h" #include "hash.h" diff --git a/tests-clay/object/raw/size.c b/tests-clar/object/raw/size.c similarity index 90% rename from tests-clay/object/raw/size.c rename to tests-clar/object/raw/size.c index 44c5b6cd1..930c6de23 100644 --- a/tests-clay/object/raw/size.c +++ b/tests-clar/object/raw/size.c @@ -1,5 +1,5 @@ -#include "clay_libgit2.h" +#include "clar_libgit2.h" #include "odb.h" diff --git a/tests-clay/object/raw/type2string.c b/tests-clar/object/raw/type2string.c similarity index 98% rename from tests-clay/object/raw/type2string.c rename to tests-clar/object/raw/type2string.c index 109bc1112..24ed1c44f 100644 --- a/tests-clay/object/raw/type2string.c +++ b/tests-clar/object/raw/type2string.c @@ -1,5 +1,5 @@ -#include "clay_libgit2.h" +#include "clar_libgit2.h" #include "odb.h" #include "hash.h" diff --git a/tests-clay/object/tree/diff.c b/tests-clar/object/tree/diff.c similarity index 99% rename from tests-clay/object/tree/diff.c rename to tests-clar/object/tree/diff.c index 315e0fa47..d481b6f2b 100644 --- a/tests-clay/object/tree/diff.c +++ b/tests-clar/object/tree/diff.c @@ -1,4 +1,4 @@ -#include "clay_libgit2.h" +#include "clar_libgit2.h" #include "tree.h" #include "repository.h" diff --git a/tests-clay/object/tree/frompath.c b/tests-clar/object/tree/frompath.c similarity index 99% rename from tests-clay/object/tree/frompath.c rename to tests-clar/object/tree/frompath.c index 06d08ac7b..3857d42a8 100644 --- a/tests-clay/object/tree/frompath.c +++ b/tests-clar/object/tree/frompath.c @@ -1,4 +1,4 @@ -#include "clay_libgit2.h" +#include "clar_libgit2.h" static git_repository *repo; const char *tree_with_subtrees_oid = "ae90f12eea699729ed24555e40b9fd669da12a12"; diff --git a/tests-clay/odb/loose.c b/tests-clar/odb/loose.c similarity index 98% rename from tests-clay/odb/loose.c rename to tests-clar/odb/loose.c index 1d534704e..f95dc28d4 100644 --- a/tests-clay/odb/loose.c +++ b/tests-clar/odb/loose.c @@ -1,4 +1,4 @@ -#include "clay_libgit2.h" +#include "clar_libgit2.h" #include "odb.h" #include "posix.h" #include "loose_data.h" diff --git a/tests-clay/odb/loose_data.h b/tests-clar/odb/loose_data.h similarity index 100% rename from tests-clay/odb/loose_data.h rename to tests-clar/odb/loose_data.h diff --git a/tests-clay/odb/pack_data.h b/tests-clar/odb/pack_data.h similarity index 100% rename from tests-clay/odb/pack_data.h rename to tests-clar/odb/pack_data.h diff --git a/tests-clay/odb/packed.c b/tests-clar/odb/packed.c similarity index 98% rename from tests-clay/odb/packed.c rename to tests-clar/odb/packed.c index 4e9918d3e..4bce41ba0 100644 --- a/tests-clay/odb/packed.c +++ b/tests-clar/odb/packed.c @@ -1,4 +1,4 @@ -#include "clay_libgit2.h" +#include "clar_libgit2.h" #include "odb.h" #include "pack_data.h" diff --git a/tests-clay/odb/sorting.c b/tests-clar/odb/sorting.c similarity index 98% rename from tests-clay/odb/sorting.c rename to tests-clar/odb/sorting.c index 779660707..bf64f6af4 100644 --- a/tests-clay/odb/sorting.c +++ b/tests-clar/odb/sorting.c @@ -1,4 +1,4 @@ -#include "clay_libgit2.h" +#include "clar_libgit2.h" #include "git2/odb_backend.h" #include "odb.h" diff --git a/tests-clay/refs/crashes.c b/tests-clar/refs/crashes.c similarity index 95% rename from tests-clay/refs/crashes.c rename to tests-clar/refs/crashes.c index 339d4f8e1..26ce98a68 100644 --- a/tests-clay/refs/crashes.c +++ b/tests-clar/refs/crashes.c @@ -1,4 +1,4 @@ -#include "clay_libgit2.h" +#include "clar_libgit2.h" void test_refs_crashes__double_free(void) { diff --git a/tests-clay/repo/getters.c b/tests-clar/repo/getters.c similarity index 98% rename from tests-clay/repo/getters.c rename to tests-clar/repo/getters.c index 426b83e54..a0d437983 100644 --- a/tests-clay/repo/getters.c +++ b/tests-clar/repo/getters.c @@ -1,4 +1,4 @@ -#include "clay_libgit2.h" +#include "clar_libgit2.h" void test_repo_getters__initialize(void) { diff --git a/tests-clay/repo/init.c b/tests-clar/repo/init.c similarity index 99% rename from tests-clay/repo/init.c rename to tests-clar/repo/init.c index e235ffaeb..ab5edfb58 100644 --- a/tests-clay/repo/init.c +++ b/tests-clar/repo/init.c @@ -1,4 +1,4 @@ -#include "clay_libgit2.h" +#include "clar_libgit2.h" #include "fileops.h" enum repo_mode { diff --git a/tests-clay/repo/open.c b/tests-clar/repo/open.c similarity index 98% rename from tests-clay/repo/open.c rename to tests-clar/repo/open.c index 05b01ceb2..3bd103c27 100644 --- a/tests-clay/repo/open.c +++ b/tests-clar/repo/open.c @@ -1,4 +1,4 @@ -#include "clay_libgit2.h" +#include "clar_libgit2.h" #include "posix.h" void test_repo_open__bare_empty_repo(void) diff --git a/tests-clay/status/ignore.c b/tests-clar/status/ignore.c similarity index 97% rename from tests-clay/status/ignore.c rename to tests-clar/status/ignore.c index f14e10c8e..3a66b3a7a 100644 --- a/tests-clay/status/ignore.c +++ b/tests-clar/status/ignore.c @@ -1,4 +1,4 @@ -#include "clay_libgit2.h" +#include "clar_libgit2.h" #include "fileops.h" #include "git2/attr.h" diff --git a/tests-clay/status/single.c b/tests-clar/status/single.c similarity index 96% rename from tests-clay/status/single.c rename to tests-clar/status/single.c index c290bddff..e900a31d6 100644 --- a/tests-clay/status/single.c +++ b/tests-clar/status/single.c @@ -1,4 +1,4 @@ -#include "clay_libgit2.h" +#include "clar_libgit2.h" #include "posix.h" static void diff --git a/tests-clay/status/status_data.h b/tests-clar/status/status_data.h similarity index 100% rename from tests-clay/status/status_data.h rename to tests-clar/status/status_data.h diff --git a/tests-clay/status/worktree.c b/tests-clar/status/worktree.c similarity index 99% rename from tests-clay/status/worktree.c rename to tests-clar/status/worktree.c index 2183649f2..d8e62a94d 100644 --- a/tests-clay/status/worktree.c +++ b/tests-clar/status/worktree.c @@ -1,4 +1,4 @@ -#include "clay_libgit2.h" +#include "clar_libgit2.h" #include "fileops.h" #include "ignore.h" #include "status_data.h" diff --git a/tests-clay/clay b/tests-clay/clay deleted file mode 100755 index b5512d09e..000000000 --- a/tests-clay/clay +++ /dev/null @@ -1,309 +0,0 @@ -#!/usr/bin/env python - -from __future__ import with_statement -from string import Template -import re, fnmatch, os - -VERSION = "0.10.0" - -TEST_FUNC_REGEX = r"^(void\s+(test_%s__(\w+))\(\s*void\s*\))\s*\{" - -EVENT_CB_REGEX = re.compile( - r"^(void\s+clay_on_(\w+)\(\s*void\s*\))\s*\{", - re.MULTILINE) - -SKIP_COMMENTS_REGEX = re.compile( - r'//.*?$|/\*.*?\*/|\'(?:\\.|[^\\\'])*\'|"(?:\\.|[^\\"])*"', - re.DOTALL | re.MULTILINE) - -CLAY_HEADER = """ -/* - * Clay v%s - * - * This is an autogenerated file. Do not modify. - * To add new unit tests or suites, regenerate the whole - * file with `./clay` - */ -""" % VERSION - -CLAY_EVENTS = [ - 'init', - 'shutdown', - 'test', - 'suite' -] - -def main(): - from optparse import OptionParser - - parser = OptionParser() - - parser.add_option('-c', '--clay-path', dest='clay_path') - parser.add_option('-v', '--report-to', dest='print_mode', default='default') - - options, args = parser.parse_args() - - for folder in args or ['.']: - builder = ClayTestBuilder(folder, - clay_path = options.clay_path, - print_mode = options.print_mode) - - builder.render() - - -class ClayTestBuilder: - def __init__(self, path, clay_path = None, print_mode = 'default'): - self.declarations = [] - self.suite_names = [] - self.callback_data = {} - self.suite_data = {} - self.event_callbacks = [] - - self.clay_path = os.path.abspath(clay_path) if clay_path else None - - self.path = os.path.abspath(path) - self.modules = [ - "clay_sandbox.c", - "clay_fixtures.c", - "clay_fs.c" - ] - - self.modules.append("clay_print_%s.c" % print_mode) - - print("Loading test suites...") - - for root, dirs, files in os.walk(self.path): - module_root = root[len(self.path):] - module_root = [c for c in module_root.split(os.sep) if c] - - tests_in_module = fnmatch.filter(files, "*.c") - - for test_file in tests_in_module: - full_path = os.path.join(root, test_file) - test_name = "_".join(module_root + [test_file[:-2]]) - - with open(full_path) as f: - self._process_test_file(test_name, f.read()) - - if not self.suite_data: - raise RuntimeError( - 'No tests found under "%s"' % folder_name) - - def render(self): - main_file = os.path.join(self.path, 'clay_main.c') - with open(main_file, "w") as out: - out.write(self._render_main()) - - header_file = os.path.join(self.path, 'clay.h') - with open(header_file, "w") as out: - out.write(self._render_header()) - - print ('Written Clay suite to "%s"' % self.path) - - ##################################################### - # Internal methods - ##################################################### - - def _render_cb(self, cb): - return '{"%s", &%s}' % (cb['short_name'], cb['symbol']) - - def _render_suite(self, suite): - template = Template( -r""" - { - "${clean_name}", - ${initialize}, - ${cleanup}, - ${cb_ptr}, ${cb_count} - } -""") - - callbacks = {} - for cb in ['initialize', 'cleanup']: - callbacks[cb] = (self._render_cb(suite[cb]) - if suite[cb] else "{NULL, NULL}") - - return template.substitute( - clean_name = suite['name'].replace("_", "::"), - initialize = callbacks['initialize'], - cleanup = callbacks['cleanup'], - cb_ptr = "_clay_cb_%s" % suite['name'], - cb_count = suite['cb_count'] - ).strip() - - def _render_callbacks(self, suite_name, callbacks): - template = Template( -r""" -static const struct clay_func _clay_cb_${suite_name}[] = { - ${callbacks} -}; -""") - callbacks = [ - self._render_cb(cb) - for cb in callbacks - if cb['short_name'] not in ('initialize', 'cleanup') - ] - - return template.substitute( - suite_name = suite_name, - callbacks = ",\n\t".join(callbacks) - ).strip() - - def _render_event_overrides(self): - overrides = [] - for event in CLAY_EVENTS: - if event in self.event_callbacks: - continue - - overrides.append( - "#define clay_on_%s() /* nop */" % event - ) - - return '\n'.join(overrides) - - def _render_header(self): - template = Template(self._load_file('clay.h')) - - declarations = "\n".join( - "extern %s;" % decl - for decl in sorted(self.declarations) - ) - - return template.substitute( - extern_declarations = declarations, - ) - - def _render_main(self): - template = Template(self._load_file('clay.c')) - suite_names = sorted(self.suite_names) - - suite_data = [ - self._render_suite(self.suite_data[s]) - for s in suite_names - ] - - callbacks = [ - self._render_callbacks(s, self.callback_data[s]) - for s in suite_names - ] - - callback_count = sum( - len(cbs) for cbs in self.callback_data.values() - ) - - return template.substitute( - clay_modules = self._get_modules(), - clay_callbacks = "\n".join(callbacks), - clay_suites = ",\n\t".join(suite_data), - clay_suite_count = len(suite_data), - clay_callback_count = callback_count, - clay_event_overrides = self._render_event_overrides(), - ) - - def _load_file(self, filename): - if self.clay_path: - filename = os.path.join(self.clay_path, filename) - with open(filename) as cfile: - return cfile.read() - - else: - import zlib, base64, sys - content = CLAY_FILES[filename] - - if sys.version_info >= (3, 0): - content = bytearray(content, 'utf_8') - content = base64.b64decode(content) - content = zlib.decompress(content) - return str(content) - else: - content = base64.b64decode(content) - return zlib.decompress(content) - - def _get_modules(self): - return "\n".join(self._load_file(f) for f in self.modules) - - def _skip_comments(self, text): - def _replacer(match): - s = match.group(0) - return "" if s.startswith('/') else s - - return re.sub(SKIP_COMMENTS_REGEX, _replacer, text) - - def _process_test_file(self, suite_name, contents): - contents = self._skip_comments(contents) - - self._process_events(contents) - self._process_declarations(suite_name, contents) - - def _process_events(self, contents): - for (decl, event) in EVENT_CB_REGEX.findall(contents): - if event not in CLAY_EVENTS: - continue - - self.declarations.append(decl) - self.event_callbacks.append(event) - - def _process_declarations(self, suite_name, contents): - callbacks = [] - initialize = cleanup = None - - regex_string = TEST_FUNC_REGEX % suite_name - regex = re.compile(regex_string, re.MULTILINE) - - for (declaration, symbol, short_name) in regex.findall(contents): - data = { - "short_name" : short_name, - "declaration" : declaration, - "symbol" : symbol - } - - if short_name == 'initialize': - initialize = data - elif short_name == 'cleanup': - cleanup = data - else: - callbacks.append(data) - - if not callbacks: - return - - tests_in_suite = len(callbacks) - - suite = { - "name" : suite_name, - "initialize" : initialize, - "cleanup" : cleanup, - "cb_count" : tests_in_suite - } - - if initialize: - self.declarations.append(initialize['declaration']) - - if cleanup: - self.declarations.append(cleanup['declaration']) - - self.declarations += [ - callback['declaration'] - for callback in callbacks - ] - - callbacks.sort(key=lambda x: x['short_name']) - self.callback_data[suite_name] = callbacks - self.suite_data[suite_name] = suite - self.suite_names.append(suite_name) - - print(" %s (%d tests)" % (suite_name, tests_in_suite)) - - - -CLAY_FILES = { -"clay.c" : r"""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""", -"clay_print_default.c" : r"""eJyFU01P4zAQPSe/YqgU1a5Cuafa3RunistqT4AiEztgKbUje9LVCvHfsccpOGhbTs48z3t+85HSo0DdwdFqCd0g/rWj0wZbbTSy8AGoPLadnQzWEGM/aVQnoLPGI3QvwsEmXRhxUJ6Xr2XBoiT/pO/KgqR7ttpbIZWESiY130DlH8yqhvgiX7yQq2YKv1E4VDKQAvpWlmeq8C8TSvvXfF9JBJRz1iXgXAUJypgfWEbelZ9GH0zyWJArp0brsKVczy5apxzybabDqdMe3dRhSqME2NBBdk9PQmgsh1uhh8mphvoaJHjuqvJNU3lgledwH4JKPsL9NYYjppdFQarXP6nQLI69iOHKWJDKd06PqO2C0ushZwzahPFNhyflvujM6MIXnBZhzktNPfhnytI9sPkiexyufsDdn/2eB/lzOlk6X07n8v5YE52yfM2T9bCPaWeyShLQh74r+XV/ImG3RIiTrXTVBb+JDb9gfbuGBtbb9Tf+aELs//8hmbjZgLF2hM3NcnuTo0vS4ins6kI6DKKG7XZLwkfRDjpcCfc87ij08adkMa4hzaw49nN5HmWYBeE1UXjiKCPZHL6V7yZUhjs=""", -"clay_print_tap.c" : r"""eJyNVMFu2zAMPVtfwbgIYBu2gWK3BtuwnYthh+02wFBtORXmSIYkZyiG/vso2m6lJG12skk9ko+PlJh13MkWjlp20A78qRmNVK6RSroMf8AJ65pWT8qV4G07SSdWR6uVddA+cgPFfKD4Qdic/WVJ5lPmr+G71RUAT3wrjij0Wfrjy3c4CmOlVnD74ZdK8x17ZuwNyvZxcp3+o67T9g5hjDaz43/oxr4geMdYInvINlHC5KWHGxi5taIDPgyw7YhYZnNspgxIYmOJGKyIAnsuBwzEIH7Qan8aHRQsMS6Js61pbut6251Xe1tGSksaqumwjtg6M7VuhhEACvoE0iHaa7HWBaiqah5Z4MOZW74XcAdb+9pE9Wnu5WD3MdwKHL90T3ekxVk2Gg3AWTbyx1DfPFyAen+M7FH0S0jvj5GDVCuyC5He36AcD8Lk63osR52wrZGj8xu9+Qjfft7fh8sCEABOCQRHeax0XdfXLodWtDrhhaV98NdwvhCzSaxnx7x+NOG11Nb6JawWYkh8WdHPkCrtQP9OUYwUP/4sTPhiYjmWEH0iZ8SozbJzNrvSAY01u/zmRDRvoCgKJOk/pGCAe78Ef0A6UQncydILTAWOvBkkHnGzH3dkYiYM8HYJy/r2Cw2Lr9GEr036FUUC/N0A7e/xFEAlfIp8zilUly3mM/sHrvXXzQ==""", -"clay_sandbox.c" : r"""eJyNVV1P20AQfLZ/xRIkYpNATItaVSkPlaBVVEoiEgQSRJaxz+SEfY7uLmkD4r931+fEHwRahBST3Zudmb0xSgeahxDOAgl+mAQrfx7o2e2x9+XTtG/bypS50DZX/jJIeOTrdJ43OWEmlDZH9+kL1362rfHk28SfgNJ42uIxOAThULkLe0q7sHMCnmtblmR6IQV4676dsT8Ynw4u8cCh0n6aRcxt9hXPThCGTKkC9dof/nThhGD79kuNc8xFlW/O9H4Rx0x2QfEn5mtImHgw1Hd5LCIWg389uPj4wbYKHKOy6F4G0g+zhdBwAsf9Ro/BZ2KJRkl1O8UeNMRqTX6NUFerC/SUf5yZz6vx2eXocvh9cH7WssF6QYlgFZM46Y0zCQ5HHK8PHL6W4/vQ6XA3h2/MxuYHpvHB2RDhUzTGMibjl2QqndJcLBhNySuv10utZgTKlCKcr5y1d1jqrp0j6MqSLOvFxl/b6u3DIAY9Y9TNZSZShrZFGVOijX4GKwjESs+4eOiClivQGSwUgx7Oh/2e/QapFtVbBa8mLVOsMasQQ1K7LFHMQP9gesLS+YhAndPr4eWpa451wcA1Lt8uExGPja7JjCtQK6VZuhGU8EeGAmpaSHy4kDIXziULdYbFd8Qdvqns8D1Z6z8PjqoBWGY8gjzSC6ECEd1nfxz6Lo8pEajk3ZtSgNp3XrtUjVcDI1FNRDhDFcgSaVYMiZUv0wpYM4XoJ08iv6BglG54VG4vFXwd8CRPTivHI2tu8p8WpW0T2fVLox7wkoOJdxZXabkYoOqbh9yyLQTDaeg3PtRFNNU/A65eZDLFpT2xnC4tejQcD24Ak/o7kBGoJFAzpvIlV6JsvYoyiShD3NwHL/Zxl+/DsholaPfam6htFtHAIGUHcDSlNy72m0H1eqdTgtE9Wl+7sgs6xLRbLmebszgGm7ZYRozSR4zJ3Ff/3E7jH4NZj0Gga1c97n32vK0HKgHHUzS4xhM9vbg6P391qDCwTFX9AucI/x8h2Nvbdue33z9CMbmqEt3qRY3eX120XBI=""", -"clay_fixtures.c" : r"""eJyFUV1LwzAUfW5+xZU9rLUVJ4ggZQ9DFAUfRCZMRglZmrBAl5Qkk03xv9v0a82U+Zabc+45595rLLGCAlXSWKBrouEccbGzW81wSew6HCIrYljicTuqJBsWoS8UmFbPobXA8npye5OlFSI+GbaglbK4YDJFKOjeMAVjdfUInUPkyFZLWu7DWiKBxtgpKN78RZETEByactlLXcBVBmdTGF+OIxQEPhrHGdRQ1zzMv5xUYN84ROLY8b1MEPeTJEdsV3tRq0wdt06tWcWVzXpS9I3QSPCccbh7nr3jh6fF/O31Hr/M5o9ouGpa4NYlPHmBVt074i/lBLy+OsWHEjkcXLAhMl+p3Wk3bjBV1VIG6TxOApgWZN8s4k8bWjAit+W/NnoTejMddI+GqW1GTOaCox8pOffr""", -"clay_fs.c" : r"""eJylVdtu20YQfSa/YkAD8TKWY8dJX6L0wXDEVqgsBhINN7UFhiGX1qIkl9hd+dLG/57ZCynJUWEkfZE0s7NnZufMGe2xsqAlpJfj6ZsT399DgzUUojhKo8npb3Mg+ud8PBlNE/hq/NP4LJ5G49n5aTKOp71zNJvFs4vx06DzPz6MZ6HvS5UplkO+zAS89EtWUd7KtM3UkuS8kcqdGE/o/+t71tYm/ArTi8lk6HuS/UNTBRVtbtRyAGzo+x4rgaQ2zMaFvucJqlaicdd8z15AHKkE/rbxIQI6+DqrKp4TF3YAJ2GH/AxwTeu8fTBRA0jtl0Xp0K+sucAsx9suzPPauX2v5AIIMxYweO9AhnBwwELAbvTFXLGFrmf/aF+X4/Uu2L++3scEjwjmitRnQ/+x7/0tZ0XXecIaBTUv6AC22i/5SuRPnQWVynAy/z3CSYg/zpPZxVkCJQLp4m2YvYqVbJHrEHU7bJgG+y7IZNBQf1HBz2nNxQN5oeEHoDnnJdlOHYa2aa18dRetmlxziI8ZOl8bCV5ruk3u3ptw9OlUnaeMquxGorOfd/OcKs2kpEKlBFuMibHUuKUCm8gbW1aoOTge4HFwyZqC30l4EgdlhmYR+J4tVVBK1q0wpnv0U4JkKmqygxTDQEdfFKcfRpNRMsKx6zgzM7oLL+c4oz9A80aSs/jjp40U6bpmA46t0vgVzZpVS7TLApg3lOwe55A6ivMqe3AKCV4GoQXZo5WkXbk4kr5c0qpK+UoRW5SrMBM3t1cLg60HV19YSS0nVuA+wE/dY/zSg8XF32StX/S9h2OrobIVeLskUhVUCM2eF8wfpKI1oM3FO/hsb3+GHDeCo/DVdRNozjx6zxQ5fB06lXXwehIsPr2n+S0xtR4vBqboLvguYwqD9YUBvLD1D/DesFfr5ejPcTJPTpOLObHn/4PLnkprmpJ+WQy3pbpeqNZOcenovvVCxm1ZIK0bEl4Hrpdpf2pbYs2rjchDs+f6nfVfAXYRuu6hGRx9Yc1R3gZD5zVBweGsd5wsNjVuXG+0y81O6KRuDt4u+r8Ro/B6JRWOo5RG5OuxM6QZYUeGfVAcdM9B6b3lRlpqr8ya4gu/363wZ0W9oekNjt4udvVA1N/1oNxuQvfiHc342TdbTYNa0u2XPiN9I/NV464Qs/e1a8PxiLJvClb63wD3Q6FA""", -"clay.h" : r"""eJy9Vctu2zAQPEdfwVo9WIIQp9c0DWAENmLACIrWQdsTQZOriKhMqiTVqCj67yUp+aGH46YHn0wtdzizu0M65KlgkCKM75bTb3g1+7zC9xgHoQ1yAb14EHJB85IButGG5Xx9md0GwU/JGaI5+YUx0RqUGQcXXBhEpWDccCmS4MKutY1kRKE45TkkdUpuWTq7oJRUnRgDTRUvmrMcUGeyzBkma6lM9H6nAWswmOZARFmMfWwcN59R/R1HCaoXsiA/SrDgLTbVLag7NuSp64/vwnzxdfX4aYY/Tlf3waE6B+WVKRWM22X6GBZk02JpwpoItpbVayBbdS9AQrA9T4NgEscBitHUz8O2DW0IVVKjZ24yBFWRc8oN8r1GG9CaPIHNn+wmb1k3pTa4sBPFYwtQCXJTiNqD9jsRuv2ArhLrlvliOcPYrZaLB78azUtBvQBK8hylxM6eXaMRCvdnJuhd1CN2maeJb47yzqoCqAGG0pYAI72GEwpqktP0b47XbfmV7asj5hoJaZBRJQzxbmd1lwH9/h9zog53pkFdRX3mM09qSMIZBnUVnbhUQv7jdWokDd2wh8flcvgqdECHPe+BmtJ3iLab6/TjpjtVx95ue4a+BXui9l7pwl6sxad0EYOVzKWizkT2NPseTp6JElw8ddV7AQM+OeaOFdiXtr4Ml6Phx6Jhes2pX2oIYqVyP8aRQAW0dK66Hg14zuvYgMkks5uWRBGXq319b39DZUAJfLjzJ9j+GfwFGCyeSg==""" -} -if __name__ == '__main__': - main()