From 416b034fe138d515931b747dc60722845e2103f8 Mon Sep 17 00:00:00 2001 From: Snaipe Date: Mon, 7 Sep 2015 01:15:31 +0200 Subject: [PATCH 01/23] Made the interface C++11-compatible --- CMakeLists.txt | 2 +- include/criterion/abort.h | 4 + include/criterion/assert.h | 169 +++++++++--------- include/criterion/common.h | 28 ++- include/criterion/criterion.h | 51 ++++-- .../criterion/designated-initializer-compat.h | 124 +++++++++++++ include/criterion/event.h | 13 +- include/criterion/hooks.h | 26 ++- include/criterion/logging.h | 13 +- include/criterion/options.h | 4 + include/criterion/ordered-set.h | 12 +- include/criterion/theories.h | 4 + include/criterion/types.h | 21 ++- samples/CMakeLists.txt | 8 + samples/asserts.c | 2 - samples/report.c | 6 +- src/report.c | 22 +-- 17 files changed, 364 insertions(+), 145 deletions(-) create mode 100644 include/criterion/designated-initializer-compat.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 4298976..d222268 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 2.8) -project(Criterion C) +project(Criterion C CXX) set(MODULE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/.cmake/Modules") set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${MODULE_DIR}) diff --git a/include/criterion/abort.h b/include/criterion/abort.h index 1df05c0..598b27e 100644 --- a/include/criterion/abort.h +++ b/include/criterion/abort.h @@ -26,6 +26,10 @@ # include "common.h" +CR_BEGIN_C_API + CR_API NORETURN void criterion_abort_test(void); +CR_END_C_API + #endif /* !CRITERION_ABORT_H_ */ diff --git a/include/criterion/assert.h b/include/criterion/assert.h index 6d796b2..23b4256 100644 --- a/include/criterion/assert.h +++ b/include/criterion/assert.h @@ -24,9 +24,17 @@ #ifndef CRITERION_ASSERT_H_ # define CRITERION_ASSERT_H_ -# include -# include -# include +# ifdef __cplusplus +# include +# include +using std::strcmp; +using std::memcmp; +# else +# include +# include +# include +# endif +# include "designated-initializer-compat.h" # include "types.h" # include "stats.h" # include "hooks.h" @@ -40,47 +48,50 @@ enum criterion_assert_kind { struct criterion_assert_args { const char *msg; - const char *default_msg; int sentinel_; + +#ifdef __cplusplus + constexpr criterion_assert_args(const char *msg) : msg(msg), sentinel_(0) {} + constexpr criterion_assert_args(const char *msg, int sentinel_) : msg(msg), sentinel_(sentinel_) {} +#endif }; -# define cr_assert_impl(Kind, Condition, ...) \ - do { \ - struct criterion_assert_args args = { \ - __VA_ARGS__ \ - }; \ - int passed = !!(Condition); \ - struct criterion_assert_stats stat = { \ - .kind = (Kind), \ - .condition = #Condition, \ - .message = args.msg ? args.msg \ - : (args.default_msg ? args.default_msg : ""), \ - .passed = passed, \ - .file = __FILE__, \ - .line = __LINE__, \ - }; \ - send_event(ASSERT, &stat, sizeof (stat)); \ - if (!passed && (Kind) == FATAL) \ - criterion_abort_test(); \ +# define CR_GET_CONDITION(Condition, ...) Condition +# define CR_GET_CONDITION_STR(Condition, ...) #Condition +# define CR_VA_SKIP(_, ...) __VA_ARGS__ + +# define cr_assert_impl(Kind, ...) \ + do { \ + struct criterion_assert_args args = { \ + CR_EXPAND(CR_VA_SKIP(__VA_ARGS__)) \ + }; \ + int passed = !!(CR_EXPAND(CR_GET_CONDITION(__VA_ARGS__))); \ + struct criterion_assert_stats stat; \ + stat.kind = (Kind); \ + stat.condition = CR_EXPAND(CR_GET_CONDITION_STR(__VA_ARGS__)); \ + stat.message = args.msg ? args.msg : ""; \ + stat.passed = passed; \ + stat.file = __FILE__; \ + stat.line = __LINE__; \ + send_event(ASSERT, &stat, sizeof (stat)); \ + if (!passed && (Kind) == FATAL) \ + criterion_abort_test(); \ } while (0) // Common asserts -# define cr_abort_test(Message) \ - cr_assert(0, \ - .default_msg = "The conditions for this test were not met.", \ - .msg = (Message) \ - ) +# define cr_abort_test(Message) \ + cr_assert(0, (Message)) -# define cr_assert(...) CR_EXPAND(cr_assert_(__VA_ARGS__, .sentinel_ = 0)) +# define cr_assert(...) CR_EXPAND(cr_assert_(__VA_ARGS__, 0)) -# define cr_expect(...) CR_EXPAND(cr_expect_(__VA_ARGS__, .sentinel_ = 0)) +# define cr_expect(...) CR_EXPAND(cr_expect_(__VA_ARGS__, 0)) # define cr_assert_(Condition, ...) CR_EXPAND(cr_assert_impl(FATAL, Condition, __VA_ARGS__)) # define cr_expect_(Condition, ...) CR_EXPAND(cr_assert_impl(NORMAL, Condition, __VA_ARGS__)) -# define cr_assert_not(...) CR_EXPAND(cr_assert_not_(__VA_ARGS__, .sentinel_ = 0)) -# define cr_expect_not(...) CR_EXPAND(cr_expect_not_(__VA_ARGS__, .sentinel_ = 0)) +# define cr_assert_not(...) CR_EXPAND(cr_assert_not_(__VA_ARGS__, 0)) +# define cr_expect_not(...) CR_EXPAND(cr_expect_not_(__VA_ARGS__, 0)) # define cr_assert_not_(Condition, ...) \ CR_EXPAND(cr_assert_impl(FATAL, !(Condition), __VA_ARGS__)) @@ -94,46 +105,46 @@ struct criterion_assert_args { # define cr_expect_op_(Op, Actual, Expected, ...) \ CR_EXPAND(cr_assert_impl(NORMAL, (Actual) Op (Expected), __VA_ARGS__)) -# define cr_assert_eq(...) CR_EXPAND(cr_assert_op_(==, __VA_ARGS__, .sentinel_ = 0)) -# define cr_expect_eq(...) CR_EXPAND(cr_expect_op_(==, __VA_ARGS__, .sentinel_ = 0)) +# define cr_assert_eq(...) CR_EXPAND(cr_assert_op_(==, __VA_ARGS__, 0)) +# define cr_expect_eq(...) CR_EXPAND(cr_expect_op_(==, __VA_ARGS__, 0)) -# define cr_assert_neq(...) CR_EXPAND(cr_assert_op_(!=, __VA_ARGS__, .sentinel_ = 0)) -# define cr_expect_neq(...) CR_EXPAND(cr_expect_op_(!=, __VA_ARGS__, .sentinel_ = 0)) +# define cr_assert_neq(...) CR_EXPAND(cr_assert_op_(!=, __VA_ARGS__, 0)) +# define cr_expect_neq(...) CR_EXPAND(cr_expect_op_(!=, __VA_ARGS__, 0)) -# define cr_assert_lt(...) CR_EXPAND(cr_assert_op_(<, __VA_ARGS__, .sentinel_ = 0)) -# define cr_expect_lt(...) CR_EXPAND(cr_expect_op_(<, __VA_ARGS__, .sentinel_ = 0)) +# define cr_assert_lt(...) CR_EXPAND(cr_assert_op_(<, __VA_ARGS__, 0)) +# define cr_expect_lt(...) CR_EXPAND(cr_expect_op_(<, __VA_ARGS__, 0)) -# define cr_assert_gt(...) CR_EXPAND(cr_assert_op_(>, __VA_ARGS__, .sentinel_ = 0)) -# define cr_expect_gt(...) CR_EXPAND(cr_expect_op_(>, __VA_ARGS__, .sentinel_ = 0)) +# define cr_assert_gt(...) CR_EXPAND(cr_assert_op_(>, __VA_ARGS__, 0)) +# define cr_expect_gt(...) CR_EXPAND(cr_expect_op_(>, __VA_ARGS__, 0)) -# define cr_assert_leq(...) CR_EXPAND(cr_assert_op_(<=, __VA_ARGS__, .sentinel_ = 0)) -# define cr_expect_leq(...) CR_EXPAND(cr_expect_op_(<=, __VA_ARGS__, .sentinel_ = 0)) +# define cr_assert_leq(...) CR_EXPAND(cr_assert_op_(<=, __VA_ARGS__, 0)) +# define cr_expect_leq(...) CR_EXPAND(cr_expect_op_(<=, __VA_ARGS__, 0)) -# define cr_assert_geq(...) CR_EXPAND(cr_assert_op_(>=, __VA_ARGS__, .sentinel_ = 0)) -# define cr_expect_geq(...) CR_EXPAND(cr_expect_op_(>=, __VA_ARGS__, .sentinel_ = 0)) +# define cr_assert_geq(...) CR_EXPAND(cr_assert_op_(>=, __VA_ARGS__, 0)) +# define cr_expect_geq(...) CR_EXPAND(cr_expect_op_(>=, __VA_ARGS__, 0)) # define cr_assert_null_(Value, ...) \ CR_EXPAND(cr_assert_impl(FATAL, (Value) == NULL, __VA_ARGS__)) # define cr_expect_null_(Value, ...) \ CR_EXPAND(cr_assert_impl(NORMAL, (Value) == NULL, __VA_ARGS__)) -# define cr_assert_null(...) CR_EXPAND(cr_assert_null_(__VA_ARGS__, .sentinel_ = 0)) -# define cr_expect_null(...) CR_EXPAND(cr_expect_null_(__VA_ARGS__, .sentinel_ = 0)) +# define cr_assert_null(...) CR_EXPAND(cr_assert_null_(__VA_ARGS__, 0)) +# define cr_expect_null(...) CR_EXPAND(cr_expect_null_(__VA_ARGS__, 0)) # define cr_assert_not_null_(Value, ...) \ CR_EXPAND(cr_assert_impl(FATAL, (Value) != NULL, __VA_ARGS__)) # define cr_expect_not_null_(Value, ...) \ CR_EXPAND(cr_assert_impl(NORMAL, (Value) != NULL, __VA_ARGS__)) -# define cr_assert_not_null(...) CR_EXPAND(cr_assert_not_null_(__VA_ARGS__, .sentinel_ = 0)) -# define cr_expect_not_null(...) CR_EXPAND(cr_expect_not_null_(__VA_ARGS__, .sentinel_ = 0)) +# define cr_assert_not_null(...) CR_EXPAND(cr_assert_not_null_(__VA_ARGS__, 0)) +# define cr_expect_not_null(...) CR_EXPAND(cr_expect_not_null_(__VA_ARGS__, 0)) // Floating-point asserts # define cr_assert_float_eq(...) \ - CR_EXPAND(cr_assert_float_eq_(__VA_ARGS__, .sentinel_ = 0)) + CR_EXPAND(cr_assert_float_eq_(__VA_ARGS__, 0)) # define cr_expect_float_eq(...) \ - CR_EXPAND(cr_expect_float_eq_(__VA_ARGS__, .sentinel_ = 0)) + CR_EXPAND(cr_expect_float_eq_(__VA_ARGS__, 0)) # define cr_assert_float_eq_(Actual, Expected, Epsilon, ...) \ CR_EXPAND(cr_assert_impl(FATAL, (Expected) - (Actual) <= (Epsilon) \ @@ -145,9 +156,9 @@ struct criterion_assert_args { __VA_ARGS__)) # define cr_assert_float_neq(...) \ - CR_EXPAND(cr_assert_float_neq_(__VA_ARGS__, .sentinel_ = 0)) + CR_EXPAND(cr_assert_float_neq_(__VA_ARGS__, 0)) # define cr_expect_float_neq(...) \ - CR_EXPAND(cr_expect_float_neq_(__VA_ARGS__, .sentinel_ = 0)) + CR_EXPAND(cr_expect_float_neq_(__VA_ARGS__, 0)) # define cr_assert_float_neq_(Actual, Expected, Epsilon, ...) \ CR_EXPAND(cr_assert_impl(FATAL, (Expected) - (Actual) > (Epsilon) \ @@ -166,55 +177,51 @@ struct criterion_assert_args { CR_EXPAND(cr_assert_impl(NORMAL, strcmp((Actual), (Expected)) Op 0, __VA_ARGS__)) # define cr_assert_strings_eq(...) \ - CR_EXPAND(cr_assert_strings_(==, __VA_ARGS__, .sentinel_ = 0)) + CR_EXPAND(cr_assert_strings_(==, __VA_ARGS__, 0)) # define cr_expect_strings_eq(...) \ - CR_EXPAND(cr_expect_strings_(==, __VA_ARGS__, .sentinel_ = 0)) + CR_EXPAND(cr_expect_strings_(==, __VA_ARGS__, 0)) # define cr_assert_strings_neq(...) \ - CR_EXPAND(cr_assert_strings_(!=, __VA_ARGS__, .sentinel_ = 0)) + CR_EXPAND(cr_assert_strings_(!=, __VA_ARGS__, 0)) # define cr_expect_strings_neq(...) \ - CR_EXPAND(cr_expect_strings_(!=, __VA_ARGS__, .sentinel_ = 0)) + CR_EXPAND(cr_expect_strings_(!=, __VA_ARGS__, 0)) -# define cr_assert_strings_gt(...) CR_EXPAND(cr_assert_strings_(>, __VA_ARGS__, .sentinel_ = 0)) -# define cr_expect_strings_gt(...) CR_EXPAND(cr_expect_strings_(>, __VA_ARGS__, .sentinel_ = 0)) +# define cr_assert_strings_gt(...) CR_EXPAND(cr_assert_strings_(>, __VA_ARGS__, 0)) +# define cr_expect_strings_gt(...) CR_EXPAND(cr_expect_strings_(>, __VA_ARGS__, 0)) -# define cr_assert_strings_lt(...) CR_EXPAND(cr_assert_strings_(<, __VA_ARGS__, .sentinel_ = 0)) -# define cr_expect_strings_lt(...) CR_EXPAND(cr_expect_strings_(<, __VA_ARGS__, .sentinel_ = 0)) +# define cr_assert_strings_lt(...) CR_EXPAND(cr_assert_strings_(<, __VA_ARGS__, 0)) +# define cr_expect_strings_lt(...) CR_EXPAND(cr_expect_strings_(<, __VA_ARGS__, 0)) -# define cr_assert_strings_leq(...) CR_EXPAND(cr_assert_strings_(<=, __VA_ARGS__, .sentinel_ = 0)) -# define cr_expect_strings_leq(...) CR_EXPAND(cr_expect_strings_(<=, __VA_ARGS__, .sentinel_ = 0)) +# define cr_assert_strings_leq(...) CR_EXPAND(cr_assert_strings_(<=, __VA_ARGS__, 0)) +# define cr_expect_strings_leq(...) CR_EXPAND(cr_expect_strings_(<=, __VA_ARGS__, 0)) -# define cr_assert_strings_geq(...) CR_EXPAND(cr_assert_strings_(>=, __VA_ARGS__, .sentinel_ = 0)) -# define cr_expect_strings_geq(...) CR_EXPAND(cr_expect_strings_(>=, __VA_ARGS__, .sentinel_ = 0)) +# define cr_assert_strings_geq(...) CR_EXPAND(cr_assert_strings_(>=, __VA_ARGS__, 0)) +# define cr_expect_strings_geq(...) CR_EXPAND(cr_expect_strings_(>=, __VA_ARGS__, 0)) // Array asserts # define cr_assert_arrays_eq(...) \ - CR_EXPAND(cr_assert_arrays_eq_(__VA_ARGS__, .sentinel_ = 0)) + CR_EXPAND(cr_assert_arrays_eq_(__VA_ARGS__, 0)) # define cr_expect_arrays_eq(...) \ - CR_EXPAND(cr_expect_arrays_eq_(__VA_ARGS__, .sentinel_ = 0)) + CR_EXPAND(cr_expect_arrays_eq_(__VA_ARGS__, 0)) # define cr_assert_arrays_neq(...) \ - CR_EXPAND(cr_assert_arrays_neq_(__VA_ARGS__, .sentinel_ = 0)) + CR_EXPAND(cr_assert_arrays_neq_(__VA_ARGS__, 0)) # define cr_expect_arrays_neq(...) \ - CR_EXPAND(cr_expect_arrays_neq_(__VA_ARGS__, .sentinel_ = 0)) + CR_EXPAND(cr_expect_arrays_neq_(__VA_ARGS__, 0)) -# define cr_assert_arrays_eq_(A, B, Size, ...) \ +# define cr_assert_arrays_eq_(A, B, Size, ...) \ CR_EXPAND(cr_assert_impl(FATAL, !memcmp((A), (B), (Size)), \ - .default_msg = "Arrays are not equal.", \ __VA_ARGS__)) -# define cr_expect_arrays_eq_(A, B, Size, ...) \ +# define cr_expect_arrays_eq_(A, B, Size, ...) \ CR_EXPAND(cr_assert_impl(NORMAL, !memcmp((A), (B), (Size)), \ - .default_msg = "Arrays are not equal.", \ __VA_ARGS__)) -# define cr_assert_arrays_neq_(A, B, Size, ...) \ +# define cr_assert_arrays_neq_(A, B, Size, ...) \ CR_EXPAND(cr_assert_impl(FATAL, memcmp((A), (B), (Size)), \ - .default_msg = "Arrays are equal", \ __VA_ARGS__)) -# define cr_expect_arrays_neq_(A, B, Size, ...) \ +# define cr_expect_arrays_neq_(A, B, Size, ...) \ CR_EXPAND(cr_assert_impl(NORMAL, memcmp((A), (B), (Size)), \ - .default_msg = "Arrays are equal", \ __VA_ARGS__)) # ifdef __GNUC__ @@ -230,7 +237,6 @@ struct criterion_assert_args { do { \ CRIT_ARR_COMPARE_(A, B, Size, Cmp, equals); \ cr_assert_impl(FATAL, equals, \ - .default_msg = "Arrays are not equal", \ __VA_ARGS__); \ } while (0) @@ -238,20 +244,18 @@ struct criterion_assert_args { do { \ CRIT_ARR_COMPARE_(A, B, Size, Cmp, equals); \ cr_assert_impl(NORMAL, equals, \ - .default_msg = "Arrays are not equal", \ __VA_ARGS__); \ } while (0) # define cr_assert_arrays_eq_cmp(...) \ - cr_assert_arrays_eq_cmp_(__VA_ARGS__, .sentinel_ = 0) + cr_assert_arrays_eq_cmp_(__VA_ARGS__, 0) # define cr_expect_arrays_eq_cmp(...) \ - cr_expect_arrays_eq_cmp_(__VA_ARGS__, .sentinel_ = 0) + cr_expect_arrays_eq_cmp_(__VA_ARGS__, 0) # define cr_assert_arrays_neq_cmp_(A, B, Size, Cmp, ...) \ do { \ CRIT_ARR_COMPARE_(A, B, Size, Cmp, equals); \ cr_assert_impl(FATAL, !equals, \ - .default_msg = "Arrays not equal", \ __VA_ARGS__); \ } while (0) @@ -259,14 +263,13 @@ struct criterion_assert_args { do { \ CRIT_ARR_COMPARE_(A, B, Size, Cmp, equals); \ cr_assert_impl(NORMAL, equals, \ - .default_msg = "Arrays not equal", \ __VA_ARGS__); \ } while (0) # define cr_assert_arrays_neq_cmp(...) \ - cr_assert_arrays_eq_cmp_(__VA_ARGS__, .sentinel_ = 0) + cr_assert_arrays_eq_cmp_(__VA_ARGS__, 0) # define cr_expect_arrays_neq_cmp(...) \ - cr_expect_arrays_eq_cmp_(__VA_ARGS__, .sentinel_ = 0) + cr_expect_arrays_eq_cmp_(__VA_ARGS__, 0) # endif /* !__GNUC__ */ // The section below is here for backward compatibility purposes. diff --git a/include/criterion/common.h b/include/criterion/common.h index 238a9c2..5ee86a9 100644 --- a/include/criterion/common.h +++ b/include/criterion/common.h @@ -43,12 +43,22 @@ # endif # endif +# ifdef __cplusplus +# define CR_ATTRIBUTE(Arg) [[gnu::Arg]] +# define CR_BEGIN_C_API extern "C" { +# define CR_END_C_API } +# else +# define CR_ATTRIBUTE(Arg) __attribute__((Arg)) +# define CR_BEGIN_C_API +# define CR_END_C_API +# endif + # ifdef __APPLE__ # define SECTION_START_PREFIX __first # define SECTION_END_PREFIX __last # define SECTION_START_SUFFIX(Name) __asm("section$start$__DATA$" Name) # define SECTION_END_SUFFIX(Name) __asm("section$end$__DATA$" Name) -# define SECTION_(Name) __attribute__((section("__DATA," Name))) +# define SECTION_(Name) CR_ATTRIBUTE(section("__DATA," Name) # define SECTION_SUFFIX_ # elif CR_IS_MSVC # define SECTION_START_PREFIX __start @@ -66,7 +76,7 @@ # define SECTION_END_PREFIX __stop # define SECTION_START_SUFFIX(Name) # define SECTION_END_SUFFIX(Name) -# define SECTION_(Name) __attribute__((section(Name))) +# define SECTION_(Name) CR_ATTRIBUTE(section(Name)) # define SECTION_SUFFIX_ # endif @@ -89,8 +99,8 @@ Type *const SECTION_END(Name) = &SECTION_END_(Name) # ifdef __GNUC__ -# define UNUSED __attribute__((unused)) -# define NORETURN __attribute__((noreturn)) +# define UNUSED CR_ATTRIBUTE(unused) +# define NORETURN CR_ATTRIBUTE(noreturn) # elif CR_IS_MSVC # define UNUSED # define NORETURN __declspec(noreturn) @@ -106,7 +116,7 @@ # endif # ifdef __GNUC__ -# define FORMAT(Archetype, Index, Ftc) __attribute__((format(Archetype, Index, Ftc))) +# define FORMAT(Archetype, Index, Ftc) CR_ATTRIBUTE(format(Archetype, Index, Ftc)) # else # define FORMAT(Archetype, Index, Ftc) # endif @@ -114,13 +124,13 @@ # if defined _WIN32 || defined __CYGWIN__ # ifdef CRITERION_BUILDING_DLL # ifdef __GNUC__ -# define CR_API __attribute__ ((dllexport)) +# define CR_API CR_ATTRIBUTE(dllexport) # else # define CR_API __declspec(dllexport) # endif # else # ifdef __GNUC__ -# define CR_API __attribute__ ((dllimport)) +# define CR_API CR_ATTRIBUTE(dllimport) # else # define CR_API __declspec(dllimport) # endif @@ -128,8 +138,8 @@ # define CR_LOCAL # else # if __GNUC__ >= 4 -# define CR_API __attribute__ ((visibility ("default"))) -# define CR_LOCAL __attribute__ ((visibility ("hidden"))) +# define CR_API CR_ATTRIBUTE(visibility("default")) +# define CR_LOCAL CR_ATTRIBUTE(visibility("hidden")) # else # define CR_API # define CR_LOCAL diff --git a/include/criterion/criterion.h b/include/criterion/criterion.h index 51c82fd..bc82ccc 100644 --- a/include/criterion/criterion.h +++ b/include/criterion/criterion.h @@ -24,14 +24,21 @@ #ifndef CRITERION_H_ # define CRITERION_H_ +# include "designated-initializer-compat.h" # include "common.h" -# include "assert.h" # include "types.h" +# include "assert.h" # define IDENTIFIER_(Category, Name, Suffix) \ Category ## _ ## Name ## _ ## Suffix -# define TEST_PROTOTYPE_(Category, Name) \ + +# ifdef __cplusplus +# define TEST_PROTOTYPE_(Category, Name) \ + extern "C" void IDENTIFIER_(Category, Name, impl)(void) +# else +# define TEST_PROTOTYPE_(Category, Name) \ void IDENTIFIER_(Category, Name, impl)(void) +# endif # define SUITE_IDENTIFIER_(Name, Suffix) \ suite_ ## Name ## _ ## Suffix @@ -39,34 +46,40 @@ # define Test(...) CR_EXPAND(Test_(__VA_ARGS__, .sentinel_ = 0)) # define Test_(Category, Name, ...) \ TEST_PROTOTYPE_(Category, Name); \ - struct criterion_test_extra_data IDENTIFIER_(Category, Name, extra) = { \ - .identifier_ = #Category "/" #Name, \ - .file_ = __FILE__, \ - .line_ = __LINE__, \ - __VA_ARGS__ \ - }; \ + struct criterion_test_extra_data IDENTIFIER_(Category, Name, extra) = \ + CR_EXPAND(CRITERION_MAKE_STRUCT(struct criterion_test_extra_data, \ + .identifier_ = #Category "/" #Name, \ + .file_ = __FILE__, \ + .line_ = __LINE__, \ + __VA_ARGS__ \ + )); \ SECTION_("cr_tst") \ const struct criterion_test IDENTIFIER_(Category, Name, meta) = { \ - .name = #Name, \ - .category = #Category, \ - .test = IDENTIFIER_(Category, Name, impl), \ - .data = &IDENTIFIER_(Category, Name, extra) \ + #Name, \ + #Category, \ + IDENTIFIER_(Category, Name, impl), \ + &IDENTIFIER_(Category, Name, extra) \ } SECTION_SUFFIX_; \ TEST_PROTOTYPE_(Category, Name) # define TestSuite(...) CR_EXPAND(TestSuite_(__VA_ARGS__, .sentinel_ = 0)) # define TestSuite_(Name, ...) \ - struct criterion_test_extra_data SUITE_IDENTIFIER_(Name, extra) = { \ - .file_ = __FILE__, \ - .line_ = 0, \ - __VA_ARGS__ \ - }; \ + struct criterion_test_extra_data SUITE_IDENTIFIER_(Name, extra) = \ + CR_EXPAND(CRITERION_MAKE_STRUCT(struct criterion_test_extra_data, \ + .file_ = __FILE__, \ + .line_ = 0, \ + __VA_ARGS__ \ + )); \ SECTION_("cr_sts") \ const struct criterion_suite SUITE_IDENTIFIER_(Name, meta) = { \ - .name = #Name, \ - .data = &SUITE_IDENTIFIER_(Name, extra), \ + #Name, \ + &SUITE_IDENTIFIER_(Name, extra), \ } SECTION_SUFFIX_ +CR_BEGIN_C_API + CR_API int criterion_run_all_tests(void); +CR_END_C_API + #endif /* !CRITERION_H_ */ diff --git a/include/criterion/designated-initializer-compat.h b/include/criterion/designated-initializer-compat.h new file mode 100644 index 0000000..910952b --- /dev/null +++ b/include/criterion/designated-initializer-compat.h @@ -0,0 +1,124 @@ +/* + * The MIT License (MIT) + * + * Copyright © 2015 Franklin "Snaipe" Mathieu + * + * 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. + */ +#ifndef CRITERION_DESIGNATED_INITIALIZER_COMPAT_HH_ +# define CRITERION_DESIGNATED_INITIALIZER_COMPAT_HH_ + +# include "common.h" + +# define CRITERION_ARG_LENGTH(...) CR_EXPAND(CRITERION_ARG_LENGTH_(__VA_ARGS__,\ + 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45,\ + 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26,\ + 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6,\ + 5, 4, 3, 2, 1, 0)) +# define CRITERION_ARG_LENGTH_(_63, _62, _61, _60, _59, _58, _57, _56, _55, _54, _53, \ + _52, _51, _50, _49, _48, _47, _46, _45, _44, _43, _42, _41, _40, _39, _38, \ + _37, _36, _35, _34, _33, _32, _31, _30, _29, _28, _27, _26, _25, _24, _23, \ + _22, _21, _20, _19, _18, _17, _16, _15, _14, _13, _12, _11, _10, _9, _8, \ + _7, _6, _5, _4, _3, _2, _1, count, ...) count + +# define CRITERION_APPLY_1(Macro, ...) +# define CRITERION_APPLY_2(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_1(Macro, Prefix, __VA_ARGS__)) +# define CRITERION_APPLY_3(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_2(Macro, Prefix, __VA_ARGS__)) +# define CRITERION_APPLY_4(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_3(Macro, Prefix, __VA_ARGS__)) +# define CRITERION_APPLY_5(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_4(Macro, Prefix, __VA_ARGS__)) +# define CRITERION_APPLY_6(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_5(Macro, Prefix, __VA_ARGS__)) +# define CRITERION_APPLY_7(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_6(Macro, Prefix, __VA_ARGS__)) +# define CRITERION_APPLY_8(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_7(Macro, Prefix, __VA_ARGS__)) +# define CRITERION_APPLY_9(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_8(Macro, Prefix, __VA_ARGS__)) +# define CRITERION_APPLY_10(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_9(Macro, Prefix, __VA_ARGS__)) +# define CRITERION_APPLY_11(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_10(Macro, Prefix, __VA_ARGS__)) +# define CRITERION_APPLY_12(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_11(Macro, Prefix, __VA_ARGS__)) +# define CRITERION_APPLY_13(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_12(Macro, Prefix, __VA_ARGS__)) +# define CRITERION_APPLY_14(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_13(Macro, Prefix, __VA_ARGS__)) +# define CRITERION_APPLY_15(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_14(Macro, Prefix, __VA_ARGS__)) +# define CRITERION_APPLY_16(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_15(Macro, Prefix, __VA_ARGS__)) +# define CRITERION_APPLY_17(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_16(Macro, Prefix, __VA_ARGS__)) +# define CRITERION_APPLY_18(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_17(Macro, Prefix, __VA_ARGS__)) +# define CRITERION_APPLY_19(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_18(Macro, Prefix, __VA_ARGS__)) +# define CRITERION_APPLY_20(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_19(Macro, Prefix, __VA_ARGS__)) +# define CRITERION_APPLY_21(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_20(Macro, Prefix, __VA_ARGS__)) +# define CRITERION_APPLY_22(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_21(Macro, Prefix, __VA_ARGS__)) +# define CRITERION_APPLY_23(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_22(Macro, Prefix, __VA_ARGS__)) +# define CRITERION_APPLY_24(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_23(Macro, Prefix, __VA_ARGS__)) +# define CRITERION_APPLY_25(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_24(Macro, Prefix, __VA_ARGS__)) +# define CRITERION_APPLY_26(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_25(Macro, Prefix, __VA_ARGS__)) +# define CRITERION_APPLY_27(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_26(Macro, Prefix, __VA_ARGS__)) +# define CRITERION_APPLY_28(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_27(Macro, Prefix, __VA_ARGS__)) +# define CRITERION_APPLY_29(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_28(Macro, Prefix, __VA_ARGS__)) +# define CRITERION_APPLY_30(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_29(Macro, Prefix, __VA_ARGS__)) +# define CRITERION_APPLY_31(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_30(Macro, Prefix, __VA_ARGS__)) +# define CRITERION_APPLY_32(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_31(Macro, Prefix, __VA_ARGS__)) +# define CRITERION_APPLY_33(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_32(Macro, Prefix, __VA_ARGS__)) +# define CRITERION_APPLY_34(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_33(Macro, Prefix, __VA_ARGS__)) +# define CRITERION_APPLY_35(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_34(Macro, Prefix, __VA_ARGS__)) +# define CRITERION_APPLY_36(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_35(Macro, Prefix, __VA_ARGS__)) +# define CRITERION_APPLY_37(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_36(Macro, Prefix, __VA_ARGS__)) +# define CRITERION_APPLY_38(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_37(Macro, Prefix, __VA_ARGS__)) +# define CRITERION_APPLY_39(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_38(Macro, Prefix, __VA_ARGS__)) +# define CRITERION_APPLY_40(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_39(Macro, Prefix, __VA_ARGS__)) +# define CRITERION_APPLY_41(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_40(Macro, Prefix, __VA_ARGS__)) +# define CRITERION_APPLY_42(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_41(Macro, Prefix, __VA_ARGS__)) +# define CRITERION_APPLY_43(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_42(Macro, Prefix, __VA_ARGS__)) +# define CRITERION_APPLY_44(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_43(Macro, Prefix, __VA_ARGS__)) +# define CRITERION_APPLY_45(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_44(Macro, Prefix, __VA_ARGS__)) +# define CRITERION_APPLY_46(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_45(Macro, Prefix, __VA_ARGS__)) +# define CRITERION_APPLY_47(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_46(Macro, Prefix, __VA_ARGS__)) +# define CRITERION_APPLY_48(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_47(Macro, Prefix, __VA_ARGS__)) +# define CRITERION_APPLY_49(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_48(Macro, Prefix, __VA_ARGS__)) +# define CRITERION_APPLY_50(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_49(Macro, Prefix, __VA_ARGS__)) +# define CRITERION_APPLY_51(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_50(Macro, Prefix, __VA_ARGS__)) +# define CRITERION_APPLY_52(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_51(Macro, Prefix, __VA_ARGS__)) +# define CRITERION_APPLY_53(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_52(Macro, Prefix, __VA_ARGS__)) +# define CRITERION_APPLY_54(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_53(Macro, Prefix, __VA_ARGS__)) +# define CRITERION_APPLY_55(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_54(Macro, Prefix, __VA_ARGS__)) +# define CRITERION_APPLY_56(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_55(Macro, Prefix, __VA_ARGS__)) +# define CRITERION_APPLY_57(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_56(Macro, Prefix, __VA_ARGS__)) +# define CRITERION_APPLY_58(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_57(Macro, Prefix, __VA_ARGS__)) +# define CRITERION_APPLY_59(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_58(Macro, Prefix, __VA_ARGS__)) +# define CRITERION_APPLY_60(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_59(Macro, Prefix, __VA_ARGS__)) +# define CRITERION_APPLY_61(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_60(Macro, Prefix, __VA_ARGS__)) +# define CRITERION_APPLY_62(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_61(Macro, Prefix, __VA_ARGS__)) +# define CRITERION_APPLY_63(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_62(Macro, Prefix, __VA_ARGS__)) +# define CRITERION_APPLY_64(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_63(Macro, Prefix, __VA_ARGS__)) +# define CRITERION_APPLY_65(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_64(Macro, Prefix, __VA_ARGS__)) + +# define CRITERION_APPLY__(Macro, Prefix, n, ...) CR_EXPAND(CRITERION_APPLY_##n(Macro, Prefix, __VA_ARGS__)) +# define CRITERION_APPLY_(Macro, n, Prefix, ...) CR_EXPAND(CRITERION_APPLY__(Macro, Prefix, n, __VA_ARGS__)) +# define CRITERION_APPLY(Macro, ...) CR_EXPAND(CRITERION_APPLY_(Macro, CRITERION_ARG_LENGTH(__VA_ARGS__), __VA_ARGS__)) + +# define CRITERION_ADD_PREFIX_ONCE(Prefix, Field, ...) Prefix Field; +# define CRITERION_ADD_PREFIX(...) \ + CR_EXPAND(CRITERION_APPLY(CRITERION_ADD_PREFIX_ONCE, __VA_ARGS__)) + +# ifdef __cplusplus +# define CRITERION_MAKE_STRUCT(Type, ...) [&]() { \ + Type t; \ + CR_EXPAND(CRITERION_ADD_PREFIX(t, __VA_ARGS__)) \ + return t; \ + }() +# else +# define CRITERION_MAKE_STRUCT(Type, ...) { __VA_ARGS__ } +# endif + +#endif /* !CRITERION_DESIGNATED_INITIALIZER_COMPAT_HH_ */ diff --git a/include/criterion/event.h b/include/criterion/event.h index db6cfe3..37881db 100644 --- a/include/criterion/event.h +++ b/include/criterion/event.h @@ -24,12 +24,21 @@ #ifndef CRITERION_EVENT_H_ # define CRITERION_EVENT_H_ -# include -# include +# ifdef __cplusplus +# include +# include +# else +# include +# include +# endif # include "common.h" +CR_BEGIN_C_API + extern FILE *g_event_pipe; CR_API void send_event(int kind, void *data, size_t size); +CR_END_C_API + #endif /* !CRITERION_EVENT_H_ */ diff --git a/include/criterion/hooks.h b/include/criterion/hooks.h index 0c86841..098790a 100644 --- a/include/criterion/hooks.h +++ b/include/criterion/hooks.h @@ -25,6 +25,7 @@ # define CRITERION_HOOKS_H_ # include "common.h" +# include "types.h" typedef enum { PRE_ALL, @@ -46,8 +47,13 @@ typedef void (*f_report_hook)(); # define HOOK_IDENTIFIER__(Line, Suffix) HOOK_IDENTIFIER___(Line, Suffix) # define HOOK_IDENTIFIER___(Line, Suffix) hook_l ## Line ## _ ## Suffix -# define HOOK_PROTOTYPE_ \ +# ifdef __cplusplus +# define HOOK_PROTOTYPE_ \ + extern "C" void HOOK_IDENTIFIER_(impl) +# else +# define HOOK_PROTOTYPE_ \ void HOOK_IDENTIFIER_(impl) +# endif // Section abbreviations # define HOOK_SECTION_PRE_ALL cr_pra @@ -68,10 +74,24 @@ typedef void (*f_report_hook)(); # define HOOK_SECTION_STRINGIFY_(Sec) HOOK_SECTION_STRINGIFY__(Sec) # define HOOK_SECTION_STRINGIFY(Kind) HOOK_SECTION_STRINGIFY_(HOOK_SECTION(Kind)) +# define HOOK_PARAM_TYPE_PRE_ALL struct criterion_test_set * +# define HOOK_PARAM_TYPE_PRE_SUITE struct criterion_suite_set * +# define HOOK_PARAM_TYPE_PRE_INIT struct criterion_test * +# define HOOK_PARAM_TYPE_PRE_TEST struct criterion_test * +# define HOOK_PARAM_TYPE_ASSERT struct criterion_assert_stats * +# define HOOK_PARAM_TYPE_THEORY_FAIL struct criterion_theory_stats * +# define HOOK_PARAM_TYPE_TEST_CRASH struct criterion_test_stats * +# define HOOK_PARAM_TYPE_POST_TEST struct criterion_test_stats * +# define HOOK_PARAM_TYPE_POST_FINI struct criterion_test_stats * +# define HOOK_PARAM_TYPE_POST_SUITE struct criterion_suite_stats * +# define HOOK_PARAM_TYPE_POST_ALL struct criterion_global_stats * + +# define HOOK_PARAM_TYPE(Kind) HOOK_PARAM_TYPE_ ## Kind + # define ReportHook(Kind) \ - HOOK_PROTOTYPE_(); \ + HOOK_PROTOTYPE_(HOOK_PARAM_TYPE(Kind)); \ SECTION_(HOOK_SECTION_STRINGIFY(Kind)) \ - const f_report_hook HOOK_IDENTIFIER_(func) = HOOK_IDENTIFIER_(impl); \ + const f_report_hook HOOK_IDENTIFIER_(func) = (f_report_hook) HOOK_IDENTIFIER_(impl); \ HOOK_PROTOTYPE_ #endif /* !CRITERION_HOOKS_H_ */ diff --git a/include/criterion/logging.h b/include/criterion/logging.h index 7cd74f7..c8c0205 100644 --- a/include/criterion/logging.h +++ b/include/criterion/logging.h @@ -24,8 +24,13 @@ #ifndef CRITERION_LOGGING_H_ # define CRITERION_LOGGING_H_ -# include -# include +# ifdef __cplusplus +# include +using std::va_list; +# else +# include +# include +# endif # include "common.h" # include "ordered-set.h" # include "stats.h" @@ -67,6 +72,8 @@ struct criterion_prefix_data { # define RESET CRIT_COLOR_NORMALIZE(CRIT_RESET) # endif +CR_BEGIN_C_API + extern const struct criterion_prefix_data g_criterion_logging_prefixes[]; # define CRITERION_PREFIX_DASHES (&g_criterion_logging_prefixes[CRITERION_LOGGING_PREFIX_DASHES]) @@ -109,6 +116,8 @@ struct criterion_output_provider { extern struct criterion_output_provider normal_logging; extern struct criterion_output_provider tap_logging; +CR_END_C_API + #define NORMAL_LOGGING (&normal_logging) #define TAP_LOGGING (&tap_logging) diff --git a/include/criterion/options.h b/include/criterion/options.h index 31b90d2..0bdcdee 100644 --- a/include/criterion/options.h +++ b/include/criterion/options.h @@ -38,6 +38,10 @@ struct criterion_options { bool short_filename; }; +CR_BEGIN_C_API + extern struct criterion_options criterion_options; +CR_END_C_API + #endif /*!CRITERION_OPTIONS_H_ */ diff --git a/include/criterion/ordered-set.h b/include/criterion/ordered-set.h index 514f601..24044f8 100644 --- a/include/criterion/ordered-set.h +++ b/include/criterion/ordered-set.h @@ -40,15 +40,7 @@ struct criterion_ordered_set_node { char data[0]; }; -struct criterion_suite_set { - struct criterion_suite suite; - struct criterion_ordered_set *tests; -}; - -struct criterion_test_set { - struct criterion_ordered_set *suites; - size_t tests; -}; +CR_BEGIN_C_API CR_API struct criterion_ordered_set *new_ordered_set(f_criterion_cmp cmp, void (*dtor)(void *, void *)); @@ -57,6 +49,8 @@ CR_API void *insert_ordered_set(struct criterion_ordered_set *l, void *ptr, size_t size); +CR_END_C_API + # define FOREACH_SET(Elt, Set) \ for (struct criterion_ordered_set_node *n = Set->first; n; n = n->next) \ for (int cond = 1; cond;) \ diff --git a/include/criterion/theories.h b/include/criterion/theories.h index 6e23345..f23c223 100644 --- a/include/criterion/theories.h +++ b/include/criterion/theories.h @@ -27,6 +27,8 @@ # include # include "criterion.h" +CR_BEGIN_C_API + struct criterion_theory_context; CR_API struct criterion_theory_context* cr_theory_init(void); @@ -114,4 +116,6 @@ CR_API void cr_theory_main(struct criterion_datapoints *dps, size_t datapoints, } \ void CR_EXPAND(CR_VAARG_ID(theory, __VA_ARGS__,))Args +CR_END_C_API + #endif /* !CRITERION_THEORIES_H_ */ diff --git a/include/criterion/types.h b/include/criterion/types.h index 9acd208..aa05e03 100644 --- a/include/criterion/types.h +++ b/include/criterion/types.h @@ -24,8 +24,13 @@ #ifndef CRITERION_TYPES_H_ # define CRITERION_TYPES_H_ -# include -# include +# ifdef __cplusplus +# include +using std::size_t; +# else +# include +# include +# endif # include "common.h" struct criterion_test_extra_data { @@ -54,6 +59,18 @@ struct criterion_suite { struct criterion_test_extra_data *data; }; +struct criterion_ordered_set; + +struct criterion_suite_set { + struct criterion_suite suite; + struct criterion_ordered_set *tests; +}; + +struct criterion_test_set { + struct criterion_ordered_set *suites; + size_t tests; +}; + typedef void (*f_worker_func)(struct criterion_test *, struct criterion_suite *); #endif /* !CRITERION_TYPES_H_ */ diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt index d8e1d14..386710a 100644 --- a/samples/CMakeLists.txt +++ b/samples/CMakeLists.txt @@ -1,5 +1,6 @@ if (NOT MSVC) set(CMAKE_C_FLAGS "-std=c99 -Wall -Wextra -pedantic") + set(CMAKE_CXX_FLAGS "-std=c++11 -Wall -Wextra -pedantic") endif () include_directories(../include) @@ -40,6 +41,13 @@ foreach(sample ${SAMPLES}) ENVIRONMENT "CRITERION_ALWAYS_SUCCEED=1" ) + add_executable(${sample}_cpp ${sample}.cc) + target_link_libraries(${sample}_cpp criterion) + add_test(${sample}_cpp ${sample}_cpp) + set_property(TEST ${sample} PROPERTY + ENVIRONMENT "CRITERION_ALWAYS_SUCCEED=1" + ) + if (NOT MSVC) # we disable the scripted tests when building with MSVC add_test(${sample}_compare sh ${CMAKE_CURRENT_LIST_DIR}/tests/run_test.sh "${CMAKE_CURRENT_LIST_DIR}" . . ${sample}) set_property(TEST ${sample}_compare PROPERTY diff --git a/samples/asserts.c b/samples/asserts.c index 6b44cb9..ef5bc98 100644 --- a/samples/asserts.c +++ b/samples/asserts.c @@ -6,8 +6,6 @@ Test(asserts, base) { cr_assert(true, "Assertions may take failure messages"); - cr_assert(true, .msg = "You can use explicit named arguments"); - cr_expect(false, "assert is fatal, expect isn't"); cr_assert(false, "This assert runs"); cr_assert(false, "This does not"); diff --git a/samples/report.c b/samples/report.c index 4c7a849..8c9ace8 100644 --- a/samples/report.c +++ b/samples/report.c @@ -15,10 +15,12 @@ ReportHook(POST_TEST)(struct criterion_test_stats *stats) { stats->passed_asserts, stats->failed_asserts, stats->passed_asserts + stats->failed_asserts); } -ReportHook(PRE_ALL)() { +ReportHook(PRE_ALL)(struct criterion_test_set *tests) { + (void) tests; puts("criterion_init"); } -ReportHook(POST_ALL)() { +ReportHook(POST_ALL)(struct criterion_global_stats *stats) { + (void) stats; puts("criterion_fini"); } diff --git a/src/report.c b/src/report.c index 5809bfd..9a6f80e 100644 --- a/src/report.c +++ b/src/report.c @@ -83,15 +83,15 @@ IMPL_CALL_REPORT_HOOKS(POST_FINI); IMPL_CALL_REPORT_HOOKS(POST_SUITE); IMPL_CALL_REPORT_HOOKS(POST_ALL); -ReportHook(PRE_ALL)() {} -ReportHook(PRE_SUITE)() {} -ReportHook(PRE_INIT)() {} -ReportHook(PRE_TEST)() {} -ReportHook(ASSERT)() {} -ReportHook(THEORY_FAIL)() {} -ReportHook(TEST_CRASH)() {} -ReportHook(POST_TEST)() {} -ReportHook(POST_FINI)() {} -ReportHook(POST_SUITE)() {} -ReportHook(POST_ALL)() {} +ReportHook(PRE_ALL)(UNUSED struct criterion_test_set *arg) {} +ReportHook(PRE_SUITE)(UNUSED struct criterion_suite_set *arg) {} +ReportHook(PRE_INIT)(UNUSED struct criterion_test *arg) {} +ReportHook(PRE_TEST)(UNUSED struct criterion_test *arg) {} +ReportHook(ASSERT)(UNUSED struct criterion_assert_stats *arg) {} +ReportHook(THEORY_FAIL)(UNUSED struct criterion_theory_stats *arg) {} +ReportHook(TEST_CRASH)(UNUSED struct criterion_test_stats *arg) {} +ReportHook(POST_TEST)(UNUSED struct criterion_test_stats *arg) {} +ReportHook(POST_FINI)(UNUSED struct criterion_test_stats *arg) {} +ReportHook(POST_SUITE)(UNUSED struct criterion_suite_stats *arg) {} +ReportHook(POST_ALL)(UNUSED struct criterion_global_stats *arg) {} From 496710164ed74e46cab80a8e42a35d43e2f4af92 Mon Sep 17 00:00:00 2001 From: Snaipe Date: Mon, 7 Sep 2015 01:42:15 +0200 Subject: [PATCH 02/23] Refactored samples for cmake compilation --- samples/CMakeLists.txt | 51 ++++++++++--------- ...rr.expected => asserts.c.bin.err.expected} | 6 +-- ...ut.expected => asserts.c.bin.out.expected} | 0 samples/asserts.cc.bin.err.expected | 6 +++ ...t.expected => asserts.cc.bin.out.expected} | 0 ...xpected => description.c.bin.err.expected} | 0 ...xpected => description.c.bin.out.expected} | 0 samples/description.cc.bin.err.expected | 3 ++ ...pected => description.cc.bin.out.expected} | 0 ...t.err.expected => exit.c.bin.err.expected} | 0 ...s.out.expected => exit.c.bin.out.expected} | 0 samples/exit.cc.bin.err.expected | 4 ++ ....out.expected => exit.cc.bin.out.expected} | 0 ...r.expected => fixtures.c.bin.err.expected} | 0 ...t.expected => fixtures.c.bin.out.expected} | 0 samples/fixtures.cc.bin.err.expected | 1 + samples/fixtures.cc.bin.out.expected | 2 + ...ected => long-messages.c.bin.err.expected} | 0 ...ected => long-messages.c.bin.out.expected} | 0 samples/long-messages.cc.bin.err.expected | 6 +++ ...cted => long-messages.cc.bin.out.expected} | 0 ...xpected => more-suites.c.bin.err.expected} | 0 ...xpected => more-suites.c.bin.out.expected} | 0 ...pected => more-suites.cc.bin.err.expected} | 0 samples/more-suites.cc.bin.out.expected | 0 ...ected => other-crashes.c.bin.err.expected} | 0 samples/other-crashes.c.bin.out.expected | 0 samples/other-crashes.cc.bin.err.expected | 3 ++ samples/other-crashes.cc.bin.out.expected | 0 ...err.expected => report.c.bin.err.expected} | 0 ...out.expected => report.c.bin.out.expected} | 0 samples/report.cc.bin.err.expected | 3 ++ samples/report.cc.bin.out.expected | 4 ++ ...err.expected => signal.c.bin.err.expected} | 0 samples/signal.c.bin.out.expected | 0 samples/signal.cc.bin.err.expected | 4 ++ samples/signal.cc.bin.out.expected | 0 ...err.expected => simple.c.bin.err.expected} | 0 samples/simple.c.bin.out.expected | 0 samples/simple.cc.bin.err.expected | 3 ++ samples/simple.cc.bin.out.expected | 0 samples/suites.c.bin.err.expected | 1 + samples/suites.c.bin.out.expected | 0 samples/suites.cc.bin.err.expected | 1 + samples/suites.cc.bin.out.expected | 0 samples/tests/early_exit.sh | 4 +- samples/tests/fail_fast.sh | 2 +- samples/tests/help.sh | 4 +- samples/tests/list.sh | 4 +- samples/tests/pattern.sh | 18 +++---- samples/tests/tap_test.sh | 12 ++--- samples/tests/verbose.sh | 2 +- 52 files changed, 95 insertions(+), 49 deletions(-) rename samples/{asserts.err.expected => asserts.c.bin.err.expected} (57%) rename samples/{asserts.out.expected => asserts.c.bin.out.expected} (100%) create mode 100644 samples/asserts.cc.bin.err.expected rename samples/{description.out.expected => asserts.cc.bin.out.expected} (100%) rename samples/{description.err.expected => description.c.bin.err.expected} (100%) rename samples/{exit.out.expected => description.c.bin.out.expected} (100%) create mode 100644 samples/description.cc.bin.err.expected rename samples/{long-messages.out.expected => description.cc.bin.out.expected} (100%) rename samples/{exit.err.expected => exit.c.bin.err.expected} (100%) rename samples/{more-suites.out.expected => exit.c.bin.out.expected} (100%) create mode 100644 samples/exit.cc.bin.err.expected rename samples/{other-crashes.out.expected => exit.cc.bin.out.expected} (100%) rename samples/{fixtures.err.expected => fixtures.c.bin.err.expected} (100%) rename samples/{fixtures.out.expected => fixtures.c.bin.out.expected} (100%) create mode 100644 samples/fixtures.cc.bin.err.expected create mode 100644 samples/fixtures.cc.bin.out.expected rename samples/{long-messages.err.expected => long-messages.c.bin.err.expected} (100%) rename samples/{signal.out.expected => long-messages.c.bin.out.expected} (100%) create mode 100644 samples/long-messages.cc.bin.err.expected rename samples/{simple.out.expected => long-messages.cc.bin.out.expected} (100%) rename samples/{more-suites.err.expected => more-suites.c.bin.err.expected} (100%) rename samples/{suites.out.expected => more-suites.c.bin.out.expected} (100%) rename samples/{suites.err.expected => more-suites.cc.bin.err.expected} (100%) create mode 100644 samples/more-suites.cc.bin.out.expected rename samples/{other-crashes.err.expected => other-crashes.c.bin.err.expected} (100%) create mode 100644 samples/other-crashes.c.bin.out.expected create mode 100644 samples/other-crashes.cc.bin.err.expected create mode 100644 samples/other-crashes.cc.bin.out.expected rename samples/{report.err.expected => report.c.bin.err.expected} (100%) rename samples/{report.out.expected => report.c.bin.out.expected} (100%) create mode 100644 samples/report.cc.bin.err.expected create mode 100644 samples/report.cc.bin.out.expected rename samples/{signal.err.expected => signal.c.bin.err.expected} (100%) create mode 100644 samples/signal.c.bin.out.expected create mode 100644 samples/signal.cc.bin.err.expected create mode 100644 samples/signal.cc.bin.out.expected rename samples/{simple.err.expected => simple.c.bin.err.expected} (100%) create mode 100644 samples/simple.c.bin.out.expected create mode 100644 samples/simple.cc.bin.err.expected create mode 100644 samples/simple.cc.bin.out.expected create mode 100644 samples/suites.c.bin.err.expected create mode 100644 samples/suites.c.bin.out.expected create mode 100644 samples/suites.cc.bin.err.expected create mode 100644 samples/suites.cc.bin.out.expected diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt index 386710a..889f39f 100644 --- a/samples/CMakeLists.txt +++ b/samples/CMakeLists.txt @@ -6,18 +6,30 @@ endif () include_directories(../include) set(SAMPLES - signal - exit - report - suites - fixtures - asserts - more-suites - long-messages - description - other-crashes - simple - theories + signal.c + exit.c + report.c + suites.c + fixtures.c + asserts.c + more-suites.c + long-messages.c + description.c + other-crashes.c + simple.c + theories.c + + signal.cc + exit.cc + report.cc + suites.cc + fixtures.cc + asserts.cc + more-suites.cc + long-messages.cc + description.cc + other-crashes.cc + simple.cc ) set(SCRIPTS @@ -34,22 +46,15 @@ if (HAVE_PCRE) endif () foreach(sample ${SAMPLES}) - add_executable(${sample} ${sample}.c) - target_link_libraries(${sample} criterion) - add_test(${sample} ${sample}) - set_property(TEST ${sample} PROPERTY - ENVIRONMENT "CRITERION_ALWAYS_SUCCEED=1" - ) - - add_executable(${sample}_cpp ${sample}.cc) - target_link_libraries(${sample}_cpp criterion) - add_test(${sample}_cpp ${sample}_cpp) + add_executable(${sample}.bin ${sample}) + target_link_libraries(${sample}.bin criterion) + add_test(${sample} ${sample}.bin) set_property(TEST ${sample} PROPERTY ENVIRONMENT "CRITERION_ALWAYS_SUCCEED=1" ) if (NOT MSVC) # we disable the scripted tests when building with MSVC - add_test(${sample}_compare sh ${CMAKE_CURRENT_LIST_DIR}/tests/run_test.sh "${CMAKE_CURRENT_LIST_DIR}" . . ${sample}) + add_test(${sample}_compare sh ${CMAKE_CURRENT_LIST_DIR}/tests/run_test.sh "${CMAKE_CURRENT_LIST_DIR}" . . ${sample}.bin) set_property(TEST ${sample}_compare PROPERTY ENVIRONMENT "LC_ALL=en_US.utf8" ENVIRONMENT "CRITERION_ALWAYS_SUCCEED=1" diff --git a/samples/asserts.err.expected b/samples/asserts.c.bin.err.expected similarity index 57% rename from samples/asserts.err.expected rename to samples/asserts.c.bin.err.expected index 644a440..0f81d72 100644 --- a/samples/asserts.err.expected +++ b/samples/asserts.c.bin.err.expected @@ -1,6 +1,6 @@ -[----] asserts.c:11: Assertion failed: assert is fatal, expect isn't -[----] asserts.c:12: Assertion failed: This assert runs +[----] asserts.c:9: Assertion failed: assert is fatal, expect isn't +[----] asserts.c:10: Assertion failed: This assert runs [FAIL] asserts::base: (0.00s) -[----] asserts.c:20: Assertion failed: The conditions for this test were not met. +[----] asserts.c:18: Assertion failed: The conditions for this test were not met. [FAIL] asserts::old_school: (0.00s) [====] Synthesis: Tested: 6 | Passing: 4 | Failing: 2 | Crashing: 0  diff --git a/samples/asserts.out.expected b/samples/asserts.c.bin.out.expected similarity index 100% rename from samples/asserts.out.expected rename to samples/asserts.c.bin.out.expected diff --git a/samples/asserts.cc.bin.err.expected b/samples/asserts.cc.bin.err.expected new file mode 100644 index 0000000..3b7d7ae --- /dev/null +++ b/samples/asserts.cc.bin.err.expected @@ -0,0 +1,6 @@ +[----] asserts.cc:9: Assertion failed: assert is fatal, expect isn't +[----] asserts.cc:10: Assertion failed: This assert runs +[FAIL] asserts::base: (0.00s) +[----] asserts.cc:18: Assertion failed: The conditions for this test were not met. +[FAIL] asserts::old_school: (0.00s) +[====] Synthesis: Tested: 6 | Passing: 4 | Failing: 2 | Crashing: 0  diff --git a/samples/description.out.expected b/samples/asserts.cc.bin.out.expected similarity index 100% rename from samples/description.out.expected rename to samples/asserts.cc.bin.out.expected diff --git a/samples/description.err.expected b/samples/description.c.bin.err.expected similarity index 100% rename from samples/description.err.expected rename to samples/description.c.bin.err.expected diff --git a/samples/exit.out.expected b/samples/description.c.bin.out.expected similarity index 100% rename from samples/exit.out.expected rename to samples/description.c.bin.out.expected diff --git a/samples/description.cc.bin.err.expected b/samples/description.cc.bin.err.expected new file mode 100644 index 0000000..730b527 --- /dev/null +++ b/samples/description.cc.bin.err.expected @@ -0,0 +1,3 @@ +[----] description.cc:4: Assertion failed: 0 +[FAIL] misc::failing: (0.00s) +[====] Synthesis: Tested: 1 | Passing: 0 | Failing: 1 | Crashing: 0  diff --git a/samples/long-messages.out.expected b/samples/description.cc.bin.out.expected similarity index 100% rename from samples/long-messages.out.expected rename to samples/description.cc.bin.out.expected diff --git a/samples/exit.err.expected b/samples/exit.c.bin.err.expected similarity index 100% rename from samples/exit.err.expected rename to samples/exit.c.bin.err.expected diff --git a/samples/more-suites.out.expected b/samples/exit.c.bin.out.expected similarity index 100% rename from samples/more-suites.out.expected rename to samples/exit.c.bin.out.expected diff --git a/samples/exit.cc.bin.err.expected b/samples/exit.cc.bin.err.expected new file mode 100644 index 0000000..3ffe51b --- /dev/null +++ b/samples/exit.cc.bin.err.expected @@ -0,0 +1,4 @@ +[----] Warning! The test `exit::unexpected_exit` exited during its setup or teardown. +[----] Warning! The test `exit_with_fixtures::fini_exits` exited during its setup or teardown. +[----] Warning! The test `exit_with_fixtures::init_exits` exited during its setup or teardown. +[====] Synthesis: Tested: 5 | Passing: 3 | Failing: 2 | Crashing: 2  diff --git a/samples/other-crashes.out.expected b/samples/exit.cc.bin.out.expected similarity index 100% rename from samples/other-crashes.out.expected rename to samples/exit.cc.bin.out.expected diff --git a/samples/fixtures.err.expected b/samples/fixtures.c.bin.err.expected similarity index 100% rename from samples/fixtures.err.expected rename to samples/fixtures.c.bin.err.expected diff --git a/samples/fixtures.out.expected b/samples/fixtures.c.bin.out.expected similarity index 100% rename from samples/fixtures.out.expected rename to samples/fixtures.c.bin.out.expected diff --git a/samples/fixtures.cc.bin.err.expected b/samples/fixtures.cc.bin.err.expected new file mode 100644 index 0000000..a34f221 --- /dev/null +++ b/samples/fixtures.cc.bin.err.expected @@ -0,0 +1 @@ +[====] Synthesis: Tested: 1 | Passing: 1 | Failing: 0 | Crashing: 0  diff --git a/samples/fixtures.cc.bin.out.expected b/samples/fixtures.cc.bin.out.expected new file mode 100644 index 0000000..a74afed --- /dev/null +++ b/samples/fixtures.cc.bin.out.expected @@ -0,0 +1,2 @@ +Runs before the test +Runs after the test diff --git a/samples/long-messages.err.expected b/samples/long-messages.c.bin.err.expected similarity index 100% rename from samples/long-messages.err.expected rename to samples/long-messages.c.bin.err.expected diff --git a/samples/signal.out.expected b/samples/long-messages.c.bin.out.expected similarity index 100% rename from samples/signal.out.expected rename to samples/long-messages.c.bin.out.expected diff --git a/samples/long-messages.cc.bin.err.expected b/samples/long-messages.cc.bin.err.expected new file mode 100644 index 0000000..fa56cf2 --- /dev/null +++ b/samples/long-messages.cc.bin.err.expected @@ -0,0 +1,6 @@ +[----] long-messages.cc:4: Assertion failed: This is +[----] A long message +[----] Spawning multiple lines. +[----] Formatting is respected. +[FAIL] sample::long_msg: (0.00s) +[====] Synthesis: Tested: 1 | Passing: 0 | Failing: 1 | Crashing: 0  diff --git a/samples/simple.out.expected b/samples/long-messages.cc.bin.out.expected similarity index 100% rename from samples/simple.out.expected rename to samples/long-messages.cc.bin.out.expected diff --git a/samples/more-suites.err.expected b/samples/more-suites.c.bin.err.expected similarity index 100% rename from samples/more-suites.err.expected rename to samples/more-suites.c.bin.err.expected diff --git a/samples/suites.out.expected b/samples/more-suites.c.bin.out.expected similarity index 100% rename from samples/suites.out.expected rename to samples/more-suites.c.bin.out.expected diff --git a/samples/suites.err.expected b/samples/more-suites.cc.bin.err.expected similarity index 100% rename from samples/suites.err.expected rename to samples/more-suites.cc.bin.err.expected diff --git a/samples/more-suites.cc.bin.out.expected b/samples/more-suites.cc.bin.out.expected new file mode 100644 index 0000000..e69de29 diff --git a/samples/other-crashes.err.expected b/samples/other-crashes.c.bin.err.expected similarity index 100% rename from samples/other-crashes.err.expected rename to samples/other-crashes.c.bin.err.expected diff --git a/samples/other-crashes.c.bin.out.expected b/samples/other-crashes.c.bin.out.expected new file mode 100644 index 0000000..e69de29 diff --git a/samples/other-crashes.cc.bin.err.expected b/samples/other-crashes.cc.bin.err.expected new file mode 100644 index 0000000..41d3cb8 --- /dev/null +++ b/samples/other-crashes.cc.bin.err.expected @@ -0,0 +1,3 @@ +[----] Warning! The test `misc::setup_crash` crashed during its setup or teardown. +[----] Warning! The test `misc::teardown_crash` crashed during its setup or teardown. +[====] Synthesis: Tested: 2 | Passing: 1 | Failing: 1 | Crashing: 1  diff --git a/samples/other-crashes.cc.bin.out.expected b/samples/other-crashes.cc.bin.out.expected new file mode 100644 index 0000000..e69de29 diff --git a/samples/report.err.expected b/samples/report.c.bin.err.expected similarity index 100% rename from samples/report.err.expected rename to samples/report.c.bin.err.expected diff --git a/samples/report.out.expected b/samples/report.c.bin.out.expected similarity index 100% rename from samples/report.out.expected rename to samples/report.c.bin.out.expected diff --git a/samples/report.cc.bin.err.expected b/samples/report.cc.bin.err.expected new file mode 100644 index 0000000..d81ba26 --- /dev/null +++ b/samples/report.cc.bin.err.expected @@ -0,0 +1,3 @@ +[----] report.cc:5: Assertion failed: 0 +[FAIL] sample::test: (0.00s) +[====] Synthesis: Tested: 1 | Passing: 0 | Failing: 1 | Crashing: 0  diff --git a/samples/report.cc.bin.out.expected b/samples/report.cc.bin.out.expected new file mode 100644 index 0000000..d560277 --- /dev/null +++ b/samples/report.cc.bin.out.expected @@ -0,0 +1,4 @@ +criterion_init +testing test in category sample +Asserts: [1 passed, 1 failed, 2 total] +criterion_fini diff --git a/samples/signal.err.expected b/samples/signal.c.bin.err.expected similarity index 100% rename from samples/signal.err.expected rename to samples/signal.c.bin.err.expected diff --git a/samples/signal.c.bin.out.expected b/samples/signal.c.bin.out.expected new file mode 100644 index 0000000..e69de29 diff --git a/samples/signal.cc.bin.err.expected b/samples/signal.cc.bin.err.expected new file mode 100644 index 0000000..8ac44c1 --- /dev/null +++ b/samples/signal.cc.bin.err.expected @@ -0,0 +1,4 @@ +[----] signal.cc:16: Unexpected signal caught below this line! +[FAIL] simple::uncaught: CRASH! +[FAIL] simple::wrong_signal: (0.00s) +[====] Synthesis: Tested: 3 | Passing: 1 | Failing: 2 | Crashing: 1  diff --git a/samples/signal.cc.bin.out.expected b/samples/signal.cc.bin.out.expected new file mode 100644 index 0000000..e69de29 diff --git a/samples/simple.err.expected b/samples/simple.c.bin.err.expected similarity index 100% rename from samples/simple.err.expected rename to samples/simple.c.bin.err.expected diff --git a/samples/simple.c.bin.out.expected b/samples/simple.c.bin.out.expected new file mode 100644 index 0000000..e69de29 diff --git a/samples/simple.cc.bin.err.expected b/samples/simple.cc.bin.err.expected new file mode 100644 index 0000000..c52de64 --- /dev/null +++ b/samples/simple.cc.bin.err.expected @@ -0,0 +1,3 @@ +[----] simple.cc:4: Assertion failed: 0 +[FAIL] misc::failing: (0.00s) +[====] Synthesis: Tested: 2 | Passing: 1 | Failing: 1 | Crashing: 0  diff --git a/samples/simple.cc.bin.out.expected b/samples/simple.cc.bin.out.expected new file mode 100644 index 0000000..e69de29 diff --git a/samples/suites.c.bin.err.expected b/samples/suites.c.bin.err.expected new file mode 100644 index 0000000..09eb50f --- /dev/null +++ b/samples/suites.c.bin.err.expected @@ -0,0 +1 @@ +[====] Synthesis: Tested: 2 | Passing: 2 | Failing: 0 | Crashing: 0  diff --git a/samples/suites.c.bin.out.expected b/samples/suites.c.bin.out.expected new file mode 100644 index 0000000..e69de29 diff --git a/samples/suites.cc.bin.err.expected b/samples/suites.cc.bin.err.expected new file mode 100644 index 0000000..09eb50f --- /dev/null +++ b/samples/suites.cc.bin.err.expected @@ -0,0 +1 @@ +[====] Synthesis: Tested: 2 | Passing: 2 | Failing: 0 | Crashing: 0  diff --git a/samples/suites.cc.bin.out.expected b/samples/suites.cc.bin.out.expected new file mode 100644 index 0000000..e69de29 diff --git a/samples/tests/early_exit.sh b/samples/tests/early_exit.sh index f25738c..71bb31d 100755 --- a/samples/tests/early_exit.sh +++ b/samples/tests/early_exit.sh @@ -1,3 +1,3 @@ #!/bin/sh -./simple --no-early-exit --always-succeed -./theories --no-early-exit --always-succeed +./simple.c.bin --no-early-exit --always-succeed +./theories.c.bin --no-early-exit --always-succeed diff --git a/samples/tests/fail_fast.sh b/samples/tests/fail_fast.sh index 3fecfd8..fcc02e1 100755 --- a/samples/tests/fail_fast.sh +++ b/samples/tests/fail_fast.sh @@ -1,2 +1,2 @@ #!/bin/sh -./simple --fail-fast --always-succeed +./simple.c.bin --fail-fast --always-succeed diff --git a/samples/tests/help.sh b/samples/tests/help.sh index 6b60bb5..6752cc6 100755 --- a/samples/tests/help.sh +++ b/samples/tests/help.sh @@ -1,3 +1,3 @@ #!/bin/sh -./simple --help -./simple --version +./simple.c.bin --help +./simple.c.bin --version diff --git a/samples/tests/list.sh b/samples/tests/list.sh index 2040e54..6ab72bf 100755 --- a/samples/tests/list.sh +++ b/samples/tests/list.sh @@ -1,3 +1,3 @@ #!/bin/sh -./simple --list -./simple --list --ascii +./simple.c.bin --list +./simple.c.bin --list --ascii diff --git a/samples/tests/pattern.sh b/samples/tests/pattern.sh index 09996f1..c1b10a9 100755 --- a/samples/tests/pattern.sh +++ b/samples/tests/pattern.sh @@ -1,10 +1,10 @@ #!/bin/sh -e -./simple --pattern '*/passing' -./simple --pattern '!(*/passing)' -./simple --pattern '[pf]a@(ss|il)ing' -./simple --pattern '@(+(nest)ed))' -./simple --pattern '?(*(a|b))' -! ./simple --pattern '?(malformed' -./simple --pattern '[!azerty]assing' -./simple --pattern '|pipe' -./simple --pattern '\!(escaped' +./simple.c.bin --pattern '*/passing' +./simple.c.bin --pattern '!(*/passing)' +./simple.c.bin --pattern '[pf]a@(ss|il)ing' +./simple.c.bin --pattern '@(+(nest)ed))' +./simple.c.bin --pattern '?(*(a|b))' +! ./simple.c.bin --pattern '?(malformed' +./simple.c.bin --pattern '[!azerty]assing' +./simple.c.bin --pattern '|pipe' +./simple.c.bin --pattern '\!(escaped' diff --git a/samples/tests/tap_test.sh b/samples/tests/tap_test.sh index 38c0ac3..5e81fbf 100755 --- a/samples/tests/tap_test.sh +++ b/samples/tests/tap_test.sh @@ -1,7 +1,7 @@ #!/bin/sh -./simple --tap --always-succeed -./signal --tap --always-succeed -./asserts --tap --always-succeed -./more-suites --tap --always-succeed -./long-messages --tap --always-succeed -./description --tap --always-succeed +./simple.c.bin --tap --always-succeed +./signal.c.bin --tap --always-succeed +./asserts.c.bin --tap --always-succeed +./more-suites.c.bin --tap --always-succeed +./long-messages.c.bin --tap --always-succeed +./description.c.bin --tap --always-succeed diff --git a/samples/tests/verbose.sh b/samples/tests/verbose.sh index 73410b8..6bb1ef2 100755 --- a/samples/tests/verbose.sh +++ b/samples/tests/verbose.sh @@ -1,2 +1,2 @@ #!/bin/sh -./simple --verbose --always-succeed +./simple.c.bin --verbose --always-succeed From 8e66ff173f2fe0b91a3cad37687dae5c89240ad4 Mon Sep 17 00:00:00 2001 From: Snaipe Date: Mon, 7 Sep 2015 01:57:05 +0200 Subject: [PATCH 03/23] Restored cr_abort_test default message --- include/criterion/assert.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/include/criterion/assert.h b/include/criterion/assert.h index 23b4256..ea3e0cc 100644 --- a/include/criterion/assert.h +++ b/include/criterion/assert.h @@ -80,8 +80,11 @@ struct criterion_assert_args { // Common asserts -# define cr_abort_test(Message) \ - cr_assert(0, (Message)) +# define cr_abort_test(Message) \ + do { \ + const char *msg = (Message); \ + cr_assert(0, msg ? msg : "The conditions for this test were not met.");\ + } while (0) # define cr_assert(...) CR_EXPAND(cr_assert_(__VA_ARGS__, 0)) From b9292bb42d397caa755d324f6b1fbc7ff6fcf5c6 Mon Sep 17 00:00:00 2001 From: Snaipe Date: Mon, 7 Sep 2015 01:58:15 +0200 Subject: [PATCH 04/23] Temporarily removed -pedantic from c++ samples --- samples/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt index 889f39f..5ab40fb 100644 --- a/samples/CMakeLists.txt +++ b/samples/CMakeLists.txt @@ -1,6 +1,6 @@ if (NOT MSVC) set(CMAKE_C_FLAGS "-std=c99 -Wall -Wextra -pedantic") - set(CMAKE_CXX_FLAGS "-std=c++11 -Wall -Wextra -pedantic") + set(CMAKE_CXX_FLAGS "-std=c++11 -Wall -Wextra") endif () include_directories(../include) From fd9cf1755afa1e3ea955ca6a36350be962331570 Mon Sep 17 00:00:00 2001 From: Snaipe Date: Mon, 7 Sep 2015 02:00:03 +0200 Subject: [PATCH 05/23] Added missing .cc samples --- .gitignore | 1 + samples/asserts.cc | 80 ++++++++++++++++++++++++++++++++++++++++ samples/description.cc | 8 ++++ samples/exit.cc | 24 ++++++++++++ samples/fixtures.cc | 14 +++++++ samples/long-messages.cc | 5 +++ samples/more-suites.cc | 21 +++++++++++ samples/other-crashes.cc | 14 +++++++ samples/report.cc | 26 +++++++++++++ samples/signal.cc | 19 ++++++++++ samples/simple.cc | 9 +++++ samples/suites.cc | 9 +++++ 12 files changed, 230 insertions(+) create mode 100644 samples/asserts.cc create mode 100644 samples/description.cc create mode 100644 samples/exit.cc create mode 100644 samples/fixtures.cc create mode 100644 samples/long-messages.cc create mode 100644 samples/more-suites.cc create mode 100644 samples/other-crashes.cc create mode 100644 samples/report.cc create mode 100644 samples/signal.cc create mode 100644 samples/simple.cc create mode 100644 samples/suites.cc diff --git a/.gitignore b/.gitignore index 9e813d9..fdaf499 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ !.ci/* !*.c +!*.cc !*.h !*.rst !samples/tests/*.sh diff --git a/samples/asserts.cc b/samples/asserts.cc new file mode 100644 index 0000000..ef5bc98 --- /dev/null +++ b/samples/asserts.cc @@ -0,0 +1,80 @@ +#include + +Test(asserts, base) { + cr_assert(true); + cr_expect(true); + + cr_assert(true, "Assertions may take failure messages"); + + cr_expect(false, "assert is fatal, expect isn't"); + cr_assert(false, "This assert runs"); + cr_assert(false, "This does not"); +} + +Test(asserts, old_school) { + if (false) + cr_abort_test("You can abort the test with a message from anywhere"); + + cr_abort_test(NULL); // or without a message +} + +Test(asserts, string) { + cr_assert_strings_eq("hello", "hello"); + cr_assert_strings_neq("hello", "olleh"); + + cr_assert_strings_gt("hello", "hell"); + cr_assert_strings_geq("hello", "hell"); + cr_assert_strings_geq("hello", "hello"); + + cr_assert_strings_lt("hell", "hello"); + cr_assert_strings_leq("hell", "hello"); + cr_assert_strings_leq("hello", "hello"); +} + +Test(asserts, native) { + cr_assert_eq(1, 1); + cr_assert_neq(1, 2); + + cr_assert_lt(1, 2); + cr_assert_leq(1, 2); + cr_assert_leq(2, 2); + + cr_assert_gt(2, 1); + cr_assert_geq(2, 1); + cr_assert_geq(2, 2); +} + +Test(asserts, float) { + cr_assert_neq(0.1 * 0.1, 0.01); + cr_assert_float_eq(0.1 * 0.1, 0.01, 0.001); +} + +struct dummy_struct { + char a; + size_t b; +}; + +int eq_dummy(struct dummy_struct *a, struct dummy_struct *b) { + return a->a != b->a || a->b != b->b; +} + +Test(asserts, array) { + int arr1[] = {1, 2, 3, 4}; + int arr2[] = {4, 3, 2, 1}; + + cr_assert_arrays_eq(arr1, arr1, 4); + cr_assert_arrays_neq(arr1, arr2, 4); + +#ifdef __GNUC__ + struct dummy_struct s1[] = {{4, 2}, {2, 4}}; + struct dummy_struct s2[2]; + memset(s2, 0xFF, sizeof(s2)); + s2[0].a = 4; + s2[0].b = 2; + s2[1].a = 2; + s2[1].b = 4; + + cr_assert_arrays_neq(s1, s2, 2); + cr_assert_arrays_eq_cmp(s1, s2, 2, eq_dummy); +#endif +} diff --git a/samples/description.cc b/samples/description.cc new file mode 100644 index 0000000..55b7b49 --- /dev/null +++ b/samples/description.cc @@ -0,0 +1,8 @@ +#include + +Test(misc, failing, .description = "Just a failing test") { + cr_assert(0); +} + +Test(misc, skipped, .description = "This one is skipped", .disabled = true) { +} diff --git a/samples/exit.cc b/samples/exit.cc new file mode 100644 index 0000000..f9c95dd --- /dev/null +++ b/samples/exit.cc @@ -0,0 +1,24 @@ +#include +#include +#include + +Test(exit, normal, .exit_code = 0) { +} + +Test(exit, expected_exit, .exit_code = 42) { + exit(42); +} + +Test(exit, unexpected_exit) { + exit(127); +} + +void do_exit (void) { + exit(127); +} + +Test(exit_with_fixtures, init_exits, .init = do_exit) { +} + +Test(exit_with_fixtures, fini_exits, .fini = do_exit) { +} diff --git a/samples/fixtures.cc b/samples/fixtures.cc new file mode 100644 index 0000000..1f7851c --- /dev/null +++ b/samples/fixtures.cc @@ -0,0 +1,14 @@ +#include +#include + +void setup(void) { + puts("Runs before the test"); +} + +void teardown(void) { + puts("Runs after the test"); +} + +Test(simple, fixtures, .init = setup, .fini = teardown) { + cr_assert(1); +} diff --git a/samples/long-messages.cc b/samples/long-messages.cc new file mode 100644 index 0000000..02472e1 --- /dev/null +++ b/samples/long-messages.cc @@ -0,0 +1,5 @@ +#include + +Test(sample, long_msg) { + cr_assert(0, "This is\nA long message\nSpawning multiple lines.\n\nFormatting is respected."); +} diff --git a/samples/more-suites.cc b/samples/more-suites.cc new file mode 100644 index 0000000..95d7039 --- /dev/null +++ b/samples/more-suites.cc @@ -0,0 +1,21 @@ +#include + +void setup_suite(void) { +} + +void teardown_suite(void) { +} + +TestSuite(suite1, .init = setup_suite, .fini = teardown_suite); + +Test(suite1, test) { + cr_assert(1); +} + +Test(suite2, test) { + cr_assert(1); +} + +TestSuite(disabled, .disabled = true); + +Test(disabled, test) {} diff --git a/samples/other-crashes.cc b/samples/other-crashes.cc new file mode 100644 index 0000000..ab689bb --- /dev/null +++ b/samples/other-crashes.cc @@ -0,0 +1,14 @@ +#include + +void crash(void) { + int *i = NULL; + *i = 42; +} + +Test(misc, setup_crash, .init = crash) { + cr_assert(true); +} + +Test(misc, teardown_crash, .fini = crash) { + cr_assert(true); +} diff --git a/samples/report.cc b/samples/report.cc new file mode 100644 index 0000000..8c9ace8 --- /dev/null +++ b/samples/report.cc @@ -0,0 +1,26 @@ +#include +#include + +Test(sample, test) { + cr_expect(0); + cr_assert(1); +} + +ReportHook(PRE_INIT)(struct criterion_test *test) { + printf("testing %s in category %s\n", test->name, test->category); +} + +ReportHook(POST_TEST)(struct criterion_test_stats *stats) { + printf("Asserts: [%d passed, %d failed, %d total]\n", + stats->passed_asserts, stats->failed_asserts, stats->passed_asserts + stats->failed_asserts); +} + +ReportHook(PRE_ALL)(struct criterion_test_set *tests) { + (void) tests; + puts("criterion_init"); +} + +ReportHook(POST_ALL)(struct criterion_global_stats *stats) { + (void) stats; + puts("criterion_fini"); +} diff --git a/samples/signal.cc b/samples/signal.cc new file mode 100644 index 0000000..9dcc99d --- /dev/null +++ b/samples/signal.cc @@ -0,0 +1,19 @@ +#include +#include +#include +#include + +Test(simple, caught, .signal = SIGSEGV) { + int *i = NULL; + *i = 42; +} + +Test(simple, wrong_signal, .signal = SIGINT) { + int *i = NULL; + *i = 42; +} + +Test(simple, uncaught) { + int *i = NULL; + *i = 42; +} diff --git a/samples/simple.cc b/samples/simple.cc new file mode 100644 index 0000000..d5916f5 --- /dev/null +++ b/samples/simple.cc @@ -0,0 +1,9 @@ +#include + +Test(misc, failing) { + cr_assert(0); +} + +Test(misc, passing) { + cr_assert(1); +} diff --git a/samples/suites.cc b/samples/suites.cc new file mode 100644 index 0000000..d19d7b2 --- /dev/null +++ b/samples/suites.cc @@ -0,0 +1,9 @@ +#include + +Test(first_suite, test) { + cr_assert(1); +} + +Test(second_suite, test) { + cr_assert(1); +} From ba051b8869712f546d333e7293f2d5f78677d676 Mon Sep 17 00:00:00 2001 From: Snaipe Date: Mon, 7 Sep 2015 02:20:18 +0200 Subject: [PATCH 06/23] Fixed missing initializer for C samples on assert substitution --- include/criterion/assert.h | 94 ++++++++++++++++++++------------------ 1 file changed, 50 insertions(+), 44 deletions(-) diff --git a/include/criterion/assert.h b/include/criterion/assert.h index ea3e0cc..2111409 100644 --- a/include/criterion/assert.h +++ b/include/criterion/assert.h @@ -86,15 +86,21 @@ struct criterion_assert_args { cr_assert(0, msg ? msg : "The conditions for this test were not met.");\ } while (0) -# define cr_assert(...) CR_EXPAND(cr_assert_(__VA_ARGS__, 0)) +# ifdef __cplusplus +# define CR_SENTINEL 0 +# else +# define CR_SENTINEL .sentinel_ = 0 +# endif -# define cr_expect(...) CR_EXPAND(cr_expect_(__VA_ARGS__, 0)) +# define cr_assert(...) CR_EXPAND(cr_assert_(__VA_ARGS__, CR_SENTINEL)) + +# define cr_expect(...) CR_EXPAND(cr_expect_(__VA_ARGS__, CR_SENTINEL)) # define cr_assert_(Condition, ...) CR_EXPAND(cr_assert_impl(FATAL, Condition, __VA_ARGS__)) # define cr_expect_(Condition, ...) CR_EXPAND(cr_assert_impl(NORMAL, Condition, __VA_ARGS__)) -# define cr_assert_not(...) CR_EXPAND(cr_assert_not_(__VA_ARGS__, 0)) -# define cr_expect_not(...) CR_EXPAND(cr_expect_not_(__VA_ARGS__, 0)) +# define cr_assert_not(...) CR_EXPAND(cr_assert_not_(__VA_ARGS__, CR_SENTINEL)) +# define cr_expect_not(...) CR_EXPAND(cr_expect_not_(__VA_ARGS__, CR_SENTINEL)) # define cr_assert_not_(Condition, ...) \ CR_EXPAND(cr_assert_impl(FATAL, !(Condition), __VA_ARGS__)) @@ -108,46 +114,46 @@ struct criterion_assert_args { # define cr_expect_op_(Op, Actual, Expected, ...) \ CR_EXPAND(cr_assert_impl(NORMAL, (Actual) Op (Expected), __VA_ARGS__)) -# define cr_assert_eq(...) CR_EXPAND(cr_assert_op_(==, __VA_ARGS__, 0)) -# define cr_expect_eq(...) CR_EXPAND(cr_expect_op_(==, __VA_ARGS__, 0)) +# define cr_assert_eq(...) CR_EXPAND(cr_assert_op_(==, __VA_ARGS__, CR_SENTINEL)) +# define cr_expect_eq(...) CR_EXPAND(cr_expect_op_(==, __VA_ARGS__, CR_SENTINEL)) -# define cr_assert_neq(...) CR_EXPAND(cr_assert_op_(!=, __VA_ARGS__, 0)) -# define cr_expect_neq(...) CR_EXPAND(cr_expect_op_(!=, __VA_ARGS__, 0)) +# define cr_assert_neq(...) CR_EXPAND(cr_assert_op_(!=, __VA_ARGS__, CR_SENTINEL)) +# define cr_expect_neq(...) CR_EXPAND(cr_expect_op_(!=, __VA_ARGS__, CR_SENTINEL)) -# define cr_assert_lt(...) CR_EXPAND(cr_assert_op_(<, __VA_ARGS__, 0)) -# define cr_expect_lt(...) CR_EXPAND(cr_expect_op_(<, __VA_ARGS__, 0)) +# define cr_assert_lt(...) CR_EXPAND(cr_assert_op_(<, __VA_ARGS__, CR_SENTINEL)) +# define cr_expect_lt(...) CR_EXPAND(cr_expect_op_(<, __VA_ARGS__, CR_SENTINEL)) -# define cr_assert_gt(...) CR_EXPAND(cr_assert_op_(>, __VA_ARGS__, 0)) -# define cr_expect_gt(...) CR_EXPAND(cr_expect_op_(>, __VA_ARGS__, 0)) +# define cr_assert_gt(...) CR_EXPAND(cr_assert_op_(>, __VA_ARGS__, CR_SENTINEL)) +# define cr_expect_gt(...) CR_EXPAND(cr_expect_op_(>, __VA_ARGS__, CR_SENTINEL)) -# define cr_assert_leq(...) CR_EXPAND(cr_assert_op_(<=, __VA_ARGS__, 0)) -# define cr_expect_leq(...) CR_EXPAND(cr_expect_op_(<=, __VA_ARGS__, 0)) +# define cr_assert_leq(...) CR_EXPAND(cr_assert_op_(<=, __VA_ARGS__, CR_SENTINEL)) +# define cr_expect_leq(...) CR_EXPAND(cr_expect_op_(<=, __VA_ARGS__, CR_SENTINEL)) -# define cr_assert_geq(...) CR_EXPAND(cr_assert_op_(>=, __VA_ARGS__, 0)) -# define cr_expect_geq(...) CR_EXPAND(cr_expect_op_(>=, __VA_ARGS__, 0)) +# define cr_assert_geq(...) CR_EXPAND(cr_assert_op_(>=, __VA_ARGS__, CR_SENTINEL)) +# define cr_expect_geq(...) CR_EXPAND(cr_expect_op_(>=, __VA_ARGS__, CR_SENTINEL)) # define cr_assert_null_(Value, ...) \ CR_EXPAND(cr_assert_impl(FATAL, (Value) == NULL, __VA_ARGS__)) # define cr_expect_null_(Value, ...) \ CR_EXPAND(cr_assert_impl(NORMAL, (Value) == NULL, __VA_ARGS__)) -# define cr_assert_null(...) CR_EXPAND(cr_assert_null_(__VA_ARGS__, 0)) -# define cr_expect_null(...) CR_EXPAND(cr_expect_null_(__VA_ARGS__, 0)) +# define cr_assert_null(...) CR_EXPAND(cr_assert_null_(__VA_ARGS__, CR_SENTINEL)) +# define cr_expect_null(...) CR_EXPAND(cr_expect_null_(__VA_ARGS__, CR_SENTINEL)) # define cr_assert_not_null_(Value, ...) \ CR_EXPAND(cr_assert_impl(FATAL, (Value) != NULL, __VA_ARGS__)) # define cr_expect_not_null_(Value, ...) \ CR_EXPAND(cr_assert_impl(NORMAL, (Value) != NULL, __VA_ARGS__)) -# define cr_assert_not_null(...) CR_EXPAND(cr_assert_not_null_(__VA_ARGS__, 0)) -# define cr_expect_not_null(...) CR_EXPAND(cr_expect_not_null_(__VA_ARGS__, 0)) +# define cr_assert_not_null(...) CR_EXPAND(cr_assert_not_null_(__VA_ARGS__, CR_SENTINEL)) +# define cr_expect_not_null(...) CR_EXPAND(cr_expect_not_null_(__VA_ARGS__, CR_SENTINEL)) // Floating-point asserts # define cr_assert_float_eq(...) \ - CR_EXPAND(cr_assert_float_eq_(__VA_ARGS__, 0)) + CR_EXPAND(cr_assert_float_eq_(__VA_ARGS__, CR_SENTINEL)) # define cr_expect_float_eq(...) \ - CR_EXPAND(cr_expect_float_eq_(__VA_ARGS__, 0)) + CR_EXPAND(cr_expect_float_eq_(__VA_ARGS__, CR_SENTINEL)) # define cr_assert_float_eq_(Actual, Expected, Epsilon, ...) \ CR_EXPAND(cr_assert_impl(FATAL, (Expected) - (Actual) <= (Epsilon) \ @@ -159,9 +165,9 @@ struct criterion_assert_args { __VA_ARGS__)) # define cr_assert_float_neq(...) \ - CR_EXPAND(cr_assert_float_neq_(__VA_ARGS__, 0)) + CR_EXPAND(cr_assert_float_neq_(__VA_ARGS__, CR_SENTINEL)) # define cr_expect_float_neq(...) \ - CR_EXPAND(cr_expect_float_neq_(__VA_ARGS__, 0)) + CR_EXPAND(cr_expect_float_neq_(__VA_ARGS__, CR_SENTINEL)) # define cr_assert_float_neq_(Actual, Expected, Epsilon, ...) \ CR_EXPAND(cr_assert_impl(FATAL, (Expected) - (Actual) > (Epsilon) \ @@ -180,38 +186,38 @@ struct criterion_assert_args { CR_EXPAND(cr_assert_impl(NORMAL, strcmp((Actual), (Expected)) Op 0, __VA_ARGS__)) # define cr_assert_strings_eq(...) \ - CR_EXPAND(cr_assert_strings_(==, __VA_ARGS__, 0)) + CR_EXPAND(cr_assert_strings_(==, __VA_ARGS__, CR_SENTINEL)) # define cr_expect_strings_eq(...) \ - CR_EXPAND(cr_expect_strings_(==, __VA_ARGS__, 0)) + CR_EXPAND(cr_expect_strings_(==, __VA_ARGS__, CR_SENTINEL)) # define cr_assert_strings_neq(...) \ - CR_EXPAND(cr_assert_strings_(!=, __VA_ARGS__, 0)) + CR_EXPAND(cr_assert_strings_(!=, __VA_ARGS__, CR_SENTINEL)) # define cr_expect_strings_neq(...) \ - CR_EXPAND(cr_expect_strings_(!=, __VA_ARGS__, 0)) + CR_EXPAND(cr_expect_strings_(!=, __VA_ARGS__, CR_SENTINEL)) -# define cr_assert_strings_gt(...) CR_EXPAND(cr_assert_strings_(>, __VA_ARGS__, 0)) -# define cr_expect_strings_gt(...) CR_EXPAND(cr_expect_strings_(>, __VA_ARGS__, 0)) +# define cr_assert_strings_gt(...) CR_EXPAND(cr_assert_strings_(>, __VA_ARGS__, CR_SENTINEL)) +# define cr_expect_strings_gt(...) CR_EXPAND(cr_expect_strings_(>, __VA_ARGS__, CR_SENTINEL)) -# define cr_assert_strings_lt(...) CR_EXPAND(cr_assert_strings_(<, __VA_ARGS__, 0)) -# define cr_expect_strings_lt(...) CR_EXPAND(cr_expect_strings_(<, __VA_ARGS__, 0)) +# define cr_assert_strings_lt(...) CR_EXPAND(cr_assert_strings_(<, __VA_ARGS__, CR_SENTINEL)) +# define cr_expect_strings_lt(...) CR_EXPAND(cr_expect_strings_(<, __VA_ARGS__, CR_SENTINEL)) -# define cr_assert_strings_leq(...) CR_EXPAND(cr_assert_strings_(<=, __VA_ARGS__, 0)) -# define cr_expect_strings_leq(...) CR_EXPAND(cr_expect_strings_(<=, __VA_ARGS__, 0)) +# define cr_assert_strings_leq(...) CR_EXPAND(cr_assert_strings_(<=, __VA_ARGS__, CR_SENTINEL)) +# define cr_expect_strings_leq(...) CR_EXPAND(cr_expect_strings_(<=, __VA_ARGS__, CR_SENTINEL)) -# define cr_assert_strings_geq(...) CR_EXPAND(cr_assert_strings_(>=, __VA_ARGS__, 0)) -# define cr_expect_strings_geq(...) CR_EXPAND(cr_expect_strings_(>=, __VA_ARGS__, 0)) +# define cr_assert_strings_geq(...) CR_EXPAND(cr_assert_strings_(>=, __VA_ARGS__, CR_SENTINEL)) +# define cr_expect_strings_geq(...) CR_EXPAND(cr_expect_strings_(>=, __VA_ARGS__, CR_SENTINEL)) // Array asserts # define cr_assert_arrays_eq(...) \ - CR_EXPAND(cr_assert_arrays_eq_(__VA_ARGS__, 0)) + CR_EXPAND(cr_assert_arrays_eq_(__VA_ARGS__, CR_SENTINEL)) # define cr_expect_arrays_eq(...) \ - CR_EXPAND(cr_expect_arrays_eq_(__VA_ARGS__, 0)) + CR_EXPAND(cr_expect_arrays_eq_(__VA_ARGS__, CR_SENTINEL)) # define cr_assert_arrays_neq(...) \ - CR_EXPAND(cr_assert_arrays_neq_(__VA_ARGS__, 0)) + CR_EXPAND(cr_assert_arrays_neq_(__VA_ARGS__, CR_SENTINEL)) # define cr_expect_arrays_neq(...) \ - CR_EXPAND(cr_expect_arrays_neq_(__VA_ARGS__, 0)) + CR_EXPAND(cr_expect_arrays_neq_(__VA_ARGS__, CR_SENTINEL)) # define cr_assert_arrays_eq_(A, B, Size, ...) \ CR_EXPAND(cr_assert_impl(FATAL, !memcmp((A), (B), (Size)), \ @@ -251,9 +257,9 @@ struct criterion_assert_args { } while (0) # define cr_assert_arrays_eq_cmp(...) \ - cr_assert_arrays_eq_cmp_(__VA_ARGS__, 0) + cr_assert_arrays_eq_cmp_(__VA_ARGS__, CR_SENTINEL) # define cr_expect_arrays_eq_cmp(...) \ - cr_expect_arrays_eq_cmp_(__VA_ARGS__, 0) + cr_expect_arrays_eq_cmp_(__VA_ARGS__, CR_SENTINEL) # define cr_assert_arrays_neq_cmp_(A, B, Size, Cmp, ...) \ do { \ @@ -270,9 +276,9 @@ struct criterion_assert_args { } while (0) # define cr_assert_arrays_neq_cmp(...) \ - cr_assert_arrays_eq_cmp_(__VA_ARGS__, 0) + cr_assert_arrays_eq_cmp_(__VA_ARGS__, CR_SENTINEL) # define cr_expect_arrays_neq_cmp(...) \ - cr_expect_arrays_eq_cmp_(__VA_ARGS__, 0) + cr_expect_arrays_eq_cmp_(__VA_ARGS__, CR_SENTINEL) # endif /* !__GNUC__ */ // The section below is here for backward compatibility purposes. From c94fef2837ecdfe7478bf326376b5a875b87c6f6 Mon Sep 17 00:00:00 2001 From: Snaipe Date: Mon, 7 Sep 2015 02:28:06 +0200 Subject: [PATCH 07/23] Switched compiler to use gcc 4.9 --- .travis.yml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 3422465..4c31586 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,13 +2,25 @@ language: c os: - linux - osx + compiler: -- gcc +- gcc-4.9 + sudo: false + +addons: + apt: + sources: + - ubuntu-toolchain-r-test + packages: + - gcc-4.9 + - g++-4.9 + before_install: - export LOCAL_INSTALL="$HOME" - export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$HOME/lib - export CFLAGS="-g -O0" +- export CXX="g++-4.9" script: - mkdir -p build - cd build From dc0f871d0e8cba2bdf33add56c2a23e3c264fc09 Mon Sep 17 00:00:00 2001 From: Snaipe Date: Mon, 7 Sep 2015 02:59:29 +0200 Subject: [PATCH 08/23] Fixed mismatching parenthesis in section attribute on OS X --- include/criterion/common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/criterion/common.h b/include/criterion/common.h index 5ee86a9..6d0910a 100644 --- a/include/criterion/common.h +++ b/include/criterion/common.h @@ -58,7 +58,7 @@ # define SECTION_END_PREFIX __last # define SECTION_START_SUFFIX(Name) __asm("section$start$__DATA$" Name) # define SECTION_END_SUFFIX(Name) __asm("section$end$__DATA$" Name) -# define SECTION_(Name) CR_ATTRIBUTE(section("__DATA," Name) +# define SECTION_(Name) CR_ATTRIBUTE(section("__DATA," Name)) # define SECTION_SUFFIX_ # elif CR_IS_MSVC # define SECTION_START_PREFIX __start From b594f5cf8abbd61276c535cd8377fde0697339d5 Mon Sep 17 00:00:00 2001 From: Snaipe Date: Mon, 7 Sep 2015 03:02:41 +0200 Subject: [PATCH 09/23] Added missing section suffix on report hooks on Windows VC builds --- include/criterion/hooks.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/criterion/hooks.h b/include/criterion/hooks.h index 098790a..d6ceed2 100644 --- a/include/criterion/hooks.h +++ b/include/criterion/hooks.h @@ -91,7 +91,9 @@ typedef void (*f_report_hook)(); # define ReportHook(Kind) \ HOOK_PROTOTYPE_(HOOK_PARAM_TYPE(Kind)); \ SECTION_(HOOK_SECTION_STRINGIFY(Kind)) \ - const f_report_hook HOOK_IDENTIFIER_(func) = (f_report_hook) HOOK_IDENTIFIER_(impl); \ + const f_report_hook HOOK_IDENTIFIER_(func) = \ + (f_report_hook) HOOK_IDENTIFIER_(impl) \ + SECTION_SUFFIX_; \ HOOK_PROTOTYPE_ #endif /* !CRITERION_HOOKS_H_ */ From 20d5f6fe59791478524686221263067360f904dc Mon Sep 17 00:00:00 2001 From: Snaipe Date: Mon, 7 Sep 2015 03:57:00 +0200 Subject: [PATCH 10/23] Removed report.cc from MinGW build on appveyor --- samples/CMakeLists.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt index 5ab40fb..1512ae8 100644 --- a/samples/CMakeLists.txt +++ b/samples/CMakeLists.txt @@ -21,7 +21,6 @@ set(SAMPLES signal.cc exit.cc - report.cc suites.cc fixtures.cc asserts.cc @@ -32,6 +31,10 @@ set(SAMPLES simple.cc ) +if (NOT WIN32 OR MSVC) + set(SAMPLES ${SAMPLES} report.cc) +endif () + set(SCRIPTS tap_test early_exit From 63f47f170ac62ce2fb0d3801e67a75e37b187d24 Mon Sep 17 00:00:00 2001 From: Snaipe Date: Mon, 7 Sep 2015 05:08:56 +0200 Subject: [PATCH 11/23] Added zero-filling code for assert stats before sending them to the monitoring process --- include/criterion/assert.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/include/criterion/assert.h b/include/criterion/assert.h index 2111409..bf9e7fe 100644 --- a/include/criterion/assert.h +++ b/include/criterion/assert.h @@ -60,6 +60,12 @@ struct criterion_assert_args { # define CR_GET_CONDITION_STR(Condition, ...) #Condition # define CR_VA_SKIP(_, ...) __VA_ARGS__ +# ifndef __cplusplus +# define CR_ZERO_FILL(Arg) memset(&(Arg), 0, sizeof (Arg)) +# else +# define CR_ZERO_FILL(Arg) std::memset(&(Arg), 0, sizeof (Arg)) +# endif + # define cr_assert_impl(Kind, ...) \ do { \ struct criterion_assert_args args = { \ @@ -67,6 +73,7 @@ struct criterion_assert_args { }; \ int passed = !!(CR_EXPAND(CR_GET_CONDITION(__VA_ARGS__))); \ struct criterion_assert_stats stat; \ + CR_ZERO_FILL(stat); \ stat.kind = (Kind); \ stat.condition = CR_EXPAND(CR_GET_CONDITION_STR(__VA_ARGS__)); \ stat.message = args.msg ? args.msg : ""; \ From 7fca89739f1abf46123d53b24613e0f708cffed7 Mon Sep 17 00:00:00 2001 From: Snaipe Date: Mon, 7 Sep 2015 05:17:27 +0200 Subject: [PATCH 12/23] Removed fast-fail flag for appveyor builds --- appveyor.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index ca061d3..692534d 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -27,9 +27,6 @@ environment: clone_depth: 5 -matrix: - fast_finish: true # set this flag to immediately finish build once one of the jobs fails. - platform: - x86_64 From 4b2fb35d31c577d7d84fc8caf388aa738801a85c Mon Sep 17 00:00:00 2001 From: Snaipe Date: Mon, 7 Sep 2015 05:27:00 +0200 Subject: [PATCH 13/23] Added RDP details for Appveyor VM debugging. --- appveyor.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/appveyor.yml b/appveyor.yml index 692534d..45385c4 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -3,6 +3,7 @@ version: 1.3.1_b{build}-{branch} os: Visual Studio 2015 init: + - ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) - git config --global core.autocrlf input - 'SET PATH=%PATH%;C:\MinGW\msys\1.0\bin;C:\MinGW\bin;%APPVEYOR_BUILD_FOLDER%\bin;%APPVEYOR_BUILD_FOLDER%\build' From 91200ed8dd59c2ebaf4229db9e47caf1e7637327 Mon Sep 17 00:00:00 2001 From: Snaipe Date: Mon, 7 Sep 2015 05:35:32 +0200 Subject: [PATCH 14/23] Changed path ordering to include C:\MinGW\bin before anything else --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 45385c4..5d22cd9 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -5,7 +5,7 @@ os: Visual Studio 2015 init: - ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) - git config --global core.autocrlf input - - 'SET PATH=%PATH%;C:\MinGW\msys\1.0\bin;C:\MinGW\bin;%APPVEYOR_BUILD_FOLDER%\bin;%APPVEYOR_BUILD_FOLDER%\build' + - 'SET PATH=C:\MinGW\bin;%PATH%;C:\MinGW\msys\1.0\bin;%APPVEYOR_BUILD_FOLDER%\bin;%APPVEYOR_BUILD_FOLDER%\build' environment: COVERALLS_REPO_TOKEN: From 18f218f4df9a62fa7132ad82cd23cfa6431ec22b Mon Sep 17 00:00:00 2001 From: Snaipe Date: Mon, 7 Sep 2015 05:42:25 +0200 Subject: [PATCH 15/23] Revert "Removed report.cc from MinGW build on appveyor" This reverts commit 20d5f6fe59791478524686221263067360f904dc. --- samples/CMakeLists.txt | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt index 1512ae8..5ab40fb 100644 --- a/samples/CMakeLists.txt +++ b/samples/CMakeLists.txt @@ -21,6 +21,7 @@ set(SAMPLES signal.cc exit.cc + report.cc suites.cc fixtures.cc asserts.cc @@ -31,10 +32,6 @@ set(SAMPLES simple.cc ) -if (NOT WIN32 OR MSVC) - set(SAMPLES ${SAMPLES} report.cc) -endif () - set(SCRIPTS tap_test early_exit From ffd6c5a5e7628a8c82631763263a30b445e63900 Mon Sep 17 00:00:00 2001 From: Snaipe Date: Mon, 7 Sep 2015 05:42:29 +0200 Subject: [PATCH 16/23] Revert "Added RDP details for Appveyor VM debugging." This reverts commit 4b2fb35d31c577d7d84fc8caf388aa738801a85c. --- appveyor.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 5d22cd9..26f267d 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -3,7 +3,6 @@ version: 1.3.1_b{build}-{branch} os: Visual Studio 2015 init: - - ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) - git config --global core.autocrlf input - 'SET PATH=C:\MinGW\bin;%PATH%;C:\MinGW\msys\1.0\bin;%APPVEYOR_BUILD_FOLDER%\bin;%APPVEYOR_BUILD_FOLDER%\build' From f35bc3d21c4d3d3339bb410e68581a19d883b7b3 Mon Sep 17 00:00:00 2001 From: Snaipe Date: Mon, 7 Sep 2015 07:26:53 +0200 Subject: [PATCH 17/23] Fixed VC++ not registering any sections and internal crashes due to test data not being zero-filled --- include/criterion/criterion.h | 4 ++-- include/criterion/designated-initializer-compat.h | 1 + include/criterion/hooks.h | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/include/criterion/criterion.h b/include/criterion/criterion.h index bc82ccc..172c585 100644 --- a/include/criterion/criterion.h +++ b/include/criterion/criterion.h @@ -54,7 +54,7 @@ __VA_ARGS__ \ )); \ SECTION_("cr_tst") \ - const struct criterion_test IDENTIFIER_(Category, Name, meta) = { \ + struct criterion_test IDENTIFIER_(Category, Name, meta) = { \ #Name, \ #Category, \ IDENTIFIER_(Category, Name, impl), \ @@ -71,7 +71,7 @@ __VA_ARGS__ \ )); \ SECTION_("cr_sts") \ - const struct criterion_suite SUITE_IDENTIFIER_(Name, meta) = { \ + struct criterion_suite SUITE_IDENTIFIER_(Name, meta) = { \ #Name, \ &SUITE_IDENTIFIER_(Name, extra), \ } SECTION_SUFFIX_ diff --git a/include/criterion/designated-initializer-compat.h b/include/criterion/designated-initializer-compat.h index 910952b..bda193b 100644 --- a/include/criterion/designated-initializer-compat.h +++ b/include/criterion/designated-initializer-compat.h @@ -114,6 +114,7 @@ # ifdef __cplusplus # define CRITERION_MAKE_STRUCT(Type, ...) [&]() { \ Type t; \ + std::memset(&t, 0, sizeof (t)); \ CR_EXPAND(CRITERION_ADD_PREFIX(t, __VA_ARGS__)) \ return t; \ }() diff --git a/include/criterion/hooks.h b/include/criterion/hooks.h index d6ceed2..62ab483 100644 --- a/include/criterion/hooks.h +++ b/include/criterion/hooks.h @@ -91,7 +91,7 @@ typedef void (*f_report_hook)(); # define ReportHook(Kind) \ HOOK_PROTOTYPE_(HOOK_PARAM_TYPE(Kind)); \ SECTION_(HOOK_SECTION_STRINGIFY(Kind)) \ - const f_report_hook HOOK_IDENTIFIER_(func) = \ + f_report_hook HOOK_IDENTIFIER_(func) = \ (f_report_hook) HOOK_IDENTIFIER_(impl) \ SECTION_SUFFIX_; \ HOOK_PROTOTYPE_ From 47d12933039f279563cbc5eaef0c77d1141dacee Mon Sep 17 00:00:00 2001 From: Snaipe Date: Mon, 7 Sep 2015 08:22:02 +0200 Subject: [PATCH 18/23] Made the theory interface C++11-compatible --- include/criterion/theories.h | 27 ++++++++- samples/CMakeLists.txt | 1 + samples/theories.cc | 112 +++++++++++++++++++++++++++++++++++ 3 files changed, 137 insertions(+), 3 deletions(-) create mode 100644 samples/theories.cc diff --git a/include/criterion/theories.h b/include/criterion/theories.h index f23c223..be9bf8b 100644 --- a/include/criterion/theories.h +++ b/include/criterion/theories.h @@ -24,9 +24,22 @@ #ifndef CRITERION_THEORIES_H_ # define CRITERION_THEORIES_H_ -# include +# ifdef __cplusplus +# include +using std::size_t; +# else +# include +# endif + # include "criterion.h" +# ifdef __cplusplus +template +constexpr size_t criterion_va_num__(const T &...) { + return sizeof...(T); +}; +# endif + CR_BEGIN_C_API struct criterion_theory_context; @@ -43,11 +56,19 @@ CR_API void cr_theory_call(struct criterion_theory_context *ctx, void (*fnptr)(v # define TheoryDataPoints(Category, Name) \ static struct criterion_datapoints IDENTIFIER_(Category, Name, dps)[] +# ifdef __cplusplus +# define CR_TH_VA_NUM(Type, ...) criterion_va_num__(__VA_ARGS__) +# define CR_TH_TEMP_ARRAY(Type, ...) []() { static Type arr[] = { __VA_ARGS__ }; return &arr; }() +# else +# define CR_TH_VA_NUM(Type, ...) sizeof ((Type[]) { __VA_ARGS__ }) / sizeof (Type) +# define CR_TH_TEMP_ARRAY(Type, ...) &(Type[]) { __VA_ARGS__ } +# endif + # define DataPoints(Type, ...) { \ sizeof (Type), \ - sizeof ((Type[]) { __VA_ARGS__ }) / sizeof (Type), \ + CR_EXPAND(CR_TH_VA_NUM(Type, __VA_ARGS__)), \ #Type, \ - &(Type[]) { __VA_ARGS__ }, \ + CR_EXPAND(CR_TH_TEMP_ARRAY(Type, __VA_ARGS__)), \ } struct criterion_datapoints { diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt index 5ab40fb..efbef5e 100644 --- a/samples/CMakeLists.txt +++ b/samples/CMakeLists.txt @@ -30,6 +30,7 @@ set(SAMPLES description.cc other-crashes.cc simple.cc + theories.cc ) set(SCRIPTS diff --git a/samples/theories.cc b/samples/theories.cc new file mode 100644 index 0000000..62f8b91 --- /dev/null +++ b/samples/theories.cc @@ -0,0 +1,112 @@ +#ifdef _MSC_VER +#pragma warning(disable : 4090) +#endif + +#include +#ifdef __cplusplus +# include +#else +# include +#endif + +# define INT_DATAPOINTS DataPoints(int, 0, 1, 2, -1, -2, INT_MAX, INT_MIN) + +// Let's test the multiplicative properties of 32-bit integers: + +int bad_mul(int a, int b) { + return a * b; +} + +int bad_div(int a, int b) { + return a / b; +} + +TheoryDataPoints(algebra, bad_divide_is_inverse_of_multiply) = { + INT_DATAPOINTS, + INT_DATAPOINTS, +}; + +Theory((int a, int b), algebra, bad_divide_is_inverse_of_multiply) { + cr_assume(b != 0); + cr_assert_eq(a, bad_div(bad_mul(a, b), b)); +} + +// The above implementation of mul & div fails the test because of overflows, +// let's try again: + +long long good_mul(long long a, long long b) { + return a * b; +} + +long long good_div(long long a, long long b) { + return a / b; +} + +TheoryDataPoints(algebra, good_divide_is_inverse_of_multiply) = { + INT_DATAPOINTS, + INT_DATAPOINTS, +}; + +Theory((int a, int b), algebra, good_divide_is_inverse_of_multiply) { + cr_assume(b != 0); + cr_assert_eq(a, good_div(good_mul(a, b), b)); +} + +// For triangulation + +Test(algebra, multiplication_by_integer) { + cr_assert_eq(10, good_mul(5, 2)); +} + +// Another property test + +TheoryDataPoints(algebra, zero_is_absorbing) = { + INT_DATAPOINTS, + INT_DATAPOINTS, +}; + +Theory((int a, int b), algebra, zero_is_absorbing) { + cr_assume(a == 0 || b == 0); + cr_assert_eq(0, good_mul(a, b)); +} + +// Testing for various parameters + +struct my_object { + int foo; +}; + +struct my_object o = {42}; + +char test_str[] = {'t', 'e', 's', 't', '\0'}; + +TheoryDataPoints(theory, misc) = { + DataPoints(char, 'a'), + DataPoints(bool, true), + DataPoints(short, 1), + DataPoints(int, 1), + DataPoints(long, 1), + DataPoints(long long, 1), + DataPoints(float, 3.14f), + DataPoints(double, 3.14), + DataPoints(char *, test_str), + DataPoints(const char *, "other test"), + DataPoints(struct my_object *, &o), +}; + +Theory((char c, bool b, short s, int i, long l, long long ll, float f, double d, char *str, const char *cstr, struct my_object *obj), theory, misc) { + cr_assert(b); + cr_assert_eq(c, 'a'); + cr_assert_eq(s, 1); + cr_assert_eq(i, 1); + cr_assert_eq(l, 1); + cr_assert_eq(ll, 1); + cr_assert_eq(f, 3.14f); + cr_assert_eq(d, 3.14); + cr_assert_strings_eq(str, "test"); + cr_assert_strings_eq(cstr, "other test"); + cr_assert_eq(obj->foo, 42); + + // abort to see the formatted string of all parameters + cr_abort_test(NULL); +} From 59e91f9404c7383c50d15dbdfd9e806fde9ad990 Mon Sep 17 00:00:00 2001 From: Snaipe Date: Mon, 7 Sep 2015 08:24:52 +0200 Subject: [PATCH 19/23] Removed extra semicolon --- include/criterion/theories.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/criterion/theories.h b/include/criterion/theories.h index be9bf8b..3dc42c5 100644 --- a/include/criterion/theories.h +++ b/include/criterion/theories.h @@ -37,7 +37,7 @@ using std::size_t; template constexpr size_t criterion_va_num__(const T &...) { return sizeof...(T); -}; +} # endif CR_BEGIN_C_API From a9f325874a61585d4f334a8d5ab0c36833edbd8e Mon Sep 17 00:00:00 2001 From: Snaipe Date: Mon, 7 Sep 2015 08:37:28 +0200 Subject: [PATCH 20/23] Switched type of 'passed' to bool instead of int --- include/criterion/assert.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/criterion/assert.h b/include/criterion/assert.h index bf9e7fe..539393d 100644 --- a/include/criterion/assert.h +++ b/include/criterion/assert.h @@ -71,7 +71,7 @@ struct criterion_assert_args { struct criterion_assert_args args = { \ CR_EXPAND(CR_VA_SKIP(__VA_ARGS__)) \ }; \ - int passed = !!(CR_EXPAND(CR_GET_CONDITION(__VA_ARGS__))); \ + bool passed = !!(CR_EXPAND(CR_GET_CONDITION(__VA_ARGS__))); \ struct criterion_assert_stats stat; \ CR_ZERO_FILL(stat); \ stat.kind = (Kind); \ From 17cd3c6509bafff4874d520a6feba5da71616796 Mon Sep 17 00:00:00 2001 From: Snaipe Date: Mon, 7 Sep 2015 08:45:38 +0200 Subject: [PATCH 21/23] Removed bogus assert in asserts.{c,cc} samples --- samples/asserts.c | 2 +- samples/asserts.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/asserts.c b/samples/asserts.c index ef5bc98..0d9daab 100644 --- a/samples/asserts.c +++ b/samples/asserts.c @@ -74,7 +74,7 @@ Test(asserts, array) { s2[1].a = 2; s2[1].b = 4; - cr_assert_arrays_neq(s1, s2, 2); + // cr_assert_arrays_eq(s1, s2, 2); not guaranteed to work on structs. cr_assert_arrays_eq_cmp(s1, s2, 2, eq_dummy); #endif } diff --git a/samples/asserts.cc b/samples/asserts.cc index ef5bc98..0d9daab 100644 --- a/samples/asserts.cc +++ b/samples/asserts.cc @@ -74,7 +74,7 @@ Test(asserts, array) { s2[1].a = 2; s2[1].b = 4; - cr_assert_arrays_neq(s1, s2, 2); + // cr_assert_arrays_eq(s1, s2, 2); not guaranteed to work on structs. cr_assert_arrays_eq_cmp(s1, s2, 2, eq_dummy); #endif } From 60760092b403f5f67a4d8e98ea3bdf93469068be Mon Sep 17 00:00:00 2001 From: Snaipe Date: Mon, 7 Sep 2015 10:22:37 +0200 Subject: [PATCH 22/23] Fixed __VA_ARG__ warnings & added -pedantic to c++ samples --- include/criterion/designated-initializer-compat.h | 4 ++-- samples/CMakeLists.txt | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/criterion/designated-initializer-compat.h b/include/criterion/designated-initializer-compat.h index bda193b..3b2a7ba 100644 --- a/include/criterion/designated-initializer-compat.h +++ b/include/criterion/designated-initializer-compat.h @@ -103,11 +103,11 @@ # define CRITERION_APPLY_64(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_63(Macro, Prefix, __VA_ARGS__)) # define CRITERION_APPLY_65(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_64(Macro, Prefix, __VA_ARGS__)) -# define CRITERION_APPLY__(Macro, Prefix, n, ...) CR_EXPAND(CRITERION_APPLY_##n(Macro, Prefix, __VA_ARGS__)) +# define CRITERION_APPLY__(Macro, Prefix, n, ...) CR_EXPAND(CRITERION_APPLY_##n(Macro, Prefix, __VA_ARGS__,)) # define CRITERION_APPLY_(Macro, n, Prefix, ...) CR_EXPAND(CRITERION_APPLY__(Macro, Prefix, n, __VA_ARGS__)) # define CRITERION_APPLY(Macro, ...) CR_EXPAND(CRITERION_APPLY_(Macro, CRITERION_ARG_LENGTH(__VA_ARGS__), __VA_ARGS__)) -# define CRITERION_ADD_PREFIX_ONCE(Prefix, Field, ...) Prefix Field; +# define CRITERION_ADD_PREFIX_ONCE(Prefix, Field) Prefix Field; # define CRITERION_ADD_PREFIX(...) \ CR_EXPAND(CRITERION_APPLY(CRITERION_ADD_PREFIX_ONCE, __VA_ARGS__)) diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt index efbef5e..f95f255 100644 --- a/samples/CMakeLists.txt +++ b/samples/CMakeLists.txt @@ -1,6 +1,6 @@ if (NOT MSVC) set(CMAKE_C_FLAGS "-std=c99 -Wall -Wextra -pedantic") - set(CMAKE_CXX_FLAGS "-std=c++11 -Wall -Wextra") + set(CMAKE_CXX_FLAGS "-std=c++11 -Wall -Wextra -pedantic") endif () include_directories(../include) From 7e1bdc54f83af27be912813ce7adc637cf422a43 Mon Sep 17 00:00:00 2001 From: Snaipe Date: Mon, 7 Sep 2015 10:35:17 +0200 Subject: [PATCH 23/23] Updated README with C++ mentions --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4ddc347..3c93776 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ [![License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat)](https://github.com/Snaipe/Criterion/blob/master/LICENSE) [![Version](https://img.shields.io/github/tag/Snaipe/Criterion.svg?label=version&style=flat)](https://github.com/Snaipe/Criterion/releases) -A dead-simple, yet extensible, C unit testing framework. +A dead-simple, yet extensible, C and C++ unit testing framework. ![Screencast](./doc/screencast.gif) @@ -24,12 +24,14 @@ This gives the user great control, at the unfortunate cost of simplicity. Criterion follows the KISS principle, while keeping the control the user would have with other frameworks: +* [x] C99 and C++11 compatible. * [x] Tests are automatically registered when declared. * [x] Implements a xUnit framework structure. * [x] A default entry point is provided, no need to declare a main unless you want to do special handling. * [x] Test are isolated in their own process, crashes and signals can be reported and tested. +* [x] Unified interface between C and C++: include the criterion header and it *just* works. * [x] There is a support for theories alongside tests * [x] Progress and statistics can be followed in real time with report hooks. * [x] TAP output format can be enabled with an option. @@ -89,7 +91,7 @@ be merged. ## F.A.Q. -**Q. What's wrong with other test frameworks?** +**Q. What's wrong with other C test frameworks?** A. I worked with CUnit and Check, and I must say that they do their job very well -- the only thing that bugs me is that setting up a test suite from scratch is a pain, it should really be simpler. Most