Merge branch 'features/better-asserts' into bleeding
ChangeLog: + Added format strings for all assertion macros. + Added cr_assert_fail and cr_expect_fail. + Added assertions for array lexicographical comparisons. - Deprecated: cr_abort_test. - Deprecated: cr_{assert,expect}_strings_*, cr_{assert,expect}_arrays_* are now deprecated in favor of cr_{assert,expect}_str_*, cr_{assert,expect}_arr_* respectively. - Breaking: cr_abort_test(NULL) is now invalid.
This commit is contained in:
commit
fc3d34c4e2
34 changed files with 943 additions and 379 deletions
|
@ -98,6 +98,7 @@ set(SOURCE_FILES
|
|||
src/ordered-set.c
|
||||
src/posix-compat.c
|
||||
src/theories.c
|
||||
src/asprintf.c
|
||||
src/main.c
|
||||
src/entry.c
|
||||
)
|
||||
|
@ -123,6 +124,7 @@ set(INTERFACE_FILES
|
|||
include/criterion/ordered-set.h
|
||||
include/criterion/stats.h
|
||||
include/criterion/theories.h
|
||||
include/criterion/asprintf-compat.h
|
||||
)
|
||||
|
||||
# Generate the configure file
|
||||
|
|
96
doc/assert.rst
Normal file
96
doc/assert.rst
Normal file
|
@ -0,0 +1,96 @@
|
|||
.. _assertions-ref:
|
||||
|
||||
Assertion reference
|
||||
===================
|
||||
|
||||
This is an exhaustive list of all assertion macros that Criterion provides.
|
||||
|
||||
As each ``assert`` macros have an ``expect`` counterpart with the exact same
|
||||
number of parameters and name suffix, there is no benefit in adding ``expect``
|
||||
macros to this list. Hence only ``assert`` macros are represented here.
|
||||
|
||||
Common Assertions
|
||||
-----------------
|
||||
|
||||
======================================================================= =========================================================================== ===========================================
|
||||
Macro Passes if and only if Notes
|
||||
======================================================================= =========================================================================== ===========================================
|
||||
cr_assert(Condition, [Message, [Args...]]) ``Condition`` is true.
|
||||
----------------------------------------------------------------------- --------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_not(Condition, [Message, [Args...]]) ``Condition`` is false.
|
||||
----------------------------------------------------------------------- --------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_null(Value, [Message, [Args...]]) ``Value`` is ``NULL``.
|
||||
----------------------------------------------------------------------- --------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_not_null(Value, [Message, [Args...]]) ``Value`` is not ``NULL``.
|
||||
----------------------------------------------------------------------- --------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_eq(Actual, Expected, [Message, [Args...]]) ``Actual`` is equal to ``Expected``. Compatible with C++ operator overloading
|
||||
----------------------------------------------------------------------- --------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_neq(Actual, Unexpected, [Message, [Args...]]) ``Actual`` is not equal to ``Unexpected``. Compatible with C++ operator overloading
|
||||
----------------------------------------------------------------------- --------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_lt(Actual, Reference, [Message, [Args...]]) ``Actual`` is less than ``Reference``. Compatible with C++ operator overloading
|
||||
----------------------------------------------------------------------- --------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_leq(Actual, Reference, [Message, [Args...]]) ``Actual`` is less or equal to ``Reference``. Compatible with C++ operator overloading
|
||||
----------------------------------------------------------------------- --------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_gt(Actual, Reference, [Message, [Args...]]) ``Actual`` is greater than ``Reference``. Compatible with C++ operator overloading
|
||||
----------------------------------------------------------------------- --------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_geq(Actual, Reference, [Message, [Args...]]) ``Actual`` is greater or equal to ``Reference``. Compatible with C++ operator overloading
|
||||
----------------------------------------------------------------------- --------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_float_eq(Actual, Expected, Epsilon, [Message, [Args...]]) ``Actual`` is equal to ``Expected`` with a tolerance of ``Epsilon``. Use this to test equality between floats
|
||||
----------------------------------------------------------------------- --------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_float_neq(Actual, Unexpected, Epsilon, [Message, [Args...]]) ``Actual`` is not equal to ``Unexpected`` with a tolerance of ``Epsilon``. Use this to test inequality between floats
|
||||
======================================================================= =========================================================================== ===========================================
|
||||
|
||||
String Assertions
|
||||
-----------------
|
||||
|
||||
Note: these macros are meant to deal with *native* strings, i.e. char arrays.
|
||||
Most of them won't work on ``std::string`` in C++, with some exceptions -- for
|
||||
``std::string``, you should use regular comparison assersions, as listed above.
|
||||
|
||||
=========================================================== =================================================================== ===========================================
|
||||
Macro Passes if and only if Notes
|
||||
=========================================================== =================================================================== ===========================================
|
||||
cr_assert_str_empty(Value, [Message, [Args...]]) ``Value`` is an empty string. Also works on std::string
|
||||
----------------------------------------------------------- ------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_str_not_empty(Value, [Message, [Args...]]) ``Value`` is not an empty string. Also works on std::string
|
||||
----------------------------------------------------------- ------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_str_eq(Actual, Expected, [Message, [Args...]]) ``Actual`` is lexicographically equal to ``Expected``.
|
||||
----------------------------------------------------------- ------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_str_neq(Actual, Unexpected, [Message, [Args...]]) ``Actual`` is not lexicographically equal to ``Unexpected``.
|
||||
----------------------------------------------------------- ------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_str_lt(Actual, Reference, [Message, [Args...]]) ``Actual`` is lexicographically less than ``Reference``.
|
||||
----------------------------------------------------------- ------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_str_leq(Actual, Reference, [Message, [Args...]]) ``Actual`` is lexicographically less or equal to ``Reference``.
|
||||
----------------------------------------------------------- ------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_str_gt(Actual, Reference, [Message, [Args...]]) ``Actual`` is lexicographically greater than ``Reference``.
|
||||
----------------------------------------------------------- ------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_str_geq(Actual, Reference, [Message, [Args...]]) ``Actual`` is lexicographically greater or equal to ``Reference``.
|
||||
=========================================================== =================================================================== ===========================================
|
||||
|
||||
Array Assertions
|
||||
-----------------
|
||||
|
||||
=========================================================================== =========================================================================== ===========================================
|
||||
Macro Passes if and only if Notes
|
||||
=========================================================================== =========================================================================== ===========================================
|
||||
cr_assert_arr_eq(Actual, Expected, [Message, [Args...]]) ``Actual`` is byte-to-byte equal to ``Expected``. This should not be used on struct arrays,
|
||||
consider using ``cr_assert_arr_eq_cmp``
|
||||
instead.
|
||||
--------------------------------------------------------------------------- --------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_arr_neq(Actual, Unexpected, [Message, [Args...]]) ``Actual`` is not byte-to-byte equal to ``Unexpected``. This should not be used on struct arrays,
|
||||
consider using ``cr_assert_arr_neq_cmp``
|
||||
instead.
|
||||
--------------------------------------------------------------------------- --------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_arr_eq_cmp(Actual, Expected, Size, Cmp, [Message, [Args...]]) ``Actual`` is comparatively equal to ``Expected`` Only available in C++ and GNU C99
|
||||
--------------------------------------------------------------------------- --------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_arr_neq_cmp(Actual, Unexpected, Size, Cmp, [Message, [Args...]]) ``Actual`` is not comparatively equal to ``Expected`` Only available in C++ and GNU C99
|
||||
--------------------------------------------------------------------------- --------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_arr_lt_cmp(Actual, Reference, Size, Cmp, [Message, [Args...]]) ``Actual`` is comparatively less than ``Reference`` Only available in C++ and GNU C99
|
||||
--------------------------------------------------------------------------- --------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_arr_leq_cmp(Actual, Reference, Size, Cmp, [Message, [Args...]]) ``Actual`` is comparatively less or equal to ``Reference`` Only available in C++ and GNU C99
|
||||
--------------------------------------------------------------------------- --------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_arr_gt_cmp(Actual, Reference, Size, Cmp, [Message, [Args...]]) ``Actual`` is comparatively greater than ``Reference`` Only available in C++ and GNU C99
|
||||
--------------------------------------------------------------------------- --------------------------------------------------------------------------- -------------------------------------------
|
||||
cr_assert_arr_geq_cmp(Actual, Reference, Size, Cmp, [Message, [Args...]]) ``Actual`` is comparatively greater or equal to ``Reference`` Only available in C++ and GNU C99
|
||||
=========================================================================== =========================================================================== ===========================================
|
||||
|
|
@ -7,6 +7,7 @@ Criterion
|
|||
intro
|
||||
setup
|
||||
starter
|
||||
assert
|
||||
hooks
|
||||
env
|
||||
theories
|
||||
|
|
|
@ -48,45 +48,8 @@ parameter, and an optional failure message:
|
|||
cr_assert(strlen("") == 0);
|
||||
}
|
||||
|
||||
On top of those, more assertions are available for common operations:
|
||||
|
||||
* ``cr_assert_null(Ptr, [Message])``: passes if Ptr is NULL.
|
||||
* ``cr_assert_eq(Actual, Expected, [Message])``: passes if Actual == Expected.
|
||||
* ``cr_assert_lt(Actual, Expected, [Message])``: passes if Actual < Expected.
|
||||
* ``cr_assert_leq(Actual, Expected, [Message])``: passes if Actual <= Expected.
|
||||
* ``cr_assert_gt(Actual, Expected, [Message])``: passes if Actual > Expected.
|
||||
* ``cr_assert_geq(Actual, Expected, [Message])``: passes if Actual >= Expected.
|
||||
* ``cr_assert_float_eq(Actual, Expected, Epsilon, [Message])``:
|
||||
passes if Actual == Expected with an error of Epsilon.
|
||||
* ``cr_assert_arrays_eq(Actual, Expected, Size, [Message])``:
|
||||
passes if all elements of Actual (from 0 to Size - 1) are equals to those
|
||||
of Expected.
|
||||
* ``cr_assert_arrays_eq_cmp(Actual, Expected, Size, Cmp, [Message])``:
|
||||
Same as ``arrays_eq`` but equality is defined by the result of the binary
|
||||
Cmp function.
|
||||
|
||||
Equality and lexical comparison assertions are also available for strings:
|
||||
|
||||
* ``cr_assert_strings_eq(Actual, Expected, [Message])``
|
||||
* ``cr_assert_strings_lt(Actual, Expected, [Message])``
|
||||
* ``cr_assert_strings_leq(Actual, Expected, [Message])``
|
||||
* ``cr_assert_strings_gt(Actual, Expected, [Message])``
|
||||
* ``cr_assert_strings_geq(Actual, Expected, [Message])``
|
||||
|
||||
And some assertions have a logical negative counterpart:
|
||||
|
||||
* ``cr_assert_not(Condition, [Message])``
|
||||
* ``cr_assert_not_null(Ptr, [Message])``
|
||||
* ``cr_assert_neq(Actual, Unexpected, [Message])``
|
||||
* ``cr_assert_float_neq(Actual, Unexpected, Epsilon, [Message])``
|
||||
* ``cr_assert_strings_neq(Actual, Unexpected, [Message])``
|
||||
* ``cr_assert_arrays_neq(Actual, Unexpected, Size, [Message])``
|
||||
* ``cr_assert_arrays_neq_cmp(Actual, Unexpected, Size, Cmp, [Message])``
|
||||
|
||||
Of course, every ``assert`` has an ``expect`` counterpart.
|
||||
|
||||
Please note that ``arrays_(n)eq`` assertions should not be used on padded
|
||||
structures -- please use ``arrays_(n)eq_cmp`` instead.
|
||||
On top of those, more assertions are available for common operations. See
|
||||
:ref:`assertions-ref` for a complete list.
|
||||
|
||||
Configuring tests
|
||||
-----------------
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
CR_BEGIN_C_API
|
||||
|
||||
CR_API NORETURN void criterion_abort_test(void);
|
||||
CR_INLINE static void criterion_continue_test(void) {}
|
||||
|
||||
CR_END_C_API
|
||||
|
||||
|
|
43
include/criterion/asprintf-compat.h
Normal file
43
include/criterion/asprintf-compat.h
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2015 Franklin "Snaipe" Mathieu <http://snai.pe/>
|
||||
*
|
||||
* 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_ASPRINTF_COMPAT_H_
|
||||
# define CRITERION_ASPRINTF_COMPAT_H_
|
||||
|
||||
# ifdef __cplusplus
|
||||
# include <cstdarg>
|
||||
# else
|
||||
# include <stdarg.h>
|
||||
# endif
|
||||
|
||||
# include "common.h"
|
||||
|
||||
CR_BEGIN_C_API
|
||||
|
||||
FORMAT(printf, 2, 3)
|
||||
CR_API int cr_asprintf(char **strp, const char *fmt, ...);
|
||||
CR_API int cr_vasprintf(char **strp, const char *fmt, va_list ap);
|
||||
|
||||
CR_END_C_API
|
||||
|
||||
#endif /* !CRITERION_ASPRINTF_COMPAT_H_ */
|
|
@ -24,11 +24,13 @@
|
|||
#ifndef CRITERION_ASSERT_H_
|
||||
# define CRITERION_ASSERT_H_
|
||||
|
||||
# include "preprocess.h"
|
||||
# include "asprintf-compat.h"
|
||||
|
||||
# ifdef __cplusplus
|
||||
# include <cstring>
|
||||
# include <cstdlib>
|
||||
using std::strcmp;
|
||||
using std::memcmp;
|
||||
# include <algorithm>
|
||||
# else
|
||||
# include <string.h>
|
||||
# include <stdlib.h>
|
||||
|
@ -41,11 +43,6 @@ using std::memcmp;
|
|||
# include "event.h"
|
||||
# include "abort.h"
|
||||
|
||||
enum criterion_assert_kind {
|
||||
NORMAL,
|
||||
FATAL
|
||||
};
|
||||
|
||||
struct criterion_assert_args {
|
||||
const char *msg;
|
||||
int sentinel_;
|
||||
|
@ -60,274 +57,457 @@ 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 = { \
|
||||
CR_EXPAND(CR_VA_SKIP(__VA_ARGS__)) \
|
||||
}; \
|
||||
bool 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 : ""; \
|
||||
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) \
|
||||
do { \
|
||||
const char *msg = (Message); \
|
||||
cr_assert(0, msg ? msg : "The conditions for this test were not met.");\
|
||||
} while (0)
|
||||
|
||||
# ifdef __cplusplus
|
||||
# define CR_SENTINEL 0
|
||||
# define CR_STDN std::
|
||||
# else
|
||||
# define CR_SENTINEL .sentinel_ = 0
|
||||
# define CR_STDN
|
||||
# endif
|
||||
|
||||
# define cr_assert(...) CR_EXPAND(cr_assert_(__VA_ARGS__, CR_SENTINEL))
|
||||
# define CR_INIT_STATS_(BufSize, MsgVar, ...) CR_EXPAND( \
|
||||
do { \
|
||||
const char *default_msg = "" CR_VA_HEAD(__VA_ARGS__); \
|
||||
char *formatted_msg = NULL; \
|
||||
int msglen = cr_asprintf(&formatted_msg, "" CR_VA_TAIL(__VA_ARGS__)); \
|
||||
MsgVar = formatted_msg && *formatted_msg ? \
|
||||
formatted_msg : default_msg; \
|
||||
\
|
||||
if (!formatted_msg || !*formatted_msg) \
|
||||
msglen = strlen(default_msg); \
|
||||
\
|
||||
BufSize = sizeof(struct criterion_assert_stats) \
|
||||
+ sizeof (size_t) + msglen + 1; \
|
||||
\
|
||||
char *buf = (char*) CR_STDN malloc(BufSize); \
|
||||
stat = (struct criterion_assert_stats*) buf; \
|
||||
CR_STDN memset(buf, 0, sizeof (struct criterion_assert_stats)); \
|
||||
buf += sizeof (struct criterion_assert_stats); \
|
||||
*((size_t*) buf) = msglen + 1; \
|
||||
buf += sizeof (size_t); \
|
||||
CR_STDN strcpy(buf, MsgVar); \
|
||||
CR_STDN free(formatted_msg); \
|
||||
} while (0))
|
||||
|
||||
# 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__, 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__))
|
||||
# define cr_expect_not_(Condition, ...) \
|
||||
CR_EXPAND(cr_expect_impl(NORMAL, !(Condition), __VA_ARGS__))
|
||||
|
||||
// Native asserts
|
||||
|
||||
# define cr_assert_op_(Op, Actual, Expected, ...) \
|
||||
CR_EXPAND(cr_assert_impl(FATAL, (Actual) Op (Expected), __VA_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__, 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__, 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__, 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__, 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__, 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__, 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__, 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__, 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__, CR_SENTINEL))
|
||||
# define cr_expect_float_eq(...) \
|
||||
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) \
|
||||
&& (Actual) - (Expected) <= (Epsilon), \
|
||||
__VA_ARGS__))
|
||||
# define cr_expect_float_eq_(Actual, Expected, Epsilon, ...) \
|
||||
CR_EXPAND(cr_assert_impl(NORMAL, (Expected) - (Actual) <= (Epsilon) \
|
||||
&& (Actual) - (Expected) <= (Epsilon), \
|
||||
__VA_ARGS__))
|
||||
|
||||
# define cr_assert_float_neq(...) \
|
||||
CR_EXPAND(cr_assert_float_neq_(__VA_ARGS__, CR_SENTINEL))
|
||||
# define cr_expect_float_neq(...) \
|
||||
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) \
|
||||
|| (Actual) - (Expected) > (Epsilon), \
|
||||
__VA_ARGS__))
|
||||
# define cr_expect_float_neq_(Actual, Expected, Epsilon, ...) \
|
||||
CR_EXPAND(cr_assert_impl(NORMAL, (Expected) - (Actual) > (Epsilon) \
|
||||
|| (Actual) - (Expected) > (Epsilon), \
|
||||
__VA_ARGS__))
|
||||
|
||||
// String asserts
|
||||
|
||||
# define cr_assert_strings_(Op, Actual, Expected, ...) \
|
||||
CR_EXPAND(cr_assert_impl(FATAL, strcmp((Actual), (Expected)) Op 0, __VA_ARGS__))
|
||||
# define cr_expect_strings_(Op, Actual, Expected, ...) \
|
||||
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__, CR_SENTINEL))
|
||||
# define cr_expect_strings_eq(...) \
|
||||
CR_EXPAND(cr_expect_strings_(==, __VA_ARGS__, CR_SENTINEL))
|
||||
|
||||
# define cr_assert_strings_neq(...) \
|
||||
CR_EXPAND(cr_assert_strings_(!=, __VA_ARGS__, CR_SENTINEL))
|
||||
# define cr_expect_strings_neq(...) \
|
||||
CR_EXPAND(cr_expect_strings_(!=, __VA_ARGS__, CR_SENTINEL))
|
||||
|
||||
# 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__, 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__, 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__, 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__, CR_SENTINEL))
|
||||
# define cr_expect_arrays_eq(...) \
|
||||
CR_EXPAND(cr_expect_arrays_eq_(__VA_ARGS__, CR_SENTINEL))
|
||||
|
||||
# define cr_assert_arrays_neq(...) \
|
||||
CR_EXPAND(cr_assert_arrays_neq_(__VA_ARGS__, CR_SENTINEL))
|
||||
# define cr_expect_arrays_neq(...) \
|
||||
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)), \
|
||||
__VA_ARGS__))
|
||||
# define cr_expect_arrays_eq_(A, B, Size, ...) \
|
||||
CR_EXPAND(cr_assert_impl(NORMAL, !memcmp((A), (B), (Size)), \
|
||||
__VA_ARGS__))
|
||||
|
||||
# define cr_assert_arrays_neq_(A, B, Size, ...) \
|
||||
CR_EXPAND(cr_assert_impl(FATAL, memcmp((A), (B), (Size)), \
|
||||
__VA_ARGS__))
|
||||
# define cr_expect_arrays_neq_(A, B, Size, ...) \
|
||||
CR_EXPAND(cr_assert_impl(NORMAL, memcmp((A), (B), (Size)), \
|
||||
__VA_ARGS__))
|
||||
# define CR_FAIL_ABORT_ criterion_abort_test
|
||||
# define CR_FAIL_CONTINUES_ criterion_continue_test
|
||||
|
||||
# ifdef __GNUC__
|
||||
# define CRIT_ARR_COMPARE_(A, B, Size, Cmp, Result) \
|
||||
__typeof__(&(A)[0]) first = (A); \
|
||||
__typeof__(&(B)[0]) second = (B); \
|
||||
int equals = 1; \
|
||||
size_t i, size; \
|
||||
for (i = 0, size = (Size); equals && i < size; ++i) \
|
||||
equals = equals && !Cmp(first + i, second + i)
|
||||
// We disable the format-zero-length warning because we use the validity of
|
||||
// asprintf(out, "") for empty assertion messages
|
||||
# pragma GCC diagnostic ignored "-Wformat-zero-length"
|
||||
# endif
|
||||
|
||||
# define cr_assert_arrays_eq_cmp_(A, B, Size, Cmp, ...) \
|
||||
do { \
|
||||
CRIT_ARR_COMPARE_(A, B, Size, Cmp, equals); \
|
||||
cr_assert_impl(FATAL, equals, \
|
||||
__VA_ARGS__); \
|
||||
# define cr_assert_impl(Fail, Condition, ...) \
|
||||
do { \
|
||||
bool passed = !!(Condition); \
|
||||
\
|
||||
const char *msg = NULL; \
|
||||
size_t bufsize; \
|
||||
\
|
||||
struct criterion_assert_stats *stat; \
|
||||
CR_EXPAND(CR_INIT_STATS_(bufsize, msg, CR_VA_TAIL(__VA_ARGS__))); \
|
||||
stat->passed = passed; \
|
||||
stat->file = __FILE__; \
|
||||
stat->line = __LINE__; \
|
||||
\
|
||||
send_event(ASSERT, stat, bufsize); \
|
||||
CR_STDN free(stat); \
|
||||
\
|
||||
if (!passed) \
|
||||
Fail(); \
|
||||
} while (0)
|
||||
|
||||
# define cr_expect_arrays_eq_cmp_(A, B, Size, Cmp, ...) \
|
||||
do { \
|
||||
CRIT_ARR_COMPARE_(A, B, Size, Cmp, equals); \
|
||||
cr_assert_impl(NORMAL, equals, \
|
||||
__VA_ARGS__); \
|
||||
// Base assertions
|
||||
|
||||
# define cr_fail(Fail, ...) \
|
||||
CR_EXPAND(cr_assert_impl( \
|
||||
Fail, \
|
||||
0, \
|
||||
dummy, \
|
||||
"The conditions for this assertion were not met.", \
|
||||
__VA_ARGS__ \
|
||||
))
|
||||
|
||||
# define cr_assert_fail(...) CR_EXPAND(cr_fail(CR_FAIL_ABORT_, __VA_ARGS__))
|
||||
# define cr_expect_fail(...) CR_EXPAND(cr_fail(CR_FAIL_CONTINUES_, __VA_ARGS__))
|
||||
|
||||
# define cr_assert(...) \
|
||||
CR_EXPAND(cr_assert_impl( \
|
||||
CR_FAIL_ABORT_, \
|
||||
CR_VA_HEAD(__VA_ARGS__), \
|
||||
dummy, \
|
||||
"The expression " CR_STR(CR_VA_HEAD(__VA_ARGS__)) " is false.", \
|
||||
CR_VA_TAIL(__VA_ARGS__) \
|
||||
))
|
||||
|
||||
# define cr_expect(...) \
|
||||
CR_EXPAND(cr_assert_impl( \
|
||||
CR_FAIL_CONTINUES_, \
|
||||
CR_VA_HEAD(__VA_ARGS__), \
|
||||
dummy, \
|
||||
"The expression " CR_STR(CR_VA_HEAD(__VA_ARGS__)) " is false.", \
|
||||
CR_VA_TAIL(__VA_ARGS__) \
|
||||
))
|
||||
|
||||
# define cr_assert_not(...) \
|
||||
CR_EXPAND(cr_assert_impl( \
|
||||
CR_FAIL_ABORT_, \
|
||||
!(CR_VA_HEAD(__VA_ARGS__)), \
|
||||
dummy, \
|
||||
"The expression " CR_STR(!(CR_VA_HEAD(__VA_ARGS__))) " is false.", \
|
||||
CR_VA_TAIL(__VA_ARGS__) \
|
||||
))
|
||||
|
||||
# define cr_expect_not(...) \
|
||||
CR_EXPAND(cr_assert_impl( \
|
||||
CR_FAIL_CONTINUES_, \
|
||||
!(CR_VA_HEAD(__VA_ARGS__)), \
|
||||
dummy, \
|
||||
"The expression " CR_STR(!(CR_VA_HEAD(__VA_ARGS__))) " is false.", \
|
||||
CR_VA_TAIL(__VA_ARGS__) \
|
||||
))
|
||||
|
||||
// Common binary assertions
|
||||
|
||||
# define cr_assert_op_(Fail, Op, Actual, Expected, ...) \
|
||||
CR_EXPAND(cr_assert_impl( \
|
||||
Fail, \
|
||||
(Actual) Op (Expected), \
|
||||
dummy, \
|
||||
"The expression " CR_STR((Actual) Op (Expected)) " is false.", \
|
||||
__VA_ARGS__ \
|
||||
))
|
||||
|
||||
# define cr_assert_op_va_(Fail, Op, ...) \
|
||||
CR_EXPAND(cr_assert_op_( \
|
||||
Fail, \
|
||||
Op, \
|
||||
CR_VA_HEAD(__VA_ARGS__), \
|
||||
CR_VA_HEAD(CR_VA_TAIL(__VA_ARGS__)), \
|
||||
CR_VA_TAIL(CR_VA_TAIL(__VA_ARGS__)) \
|
||||
))
|
||||
|
||||
# define cr_assert_eq(...) CR_EXPAND(cr_assert_op_va_(CR_FAIL_ABORT_, ==, __VA_ARGS__))
|
||||
# define cr_expect_eq(...) CR_EXPAND(cr_assert_op_va_(CR_FAIL_CONTINUES_, ==, __VA_ARGS__))
|
||||
|
||||
# define cr_assert_neq(...) CR_EXPAND(cr_assert_op_va_(CR_FAIL_ABORT_, !=, __VA_ARGS__))
|
||||
# define cr_expect_neq(...) CR_EXPAND(cr_assert_op_va_(CR_FAIL_CONTINUES_, !=, __VA_ARGS__))
|
||||
|
||||
# define cr_assert_lt(...) CR_EXPAND(cr_assert_op_va_(CR_FAIL_ABORT_, <, __VA_ARGS__))
|
||||
# define cr_expect_lt(...) CR_EXPAND(cr_assert_op_va_(CR_FAIL_CONTINUES_, <, __VA_ARGS__))
|
||||
|
||||
# define cr_assert_leq(...) CR_EXPAND(cr_assert_op_va_(CR_FAIL_ABORT_, <=, __VA_ARGS__))
|
||||
# define cr_expect_leq(...) CR_EXPAND(cr_assert_op_va_(CR_FAIL_CONTINUES_, <=, __VA_ARGS__))
|
||||
|
||||
# define cr_assert_gt(...) CR_EXPAND(cr_assert_op_va_(CR_FAIL_ABORT_, >, __VA_ARGS__))
|
||||
# define cr_expect_gt(...) CR_EXPAND(cr_assert_op_va_(CR_FAIL_CONTINUES_, >, __VA_ARGS__))
|
||||
|
||||
# define cr_assert_geq(...) CR_EXPAND(cr_assert_op_va_(CR_FAIL_ABORT_, >=, __VA_ARGS__))
|
||||
# define cr_expect_geq(...) CR_EXPAND(cr_assert_op_va_(CR_FAIL_CONTINUES_, >=, __VA_ARGS__))
|
||||
|
||||
// Common unary assertions
|
||||
|
||||
# define cr_assert_null_op_(Fail, Op, Not, Value, ...) \
|
||||
CR_EXPAND(cr_assert_impl( \
|
||||
Fail, \
|
||||
(Value) Op NULL, \
|
||||
dummy, \
|
||||
CR_STR(Value) " is" Not " null.", \
|
||||
__VA_ARGS__ \
|
||||
))
|
||||
|
||||
# define cr_assert_null_op_va_(Fail, Op, Not, ...) \
|
||||
CR_EXPAND(cr_assert_null_op_( \
|
||||
Fail, \
|
||||
Op, \
|
||||
Not, \
|
||||
CR_VA_HEAD(__VA_ARGS__), \
|
||||
CR_VA_TAIL(__VA_ARGS__) \
|
||||
))
|
||||
|
||||
# define cr_assert_null(...) CR_EXPAND(cr_assert_null_op_va_(CR_FAIL_ABORT_, ==, " not", __VA_ARGS__))
|
||||
# define cr_expect_null(...) CR_EXPAND(cr_assert_null_op_va_(CR_FAIL_CONTINUES_, ==, " not", __VA_ARGS__))
|
||||
|
||||
# define cr_assert_not_null(...) CR_EXPAND(cr_assert_null_op_va_(CR_FAIL_ABORT_, !=, "", __VA_ARGS__))
|
||||
# define cr_expect_not_null(...) CR_EXPAND(cr_assert_null_op_va_(CR_FAIL_CONTINUES_, !=, "", __VA_ARGS__))
|
||||
|
||||
// Floating-point assertions
|
||||
|
||||
# define cr_assert_float_eq_op_(Actual, Expected, Epsilon) \
|
||||
(Expected) - (Actual) <= (Epsilon) && (Actual) - (Expected) <= (Epsilon)
|
||||
|
||||
# define cr_assert_float_neq_op_(Actual, Expected, Epsilon) \
|
||||
(Expected) - (Actual) > (Epsilon) || (Actual) - (Expected) > (Epsilon)
|
||||
|
||||
# define cr_assert_float_op_(Fail, Op, Actual, Expected, Epsilon, ...) \
|
||||
CR_EXPAND(cr_assert_impl( \
|
||||
Fail, \
|
||||
Op(Actual, Expected, Epsilon), \
|
||||
dummy, \
|
||||
"The expression " CR_STR(Op(Actual, Expected, Epsilon)) " is false.", \
|
||||
__VA_ARGS__ \
|
||||
))
|
||||
|
||||
# define cr_assert_float_op_va_(Fail, Op, ...) \
|
||||
CR_EXPAND(cr_assert_float_op_( \
|
||||
Fail, \
|
||||
Op, \
|
||||
CR_VA_HEAD(__VA_ARGS__), \
|
||||
CR_VA_HEAD(CR_VA_TAIL(__VA_ARGS__)), \
|
||||
CR_VA_HEAD(CR_VA_TAIL(CR_VA_TAIL(__VA_ARGS__))), \
|
||||
CR_VA_TAIL(CR_VA_TAIL(CR_VA_TAIL(__VA_ARGS__))) \
|
||||
))
|
||||
|
||||
# define cr_assert_float_eq(...) CR_EXPAND(cr_assert_float_op_va_(CR_FAIL_ABORT_, cr_assert_float_eq_op_, __VA_ARGS__))
|
||||
# define cr_expect_float_eq(...) CR_EXPAND(cr_assert_float_op_va_(CR_FAIL_CONTINUES_, cr_assert_float_eq_op_, __VA_ARGS__))
|
||||
|
||||
# define cr_assert_float_neq(...) CR_EXPAND(cr_assert_float_op_va_(CR_FAIL_ABORT_, cr_assert_float_neq_op_, __VA_ARGS__))
|
||||
# define cr_expect_float_neq(...) CR_EXPAND(cr_assert_float_op_va_(CR_FAIL_CONTINUES_, cr_assert_float_neq_op_, __VA_ARGS__))
|
||||
|
||||
// String assertions
|
||||
|
||||
# define cr_assert_str_op_empty_(Fail, Op, Not, Value, ...) \
|
||||
CR_EXPAND(cr_assert_impl( \
|
||||
Fail, \
|
||||
(Value)[0] Op '\0', \
|
||||
dummy, \
|
||||
CR_STR(Value) " is" Not " empty.", \
|
||||
__VA_ARGS__ \
|
||||
))
|
||||
|
||||
# define cr_assert_str_op_empty_va_(Fail, Op, Not, ...) \
|
||||
CR_EXPAND(cr_assert_str_op_empty_( \
|
||||
Fail, \
|
||||
Op, \
|
||||
Not, \
|
||||
CR_VA_HEAD(__VA_ARGS__), \
|
||||
CR_VA_TAIL(__VA_ARGS__) \
|
||||
))
|
||||
|
||||
# define cr_assert_str_empty(...) CR_EXPAND(cr_assert_str_op_empty_va_(CR_FAIL_ABORT_, ==, " not", __VA_ARGS__))
|
||||
# define cr_expect_str_empty(...) CR_EXPAND(cr_assert_str_op_empty_va_(CR_FAIL_CONTINUES_, ==, " not", __VA_ARGS__))
|
||||
|
||||
# define cr_assert_str_not_empty(...) CR_EXPAND(cr_assert_str_op_empty_va_(CR_FAIL_ABORT_, !=, "", __VA_ARGS__))
|
||||
# define cr_expect_str_not_empty(...) CR_EXPAND(cr_assert_str_op_empty_va_(CR_FAIL_CONTINUES_, !=, "", __VA_ARGS__))
|
||||
|
||||
# define cr_assert_str_op_(Fail, Op, Actual, Expected, ...) \
|
||||
CR_EXPAND(cr_assert_impl( \
|
||||
Fail, \
|
||||
CR_STDN strcmp((Actual), (Expected)) Op 0, \
|
||||
dummy, \
|
||||
"The expression (as strings) " \
|
||||
CR_STR((Actual) Op (Expected)) " is false", \
|
||||
__VA_ARGS__ \
|
||||
))
|
||||
|
||||
# define cr_assert_str_op_va_(Fail, Op, ...) \
|
||||
CR_EXPAND(cr_assert_str_op_( \
|
||||
Fail, \
|
||||
Op, \
|
||||
CR_VA_HEAD(__VA_ARGS__), \
|
||||
CR_VA_HEAD(CR_VA_TAIL(__VA_ARGS__)), \
|
||||
CR_VA_TAIL(CR_VA_TAIL(__VA_ARGS__)) \
|
||||
))
|
||||
|
||||
# define cr_assert_str_eq(...) CR_EXPAND(cr_assert_str_op_va_(CR_FAIL_ABORT_, ==, __VA_ARGS__))
|
||||
# define cr_expect_str_eq(...) CR_EXPAND(cr_assert_str_op_va_(CR_FAIL_CONTINUES_, ==, __VA_ARGS__))
|
||||
|
||||
# define cr_assert_str_neq(...) CR_EXPAND(cr_assert_str_op_va_(CR_FAIL_ABORT_, !=, __VA_ARGS__))
|
||||
# define cr_expect_str_neq(...) CR_EXPAND(cr_assert_str_op_va_(CR_FAIL_CONTINUES_, !=, __VA_ARGS__))
|
||||
|
||||
# define cr_assert_str_lt(...) CR_EXPAND(cr_assert_str_op_va_(CR_FAIL_ABORT_, <, __VA_ARGS__))
|
||||
# define cr_expect_str_lt(...) CR_EXPAND(cr_assert_str_op_va_(CR_FAIL_CONTINUES_, <, __VA_ARGS__))
|
||||
|
||||
# define cr_assert_str_leq(...) CR_EXPAND(cr_assert_str_op_va_(CR_FAIL_ABORT_, <=, __VA_ARGS__))
|
||||
# define cr_expect_str_leq(...) CR_EXPAND(cr_assert_str_op_va_(CR_FAIL_CONTINUES_, <=, __VA_ARGS__))
|
||||
|
||||
# define cr_assert_str_gt(...) CR_EXPAND(cr_assert_str_op_va_(CR_FAIL_ABORT_, >, __VA_ARGS__))
|
||||
# define cr_expect_str_gt(...) CR_EXPAND(cr_assert_str_op_va_(CR_FAIL_CONTINUES_, >, __VA_ARGS__))
|
||||
|
||||
# define cr_assert_str_geq(...) CR_EXPAND(cr_assert_str_op_va_(CR_FAIL_ABORT_, >=, __VA_ARGS__))
|
||||
# define cr_expect_str_geq(...) CR_EXPAND(cr_assert_str_op_va_(CR_FAIL_CONTINUES_, >=, __VA_ARGS__))
|
||||
|
||||
// Array assertions
|
||||
|
||||
# define cr_assert_mem_op_(Fail, Op, Actual, Expected, Size, ...) \
|
||||
CR_EXPAND(cr_assert_impl( \
|
||||
Fail, \
|
||||
CR_STDN memcmp((Actual), (Expected), (Size)) Op 0, \
|
||||
dummy, \
|
||||
"The expression " \
|
||||
CR_STR((Actual)[0 .. Size] Op (Expected)[0 .. Size]) \
|
||||
"is false.", \
|
||||
__VA_ARGS__ \
|
||||
))
|
||||
|
||||
# define cr_assert_mem_op_va_(Fail, Op, ...) \
|
||||
CR_EXPAND(cr_assert_mem_op_( \
|
||||
Fail, \
|
||||
Op, \
|
||||
CR_VA_HEAD(__VA_ARGS__), \
|
||||
CR_VA_HEAD(CR_VA_TAIL(__VA_ARGS__)), \
|
||||
CR_VA_HEAD(CR_VA_TAIL(CR_VA_TAIL(__VA_ARGS__))), \
|
||||
CR_VA_TAIL(CR_VA_TAIL(CR_VA_TAIL(__VA_ARGS__))) \
|
||||
))
|
||||
|
||||
# define cr_assert_arr_eq(...) CR_EXPAND(cr_assert_mem_op_va_(CR_FAIL_ABORT_, ==, __VA_ARGS__))
|
||||
# define cr_expect_arr_eq(...) CR_EXPAND(cr_assert_mem_op_va_(CR_FAIL_CONTINUES_, ==, __VA_ARGS__))
|
||||
|
||||
# define cr_assert_arr_neq(...) CR_EXPAND(cr_assert_mem_op_va_(CR_FAIL_ABORT_, !=, __VA_ARGS__))
|
||||
# define cr_expect_arr_neq(...) CR_EXPAND(cr_assert_mem_op_va_(CR_FAIL_CONTINUES_, !=, __VA_ARGS__))
|
||||
|
||||
// Safe array comparison assertions
|
||||
|
||||
# if defined(__GNUC__) || defined(__cplusplus)
|
||||
|
||||
# ifdef __cplusplus
|
||||
# define CR_ARR_COMPARE_(A, B, Size, Cmp, Result) \
|
||||
int Result = std::lexicographical_compare((A), (A) + Size, (B), (B) + Size, Cmp)
|
||||
# else
|
||||
# define CR_ARR_COMPARE_(A, B, Size, Cmp, Result) \
|
||||
__typeof__(&(A)[0]) first = (A); \
|
||||
__typeof__(&(B)[0]) second = (B); \
|
||||
int Result = 0; \
|
||||
size_t i, size; \
|
||||
for (i = 0, size = (Size); !Result && i < size; ++i) \
|
||||
Result = Cmp(first + i, second + i)
|
||||
# endif
|
||||
|
||||
# define cr_assert_arr_op_cmp_(Fail, Op, Actual, Expected, Size, Cmp, ...) \
|
||||
do { \
|
||||
CR_ARR_COMPARE_(Actual, Expected, Size, Cmp, order); \
|
||||
CR_EXPAND(cr_assert_impl( \
|
||||
Fail, \
|
||||
order Op 0, \
|
||||
dummy, \
|
||||
"The expression " \
|
||||
CR_STR((Actual)[0 .. Size] Op (Expected)[0 .. Size]) \
|
||||
" is false.", \
|
||||
__VA_ARGS__ \
|
||||
)); \
|
||||
} while (0)
|
||||
|
||||
# define cr_assert_arrays_eq_cmp(...) \
|
||||
cr_assert_arrays_eq_cmp_(__VA_ARGS__, CR_SENTINEL)
|
||||
# define cr_expect_arrays_eq_cmp(...) \
|
||||
cr_expect_arrays_eq_cmp_(__VA_ARGS__, CR_SENTINEL)
|
||||
# define cr_assert_arr_op_cmp_va_(Fail, Op, ...) \
|
||||
CR_EXPAND(cr_assert_arr_op_cmp_( \
|
||||
Fail, \
|
||||
Op, \
|
||||
CR_VA_HEAD(__VA_ARGS__), \
|
||||
CR_VA_HEAD(CR_VA_TAIL(__VA_ARGS__)), \
|
||||
CR_VA_HEAD(CR_VA_TAIL(CR_VA_TAIL(__VA_ARGS__))), \
|
||||
CR_VA_HEAD(CR_VA_TAIL(CR_VA_TAIL(CR_VA_TAIL(__VA_ARGS__)))), \
|
||||
CR_VA_TAIL(CR_VA_TAIL(CR_VA_TAIL(CR_VA_TAIL(__VA_ARGS__)))) \
|
||||
))
|
||||
|
||||
# define cr_assert_arrays_neq_cmp_(A, B, Size, Cmp, ...) \
|
||||
do { \
|
||||
CRIT_ARR_COMPARE_(A, B, Size, Cmp, equals); \
|
||||
cr_assert_impl(FATAL, !equals, \
|
||||
__VA_ARGS__); \
|
||||
} while (0)
|
||||
# define cr_assert_arr_eq_cmp(...) CR_EXPAND(cr_assert_arr_op_cmp_va_(CR_FAIL_ABORT_, ==, __VA_ARGS__))
|
||||
# define cr_expect_arr_eq_cmp(...) CR_EXPAND(cr_assert_arr_op_cmp_va_(CR_FAIL_CONTINUES_, ==, __VA_ARGS__))
|
||||
|
||||
# define cr_expect_arrays_neq_cmp_(A, B, Size, Cmp, ...) \
|
||||
do { \
|
||||
CRIT_ARR_COMPARE_(A, B, Size, Cmp, equals); \
|
||||
cr_assert_impl(NORMAL, equals, \
|
||||
__VA_ARGS__); \
|
||||
} while (0)
|
||||
# define cr_assert_arr_neq_cmp(...) CR_EXPAND(cr_assert_arr_op_cmp_va_(CR_FAIL_ABORT_, !=, __VA_ARGS__))
|
||||
# define cr_expect_arr_neq_cmp(...) CR_EXPAND(cr_assert_arr_op_cmp_va_(CR_FAIL_CONTINUES_, !=, __VA_ARGS__))
|
||||
|
||||
# define cr_assert_arrays_neq_cmp(...) \
|
||||
cr_assert_arrays_eq_cmp_(__VA_ARGS__, CR_SENTINEL)
|
||||
# define cr_expect_arrays_neq_cmp(...) \
|
||||
cr_expect_arrays_eq_cmp_(__VA_ARGS__, CR_SENTINEL)
|
||||
# endif /* !__GNUC__ */
|
||||
# define cr_assert_arr_lt_cmp(...) CR_EXPAND(cr_assert_arr_op_cmp_va_(CR_FAIL_ABORT_, <, __VA_ARGS__))
|
||||
# define cr_expect_arr_lt_cmp(...) CR_EXPAND(cr_assert_arr_op_cmp_va_(CR_FAIL_CONTINUES_, <, __VA_ARGS__))
|
||||
|
||||
# define cr_assert_arr_leq_cmp(...) CR_EXPAND(cr_assert_arr_op_cmp_va_(CR_FAIL_ABORT_, <=, __VA_ARGS__))
|
||||
# define cr_expect_arr_leq_cmp(...) CR_EXPAND(cr_assert_arr_op_cmp_va_(CR_FAIL_CONTINUES_, <=, __VA_ARGS__))
|
||||
|
||||
# define cr_assert_arr_gt_cmp(...) CR_EXPAND(cr_assert_arr_op_cmp_va_(CR_FAIL_ABORT_, >, __VA_ARGS__))
|
||||
# define cr_expect_arr_gt_cmp(...) CR_EXPAND(cr_assert_arr_op_cmp_va_(CR_FAIL_CONTINUES_, >, __VA_ARGS__))
|
||||
|
||||
# define cr_assert_arr_geq_cmp(...) CR_EXPAND(cr_assert_arr_op_cmp_va_(CR_FAIL_ABORT_, >=, __VA_ARGS__))
|
||||
# define cr_expect_arr_geq_cmp(...) CR_EXPAND(cr_assert_arr_op_cmp_va_(CR_FAIL_CONTINUES_, >=, __VA_ARGS__))
|
||||
|
||||
# else
|
||||
|
||||
# define CRITERION_GNUC_WARN__(Msg) \
|
||||
_Pragma(#Msg)
|
||||
|
||||
# define CRITERION_GNUC_WARN_(Name) CRITERION_GNUC_WARN__( \
|
||||
message \
|
||||
"The `" #Name "` macro is only available on GNU C compilers." \
|
||||
)
|
||||
|
||||
# define cr_assert_arr_eq_cmp(...) CRITERION_GNUC_WARN_(cr_assert_arr_eq_cmp) CR_NOOP
|
||||
# define cr_expect_arr_eq_cmp(...) CRITERION_GNUC_WARN_(cr_expect_arr_eq_cmp) CR_NOOP
|
||||
|
||||
# define cr_assert_arr_neq_cmp(...) CRITERION_GNUC_WARN_(cr_assert_arr_neq_cmp) CR_NOOP
|
||||
# define cr_expect_arr_neq_cmp(...) CRITERION_GNUC_WARN_(cr_expect_arr_neq_cmp) CR_NOOP
|
||||
|
||||
# define cr_assert_arr_lt_cmp(...) CRITERION_GNUC_WARN_(cr_assert_arr_lt_cmp) CR_NOOP
|
||||
# define cr_expect_arr_lt_cmp(...) CRITERION_GNUC_WARN_(cr_expect_arr_lt_cmp) CR_NOOP
|
||||
|
||||
# define cr_assert_arr_leq_cmp(...) CRITERION_GNUC_WARN_(cr_assert_arr_leq_cmp) CR_NOOP
|
||||
# define cr_expect_arr_leq_cmp(...) CRITERION_GNUC_WARN_(cr_expect_arr_leq_cmp) CR_NOOP
|
||||
|
||||
# define cr_assert_arr_gt_cmp(...) CRITERION_GNUC_WARN_(cr_assert_arr_gt_cmp) CR_NOOP
|
||||
# define cr_expect_arr_gt_cmp(...) CRITERION_GNUC_WARN_(cr_expect_arr_gt_cmp) CR_NOOP
|
||||
|
||||
# define cr_assert_arr_geq_cmp(...) CRITERION_GNUC_WARN_(cr_assert_arr_geq_cmp) CR_NOOP
|
||||
# define cr_expect_arr_geq_cmp(...) CRITERION_GNUC_WARN_(cr_expect_arr_geq_cmp) CR_NOOP
|
||||
|
||||
# endif
|
||||
|
||||
# ifdef __cplusplus
|
||||
# define cr_assert_throw(...) CR_EXPAND(cr_assert_throw_(__VA_ARGS__, CR_SENTINEL))
|
||||
# define cr_assert_throw_(Statement, Exception, ...) \
|
||||
try { \
|
||||
Statement; \
|
||||
} catch (Exception &ex) { \
|
||||
} catch (...) { CR_EXPAND(cr_assert_impl(FATAL, 0, __VA_ARGS__)); }
|
||||
|
||||
# define cr_assert_no_throw(...) CR_EXPAND(cr_assert_not_throw_(__VA_ARGS__, CR_SENTINEL))
|
||||
# define cr_assert_no_throw_(Statement, Exception, ...) \
|
||||
try { \
|
||||
Statement; \
|
||||
} catch (Exception &ex) { CR_EXPAND(cr_assert_impl(FATAL, 0, __VA_ARGS__)); }
|
||||
# define cr_assert_throw_(Fail, Statement, Exception, ...) \
|
||||
try { \
|
||||
Statement; \
|
||||
} catch (Exception const &) { \
|
||||
} catch (...) { CR_EXPAND(cr_fail(Fail, CR_VA_TAIL(__VA_ARGS__))); }
|
||||
|
||||
# define cr_expect_throw(...) CR_EXPAND(cr_expect_throw_(__VA_ARGS__, CR_SENTINEL))
|
||||
# define cr_expect_throw_(Statement, Exception, ...) \
|
||||
try { \
|
||||
Statement; \
|
||||
} catch (Exception &ex) { \
|
||||
} catch (...) { CR_EXPAND(cr_assert_impl(NORMAL, 0, __VA_ARGS__)); }
|
||||
# define cr_assert_throw_va_(...) \
|
||||
CR_EXPAND(cr_assert_throw_( \
|
||||
CR_VA_HEAD(__VA_ARGS__), \
|
||||
CR_VA_HEAD(CR_VA_TAIL(__VA_ARGS__)), \
|
||||
CR_VA_HEAD(CR_VA_TAIL(CR_VA_TAIL(__VA_ARGS__))), \
|
||||
dummy, \
|
||||
CR_VA_TAIL(CR_VA_TAIL(CR_VA_TAIL(__VA_ARGS__))) \
|
||||
))
|
||||
|
||||
# define cr_assert_throw(...) CR_EXPAND(cr_assert_throw_va_(CR_FAIL_ABORT_, __VA_ARGS__))
|
||||
# define cr_expect_throw(...) CR_EXPAND(cr_assert_throw_va_(CR_FAIL_CONTINUES_, __VA_ARGS__))
|
||||
|
||||
# define cr_assert_no_throw_(Fail, Statement, Exception, ...) \
|
||||
try { \
|
||||
Statement; \
|
||||
} catch (Exception const &) { CR_EXPAND(cr_fail(Fail, CR_VA_TAIL(__VA_ARGS__))); }
|
||||
|
||||
# define cr_assert_no_throw_va_(...) \
|
||||
CR_EXPAND(cr_assert_no_throw_( \
|
||||
CR_VA_HEAD(__VA_ARGS__), \
|
||||
CR_VA_HEAD(CR_VA_TAIL(__VA_ARGS__)), \
|
||||
CR_VA_HEAD(CR_VA_TAIL(CR_VA_TAIL(__VA_ARGS__))), \
|
||||
dummy, \
|
||||
CR_VA_TAIL(CR_VA_TAIL(CR_VA_TAIL(__VA_ARGS__))) \
|
||||
))
|
||||
|
||||
# define cr_assert_no_throw(...) CR_EXPAND(cr_assert_no_throw_va_(CR_FAIL_ABORT_, __VA_ARGS__))
|
||||
# define cr_expect_no_throw(...) CR_EXPAND(cr_assert_no_throw_va_(CR_FAIL_CONTINUES_, __VA_ARGS__))
|
||||
|
||||
# define cr_expect_no_throw(...) CR_EXPAND(cr_expect_not_throw_(__VA_ARGS__, CR_SENTINEL))
|
||||
# define cr_expect_no_throw_(Statement, Exception, ...) \
|
||||
try { \
|
||||
Statement; \
|
||||
} catch (Exception &ex) { CR_EXPAND(cr_assert_impl(NORMAL, 0, __VA_ARGS__)); }
|
||||
# endif
|
||||
|
||||
// The section below is here for backward compatibility purposes.
|
||||
// It shall be removed in the text major version of Criterion
|
||||
// It shall be removed in the next major version of Criterion
|
||||
# ifndef CRITERION_NO_COMPAT
|
||||
|
||||
# define CRITERION_ASSERT_DEPRECATED_(Name) CRITERION_ASSERT_DEPRECATED__( \
|
||||
message \
|
||||
"The `" #Name "` macro is deprecated, " \
|
||||
"please use `cr_" #Name "` instead." \
|
||||
# define CRITERION_ASSERT_DEPRECATED_(Name) CRITERION_ASSERT_DEPRECATED__( \
|
||||
message \
|
||||
("The `" #Name "` macro is deprecated, " \
|
||||
"please use `cr_" #Name "` instead.") \
|
||||
)
|
||||
|
||||
# define CRITERION_ASSERT_DEPRECATED_B(Name, Newname) \
|
||||
CRITERION_ASSERT_DEPRECATED__( \
|
||||
message \
|
||||
("The `" #Name "` macro is deprecated, " \
|
||||
"please use `" #Newname "` instead.") \
|
||||
)
|
||||
|
||||
# ifdef _MSC_VER
|
||||
# define CRITERION_ASSERT_DEPRECATED__(Msg) \
|
||||
__pragma(Msg)
|
||||
# else
|
||||
# define CRITERION_ASSERT_DEPRECATED__(Msg) \
|
||||
_Pragma(#Msg)
|
||||
# endif
|
||||
|
||||
# ifndef assert
|
||||
# define assert(...) CRITERION_ASSERT_DEPRECATED_(assert) cr_assert(__VA_ARGS__)
|
||||
|
@ -339,6 +519,22 @@ struct criterion_assert_args {
|
|||
# endif /* !_ASSERT_H */
|
||||
# endif /* !assert */
|
||||
|
||||
// scheduled for removal after 2.0
|
||||
# define cr_abort_test(Message) CRITERION_ASSERT_DEPRECATED_B(cr_abort_test, cr_assert_fail) cr_assert_fail(Message)
|
||||
# define cr_assert_strings_eq(...) CRITERION_ASSERT_DEPRECATED_B(cr_assert_strings_eq, cr_assert_str_eq) cr_assert_str_eq(__VA_ARGS__)
|
||||
# define cr_assert_strings_neq(...) CRITERION_ASSERT_DEPRECATED_B(cr_assert_strings_neq, cr_assert_str_neq) cr_assert_str_neq(__VA_ARGS__)
|
||||
# define cr_assert_strings_lt(...) CRITERION_ASSERT_DEPRECATED_B(cr_assert_strings_lt, cr_assert_str_lt) cr_assert_str_lt(__VA_ARGS__)
|
||||
# define cr_assert_strings_leq(...) CRITERION_ASSERT_DEPRECATED_B(cr_assert_strings_leq, cr_assert_str_leq) cr_assert_str_leq(__VA_ARGS__)
|
||||
# define cr_assert_strings_gt(...) CRITERION_ASSERT_DEPRECATED_B(cr_assert_strings_gt, cr_assert_str_gt) cr_assert_str_gt(__VA_ARGS__)
|
||||
# define cr_assert_strings_geq(...) CRITERION_ASSERT_DEPRECATED_B(cr_assert_strings_geq, cr_assert_str_geq) cr_assert_str_geq(__VA_ARGS__)
|
||||
|
||||
# define cr_assert_arrays_eq(...) CRITERION_ASSERT_DEPRECATED_B(cr_assert_arrays_eq, cr_assert_arr_eq) cr_assert_arr_eq(__VA_ARGS__)
|
||||
# define cr_assert_arrays_neq(...) CRITERION_ASSERT_DEPRECATED_B(cr_assert_arrays_neq, cr_assert_arr_neq) cr_assert_arr_neq(__VA_ARGS__)
|
||||
|
||||
# define cr_assert_arrays_eq_cmp(...) CRITERION_ASSERT_DEPRECATED_B(cr_assert_arrays_eq_cmp, cr_assert_arr_eq_cmp) cr_assert_arr_eq_cmp(__VA_ARGS__)
|
||||
# define cr_assert_arrays_neq_cmp(...) CRITERION_ASSERT_DEPRECATED_B(cr_assert_arrays_neq_cmp, cr_assert_arr_neq_cmp) cr_assert_arr_neq_cmp(__VA_ARGS__)
|
||||
|
||||
// scheduled for removal at 2.0
|
||||
# define abort_test(Message) CRITERION_ASSERT_DEPRECATED_(abort_test) cr_abort_test(Message)
|
||||
# define expect(...) CRITERION_ASSERT_DEPRECATED_(expect) cr_expect(__VA_ARGS__)
|
||||
# define assert_not(...) CRITERION_ASSERT_DEPRECATED_(assert_not) cr_assert_not(__VA_ARGS__)
|
||||
|
|
|
@ -24,8 +24,6 @@
|
|||
#ifndef CRITERION_COMMON_H_
|
||||
# define CRITERION_COMMON_H_
|
||||
|
||||
# define CR_EXPAND(x) x
|
||||
|
||||
# if defined(_MSC_VER)
|
||||
# if _MSC_VER < 1900
|
||||
# error \
|
||||
|
@ -101,12 +99,15 @@
|
|||
# ifdef __GNUC__
|
||||
# define UNUSED CR_ATTRIBUTE(unused)
|
||||
# define NORETURN CR_ATTRIBUTE(noreturn)
|
||||
# define CR_INLINE CR_ATTRIBUTE(always_inline) inline
|
||||
# elif CR_IS_MSVC
|
||||
# define UNUSED
|
||||
# define NORETURN __declspec(noreturn)
|
||||
# define CR_INLINE __forceinline
|
||||
# else
|
||||
# define UNUSED
|
||||
# define NORETURN
|
||||
# define CR_INLINE inline
|
||||
# endif
|
||||
|
||||
# ifdef _WIN32
|
||||
|
|
|
@ -26,17 +26,13 @@
|
|||
|
||||
# ifdef __cplusplus
|
||||
# include <cstddef>
|
||||
# include <cstdio>
|
||||
# else
|
||||
# include <stddef.h>
|
||||
# include <stdio.h>
|
||||
# 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
|
||||
|
|
72
include/criterion/preprocess.h
Normal file
72
include/criterion/preprocess.h
Normal file
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2015 Franklin "Snaipe" Mathieu <http://snai.pe/>
|
||||
*
|
||||
* 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_PREPROCESS_H_
|
||||
# define CRITERION_PREPROCESS_H_
|
||||
|
||||
# define CR_NOOP do {} while(0)
|
||||
|
||||
# ifdef __cplusplus
|
||||
# define CR_NOTHROW throw()
|
||||
# else
|
||||
# define CR_NOTHROW
|
||||
# endif
|
||||
|
||||
# define CR_EXPAND(x) x
|
||||
|
||||
# define CR_STR(x) CR_EXPAND(CR_STR_(x))
|
||||
# define CR_STR_(x) #x
|
||||
|
||||
# define CR_VA_TAIL(...) CR_EXPAND(CR_VA_TAIL_HELPER(CR_VA_TAIL_SELECT(__VA_ARGS__), __VA_ARGS__))
|
||||
|
||||
# define CR_VA_TAIL_HELPER(N, ...) CR_EXPAND(CR_VA_TAIL_HELPER_(N, __VA_ARGS__))
|
||||
# define CR_VA_TAIL_HELPER_(N, ...) CR_EXPAND(CR_VA_TAIL_HELPER_##N(__VA_ARGS__))
|
||||
# define CR_VA_TAIL_HELPER_1(Head)
|
||||
# define CR_VA_TAIL_HELPER_2(Head, ...) __VA_ARGS__
|
||||
|
||||
# define CR_VA_HEAD(...) CR_EXPAND(CR_VA_HEAD_HELPER(CR_VA_TAIL_SELECT(__VA_ARGS__), __VA_ARGS__))
|
||||
|
||||
# define CR_VA_HEAD_HELPER(N, ...) CR_EXPAND(CR_VA_HEAD_HELPER_(N, __VA_ARGS__))
|
||||
# define CR_VA_HEAD_HELPER_(N, ...) CR_EXPAND(CR_VA_HEAD_HELPER_##N(__VA_ARGS__))
|
||||
# define CR_VA_HEAD_HELPER_1(Head) Head
|
||||
# define CR_VA_HEAD_HELPER_2(Head, ...) Head
|
||||
|
||||
# define CR_VA_TAIL_SELECT(...) CR_EXPAND(CR_VA_TAIL_SELECT64(__VA_ARGS__, \
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, \
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, \
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, \
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, \
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, \
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, \
|
||||
2, 2, 1, _))
|
||||
|
||||
# define CR_VA_TAIL_SELECT64( \
|
||||
_01, _02, _03, _04, _05, _06, _07, _08, _09, _10, \
|
||||
_11, _12, _13, _14, _15, _16, _17, _18, _19, _20, \
|
||||
_21, _22, _23, _24, _25, _26, _27, _28, _29, _30, \
|
||||
_31, _32, _33, _34, _35, _36, _37, _38, _39, _40, \
|
||||
_41, _42, _43, _44, _45, _46, _47, _48, _49, _50, \
|
||||
_51, _52, _53, _54, _55, _56, _57, _58, _59, _60, \
|
||||
_61, _62, _63, X, ...) X
|
||||
|
||||
#endif /* !CRITERION_PREPROCESS_H_ */
|
|
@ -27,8 +27,6 @@
|
|||
# include "types.h"
|
||||
|
||||
struct criterion_assert_stats {
|
||||
int kind;
|
||||
const char *condition;
|
||||
const char *message;
|
||||
bool passed;
|
||||
unsigned line;
|
||||
|
|
|
@ -46,23 +46,27 @@ if (HAVE_PCRE)
|
|||
set(SCRIPTS ${SCRIPTS} pattern)
|
||||
endif ()
|
||||
|
||||
foreach(sample ${SAMPLES})
|
||||
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}.bin)
|
||||
set_property(TEST ${sample}_compare PROPERTY
|
||||
ENVIRONMENT "LC_ALL=en_US.utf8"
|
||||
macro(add_samples DIR_ SAMPLES_)
|
||||
foreach(sample ${SAMPLES_})
|
||||
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"
|
||||
ENVIRONMENT "CRITERION_SHORT_FILENAME=1"
|
||||
)
|
||||
endif ()
|
||||
endforeach()
|
||||
|
||||
if (NOT MSVC) # we disable the scripted tests when building with MSVC
|
||||
add_test(${sample}_compare sh ${DIR_}/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"
|
||||
ENVIRONMENT "CRITERION_SHORT_FILENAME=1"
|
||||
)
|
||||
endif ()
|
||||
endforeach()
|
||||
endmacro()
|
||||
|
||||
add_samples("${CMAKE_CURRENT_LIST_DIR}/tests" "${SAMPLES}")
|
||||
|
||||
if (NOT MSVC) # we disable the scripted tests when building with MSVC
|
||||
|
||||
|
@ -81,3 +85,5 @@ foreach(script ${SCRIPTS})
|
|||
endforeach()
|
||||
|
||||
endif()
|
||||
|
||||
add_subdirectory(tests)
|
||||
|
|
|
@ -6,29 +6,32 @@ Test(asserts, base) {
|
|||
|
||||
cr_assert(true, "Assertions may take failure messages");
|
||||
|
||||
cr_assert(true, "Or even %d format string %s", 1, "with parameters");
|
||||
|
||||
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
|
||||
cr_expect_fail("You can fail an assertion with a message from anywhere");
|
||||
cr_assert_fail(); // or without a message
|
||||
}
|
||||
|
||||
Test(asserts, string) {
|
||||
cr_assert_strings_eq("hello", "hello");
|
||||
cr_assert_strings_neq("hello", "olleh");
|
||||
cr_assert_str_empty("");
|
||||
cr_assert_str_not_empty("foo");
|
||||
|
||||
cr_assert_strings_gt("hello", "hell");
|
||||
cr_assert_strings_geq("hello", "hell");
|
||||
cr_assert_strings_geq("hello", "hello");
|
||||
cr_assert_str_eq("hello", "hello");
|
||||
cr_assert_str_neq("hello", "olleh");
|
||||
|
||||
cr_assert_strings_lt("hell", "hello");
|
||||
cr_assert_strings_leq("hell", "hello");
|
||||
cr_assert_strings_leq("hello", "hello");
|
||||
cr_assert_str_gt("hello", "hell");
|
||||
cr_assert_str_geq("hello", "hell");
|
||||
cr_assert_str_geq("hello", "hello");
|
||||
|
||||
cr_assert_str_lt("hell", "hello");
|
||||
cr_assert_str_leq("hell", "hello");
|
||||
cr_assert_str_leq("hello", "hello");
|
||||
}
|
||||
|
||||
Test(asserts, native) {
|
||||
|
@ -62,8 +65,8 @@ 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);
|
||||
cr_assert_arr_eq(arr1, arr1, 4);
|
||||
cr_assert_arr_neq(arr1, arr2, 4);
|
||||
|
||||
#ifdef __GNUC__
|
||||
struct dummy_struct s1[] = {{4, 2}, {2, 4}};
|
||||
|
@ -74,7 +77,7 @@ Test(asserts, array) {
|
|||
s2[1].a = 2;
|
||||
s2[1].b = 4;
|
||||
|
||||
// cr_assert_arrays_eq(s1, s2, 2); not guaranteed to work on structs.
|
||||
cr_assert_arrays_eq_cmp(s1, s2, 2, eq_dummy);
|
||||
// cr_assert_arr_eq(s1, s2, 2); not guaranteed to work on structs.
|
||||
cr_assert_arr_eq_cmp(s1, s2, 2, eq_dummy);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
[[0;34m----[0m] [0;1masserts.c[0m:[0;31m9[0m: Assertion failed: assert is fatal, expect isn't
|
||||
[[0;34m----[0m] [0;1masserts.c[0m:[0;31m10[0m: Assertion failed: This assert runs
|
||||
[[0;34m----[0m] [0;1masserts.c[0m:[0;31m11[0m: Assertion failed: assert is fatal, expect isn't
|
||||
[[0;34m----[0m] [0;1masserts.c[0m:[0;31m12[0m: Assertion failed: This assert runs
|
||||
[[0;31mFAIL[0m] asserts::base: (0.00s)
|
||||
[[0;34m----[0m] [0;1masserts.c[0m:[0;31m18[0m: Assertion failed: The conditions for this test were not met.
|
||||
[[0;34m----[0m] [0;1masserts.c[0m:[0;31m17[0m: Assertion failed: You can fail an assertion with a message from anywhere
|
||||
[[0;34m----[0m] [0;1masserts.c[0m:[0;31m18[0m: Assertion failed: The conditions for this assertion were not met.
|
||||
[[0;31mFAIL[0m] asserts::old_school: (0.00s)
|
||||
[[0;34m====[0m] [0;1mSynthesis: Tested: [0;34m6[0;1m | Passing: [0;32m4[0;1m | Failing: [0;31m2[0;1m | Crashing: [0;31m0[0;1m [0m
|
||||
|
|
|
@ -8,29 +8,32 @@ Test(asserts, base) {
|
|||
|
||||
cr_assert(true, "Assertions may take failure messages");
|
||||
|
||||
cr_assert(true, "Or even %d format string %s", 1, "with parameters");
|
||||
|
||||
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
|
||||
cr_expect_fail("You can fail an assertion with a message from anywhere");
|
||||
cr_assert_fail(); // or without a message
|
||||
}
|
||||
|
||||
Test(asserts, string) {
|
||||
cr_assert_strings_eq("hello", "hello");
|
||||
cr_assert_strings_neq("hello", "olleh");
|
||||
cr_assert_str_empty("");
|
||||
cr_assert_str_not_empty("foo");
|
||||
|
||||
cr_assert_strings_gt("hello", "hell");
|
||||
cr_assert_strings_geq("hello", "hell");
|
||||
cr_assert_strings_geq("hello", "hello");
|
||||
cr_assert_str_eq("hello", "hello");
|
||||
cr_assert_str_neq("hello", "olleh");
|
||||
|
||||
cr_assert_strings_lt("hell", "hello");
|
||||
cr_assert_strings_leq("hell", "hello");
|
||||
cr_assert_strings_leq("hello", "hello");
|
||||
cr_assert_str_gt("hello", "hell");
|
||||
cr_assert_str_geq("hello", "hell");
|
||||
cr_assert_str_geq("hello", "hello");
|
||||
|
||||
cr_assert_str_lt("hell", "hello");
|
||||
cr_assert_str_leq("hell", "hello");
|
||||
cr_assert_str_leq("hello", "hello");
|
||||
}
|
||||
|
||||
Test(asserts, native) {
|
||||
|
@ -64,8 +67,8 @@ 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);
|
||||
cr_assert_arr_eq(arr1, arr1, 4);
|
||||
cr_assert_arr_neq(arr1, arr2, 4);
|
||||
|
||||
#ifdef __GNUC__
|
||||
struct dummy_struct s1[] = {{4, 2}, {2, 4}};
|
||||
|
@ -76,8 +79,8 @@ Test(asserts, array) {
|
|||
s2[1].a = 2;
|
||||
s2[1].b = 4;
|
||||
|
||||
// cr_assert_arrays_eq(s1, s2, 2); not guaranteed to work on structs.
|
||||
cr_assert_arrays_eq_cmp(s1, s2, 2, eq_dummy);
|
||||
// cr_assert_arrays_eq(&s1, &s2, 2); not guaranteed to work on structs.
|
||||
cr_assert_arr_eq_cmp(&s1, &s2, 2, eq_dummy);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
[[0;34m----[0m] [0;1masserts.cc[0m:[0;31m11[0m: Assertion failed: assert is fatal, expect isn't
|
||||
[[0;34m----[0m] [0;1masserts.cc[0m:[0;31m12[0m: Assertion failed: This assert runs
|
||||
[[0;34m----[0m] [0;1masserts.cc[0m:[0;31m83[0m: Assertion failed: The expression (&s1)[0 .. 2] == (&s2)[0 .. 2] is false.
|
||||
[[0;31mFAIL[0m] asserts::array: (0.00s)
|
||||
[[0;34m----[0m] [0;1masserts.cc[0m:[0;31m13[0m: Assertion failed: assert is fatal, expect isn't
|
||||
[[0;34m----[0m] [0;1masserts.cc[0m:[0;31m14[0m: Assertion failed: This assert runs
|
||||
[[0;31mFAIL[0m] asserts::base: (0.00s)
|
||||
[[0;34m----[0m] [0;1masserts.cc[0m:[0;31m86[0m: Assertion failed: 0
|
||||
[[0;34m----[0m] [0;1masserts.cc[0m:[0;31m89[0m: Assertion failed: The conditions for this assertion were not met.
|
||||
[[0;31mFAIL[0m] asserts::exception: (0.00s)
|
||||
[[0;34m----[0m] [0;1masserts.cc[0m:[0;31m20[0m: Assertion failed: The conditions for this test were not met.
|
||||
[[0;34m----[0m] [0;1masserts.cc[0m:[0;31m19[0m: Assertion failed: You can fail an assertion with a message from anywhere
|
||||
[[0;34m----[0m] [0;1masserts.cc[0m:[0;31m20[0m: Assertion failed: The conditions for this assertion were not met.
|
||||
[[0;31mFAIL[0m] asserts::old_school: (0.00s)
|
||||
[[0;34m====[0m] [0;1mSynthesis: Tested: [0;34m7[0;1m | Passing: [0;32m4[0;1m | Failing: [0;31m3[0;1m | Crashing: [0;31m0[0;1m [0m
|
||||
[[0;34m====[0m] [0;1mSynthesis: Tested: [0;34m7[0;1m | Passing: [0;32m3[0;1m | Failing: [0;31m4[0;1m | Crashing: [0;31m0[0;1m [0m
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
[[0;34m----[0m] [0;1mdescription.c[0m:[0;31m4[0m: Assertion failed: 0
|
||||
[[0;34m----[0m] [0;1mdescription.c[0m:[0;31m4[0m: Assertion failed: The expression 0 is false.
|
||||
[[0;31mFAIL[0m] misc::failing: (0.00s)
|
||||
[[0;34m====[0m] [0;1mSynthesis: Tested: [0;34m1[0;1m | Passing: [0;32m0[0;1m | Failing: [0;31m1[0;1m | Crashing: [0;31m0[0;1m [0m
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
[[0;34m----[0m] [0;1mdescription.cc[0m:[0;31m4[0m: Assertion failed: 0
|
||||
[[0;34m----[0m] [0;1mdescription.cc[0m:[0;31m4[0m: Assertion failed: The expression 0 is false.
|
||||
[[0;31mFAIL[0m] misc::failing: (0.00s)
|
||||
[[0;34m====[0m] [0;1mSynthesis: Tested: [0;34m1[0;1m | Passing: [0;32m0[0;1m | Failing: [0;31m1[0;1m | Crashing: [0;31m0[0;1m [0m
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
[[0;34m----[0m] [0;1mreport.c[0m:[0;31m5[0m: Assertion failed: 0
|
||||
[[0;34m----[0m] [0;1mreport.c[0m:[0;31m5[0m: Assertion failed: The expression 0 is false.
|
||||
[[0;31mFAIL[0m] sample::test: (0.00s)
|
||||
[[0;34m====[0m] [0;1mSynthesis: Tested: [0;34m1[0;1m | Passing: [0;32m0[0;1m | Failing: [0;31m1[0;1m | Crashing: [0;31m0[0;1m [0m
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
[[0;34m----[0m] [0;1mreport.cc[0m:[0;31m5[0m: Assertion failed: 0
|
||||
[[0;34m----[0m] [0;1mreport.cc[0m:[0;31m5[0m: Assertion failed: The expression 0 is false.
|
||||
[[0;31mFAIL[0m] sample::test: (0.00s)
|
||||
[[0;34m====[0m] [0;1mSynthesis: Tested: [0;34m1[0;1m | Passing: [0;32m0[0;1m | Failing: [0;31m1[0;1m | Crashing: [0;31m0[0;1m [0m
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
[[0;34m----[0m] [0;1msimple.c[0m:[0;31m4[0m: Assertion failed: 0
|
||||
[[0;34m----[0m] [0;1msimple.c[0m:[0;31m4[0m: Assertion failed: The expression 0 is false.
|
||||
[[0;31mFAIL[0m] misc::failing: (0.00s)
|
||||
[[0;34m====[0m] [0;1mSynthesis: Tested: [0;34m2[0;1m | Passing: [0;32m1[0;1m | Failing: [0;31m1[0;1m | Crashing: [0;31m0[0;1m [0m
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
[[0;34m----[0m] [0;1msimple.cc[0m:[0;31m4[0m: Assertion failed: 0
|
||||
[[0;34m----[0m] [0;1msimple.cc[0m:[0;31m4[0m: Assertion failed: The expression 0 is false.
|
||||
[[0;31mFAIL[0m] misc::failing: (0.00s)
|
||||
[[0;34m====[0m] [0;1mSynthesis: Tested: [0;34m2[0;1m | Passing: [0;32m1[0;1m | Failing: [0;31m1[0;1m | Crashing: [0;31m0[0;1m [0m
|
||||
|
|
5
samples/tests/CMakeLists.txt
Normal file
5
samples/tests/CMakeLists.txt
Normal file
|
@ -0,0 +1,5 @@
|
|||
set(SAMPLES
|
||||
failmessages.c
|
||||
)
|
||||
|
||||
add_samples("${CMAKE_CURRENT_LIST_DIR}" "${SAMPLES}")
|
49
samples/tests/failmessages.c
Normal file
49
samples/tests/failmessages.c
Normal file
|
@ -0,0 +1,49 @@
|
|||
#include <criterion/criterion.h>
|
||||
|
||||
Test(messages, default) {
|
||||
cr_expect(0);
|
||||
cr_expect_eq(0, 1);
|
||||
cr_expect_neq(1, 1);
|
||||
cr_expect_lt(2, 1);
|
||||
cr_expect_leq(2, 1);
|
||||
cr_expect_gt(1, 2);
|
||||
cr_expect_geq(1, 2);
|
||||
cr_expect_null("");
|
||||
cr_expect_not_null(NULL);
|
||||
|
||||
cr_expect_float_eq(1, 2, 0.1);
|
||||
cr_expect_float_neq(2, 2, 0.1);
|
||||
|
||||
cr_expect_str_empty("foo");
|
||||
cr_expect_str_not_empty("");
|
||||
cr_expect_str_eq("abc", "abd");
|
||||
cr_expect_str_neq("abc", "abc");
|
||||
cr_expect_str_lt("abc", "aba");
|
||||
cr_expect_str_leq("abc", "aba");
|
||||
cr_expect_str_gt("abc", "abd");
|
||||
cr_expect_str_geq("abc", "abd");
|
||||
}
|
||||
|
||||
Test(messages, user) {
|
||||
cr_expect(0, "foo %s", "bar");
|
||||
cr_expect_eq(0, 1, "foo %s", "bar");
|
||||
cr_expect_neq(1, 1, "foo %s", "bar");
|
||||
cr_expect_lt(2, 1, "foo %s", "bar");
|
||||
cr_expect_leq(2, 1, "foo %s", "bar");
|
||||
cr_expect_gt(1, 2, "foo %s", "bar");
|
||||
cr_expect_geq(1, 2, "foo %s", "bar");
|
||||
cr_expect_null("", "foo %s", "bar");
|
||||
cr_expect_not_null(NULL, "foo %s", "bar");
|
||||
|
||||
cr_expect_float_eq(1, 2, 0.1, "foo %s", "bar");
|
||||
cr_expect_float_neq(2, 2, 0.1, "foo %s", "bar");
|
||||
|
||||
cr_expect_str_empty("foo", "foo %s", "bar");
|
||||
cr_expect_str_not_empty("", "foo %s", "bar");
|
||||
cr_expect_str_eq("abc", "abd", "foo %s", "bar");
|
||||
cr_expect_str_neq("abc", "abc", "foo %s", "bar");
|
||||
cr_expect_str_lt("abc", "aba", "foo %s", "bar");
|
||||
cr_expect_str_leq("abc", "aba", "foo %s", "bar");
|
||||
cr_expect_str_gt("abc", "abd", "foo %s", "bar");
|
||||
cr_expect_str_geq("abc", "abd", "foo %s", "bar");
|
||||
}
|
41
samples/tests/failmessages.c.bin.err.expected
Normal file
41
samples/tests/failmessages.c.bin.err.expected
Normal file
|
@ -0,0 +1,41 @@
|
|||
[[0;34m----[0m] [0;1mfailmessages.c[0m:[0;31m4[0m: Assertion failed: The expression 0 is false.
|
||||
[[0;34m----[0m] [0;1mfailmessages.c[0m:[0;31m5[0m: Assertion failed: The expression (0) == (1) is false.
|
||||
[[0;34m----[0m] [0;1mfailmessages.c[0m:[0;31m6[0m: Assertion failed: The expression (1) != (1) is false.
|
||||
[[0;34m----[0m] [0;1mfailmessages.c[0m:[0;31m7[0m: Assertion failed: The expression (2) < (1) is false.
|
||||
[[0;34m----[0m] [0;1mfailmessages.c[0m:[0;31m8[0m: Assertion failed: The expression (2) <= (1) is false.
|
||||
[[0;34m----[0m] [0;1mfailmessages.c[0m:[0;31m9[0m: Assertion failed: The expression (1) > (2) is false.
|
||||
[[0;34m----[0m] [0;1mfailmessages.c[0m:[0;31m10[0m: Assertion failed: The expression (1) >= (2) is false.
|
||||
[[0;34m----[0m] [0;1mfailmessages.c[0m:[0;31m11[0m: Assertion failed: "" is not null.
|
||||
[[0;34m----[0m] [0;1mfailmessages.c[0m:[0;31m12[0m: Assertion failed: ((void *)0) is null.
|
||||
[[0;34m----[0m] [0;1mfailmessages.c[0m:[0;31m14[0m: Assertion failed: The expression (2) - (1) <= (0.1) && (1) - (2) <= (0.1) is false.
|
||||
[[0;34m----[0m] [0;1mfailmessages.c[0m:[0;31m15[0m: Assertion failed: The expression (2) - (2) > (0.1) || (2) - (2) > (0.1) is false.
|
||||
[[0;34m----[0m] [0;1mfailmessages.c[0m:[0;31m17[0m: Assertion failed: "foo" is not empty.
|
||||
[[0;34m----[0m] [0;1mfailmessages.c[0m:[0;31m18[0m: Assertion failed: "" is empty.
|
||||
[[0;34m----[0m] [0;1mfailmessages.c[0m:[0;31m19[0m: Assertion failed: The expression (as strings) ("abc") == ("abd") is false
|
||||
[[0;34m----[0m] [0;1mfailmessages.c[0m:[0;31m20[0m: Assertion failed: The expression (as strings) ("abc") != ("abc") is false
|
||||
[[0;34m----[0m] [0;1mfailmessages.c[0m:[0;31m21[0m: Assertion failed: The expression (as strings) ("abc") < ("aba") is false
|
||||
[[0;34m----[0m] [0;1mfailmessages.c[0m:[0;31m22[0m: Assertion failed: The expression (as strings) ("abc") <= ("aba") is false
|
||||
[[0;34m----[0m] [0;1mfailmessages.c[0m:[0;31m23[0m: Assertion failed: The expression (as strings) ("abc") > ("abd") is false
|
||||
[[0;34m----[0m] [0;1mfailmessages.c[0m:[0;31m24[0m: Assertion failed: The expression (as strings) ("abc") >= ("abd") is false
|
||||
[[0;31mFAIL[0m] messages::default: (0.00s)
|
||||
[[0;34m----[0m] [0;1mfailmessages.c[0m:[0;31m28[0m: Assertion failed: foo bar
|
||||
[[0;34m----[0m] [0;1mfailmessages.c[0m:[0;31m29[0m: Assertion failed: foo bar
|
||||
[[0;34m----[0m] [0;1mfailmessages.c[0m:[0;31m30[0m: Assertion failed: foo bar
|
||||
[[0;34m----[0m] [0;1mfailmessages.c[0m:[0;31m31[0m: Assertion failed: foo bar
|
||||
[[0;34m----[0m] [0;1mfailmessages.c[0m:[0;31m32[0m: Assertion failed: foo bar
|
||||
[[0;34m----[0m] [0;1mfailmessages.c[0m:[0;31m33[0m: Assertion failed: foo bar
|
||||
[[0;34m----[0m] [0;1mfailmessages.c[0m:[0;31m34[0m: Assertion failed: foo bar
|
||||
[[0;34m----[0m] [0;1mfailmessages.c[0m:[0;31m35[0m: Assertion failed: foo bar
|
||||
[[0;34m----[0m] [0;1mfailmessages.c[0m:[0;31m36[0m: Assertion failed: foo bar
|
||||
[[0;34m----[0m] [0;1mfailmessages.c[0m:[0;31m38[0m: Assertion failed: foo bar
|
||||
[[0;34m----[0m] [0;1mfailmessages.c[0m:[0;31m39[0m: Assertion failed: foo bar
|
||||
[[0;34m----[0m] [0;1mfailmessages.c[0m:[0;31m41[0m: Assertion failed: foo bar
|
||||
[[0;34m----[0m] [0;1mfailmessages.c[0m:[0;31m42[0m: Assertion failed: foo bar
|
||||
[[0;34m----[0m] [0;1mfailmessages.c[0m:[0;31m43[0m: Assertion failed: foo bar
|
||||
[[0;34m----[0m] [0;1mfailmessages.c[0m:[0;31m44[0m: Assertion failed: foo bar
|
||||
[[0;34m----[0m] [0;1mfailmessages.c[0m:[0;31m45[0m: Assertion failed: foo bar
|
||||
[[0;34m----[0m] [0;1mfailmessages.c[0m:[0;31m46[0m: Assertion failed: foo bar
|
||||
[[0;34m----[0m] [0;1mfailmessages.c[0m:[0;31m47[0m: Assertion failed: foo bar
|
||||
[[0;34m----[0m] [0;1mfailmessages.c[0m:[0;31m48[0m: Assertion failed: foo bar
|
||||
[[0;31mFAIL[0m] messages::user: (0.00s)
|
||||
[[0;34m====[0m] [0;1mSynthesis: Tested: [0;34m2[0;1m | Passing: [0;32m0[0;1m | Failing: [0;31m2[0;1m | Crashing: [0;31m0[0;1m [0m
|
0
samples/tests/failmessages.c.bin.out.expected
Normal file
0
samples/tests/failmessages.c.bin.out.expected
Normal file
|
@ -95,12 +95,12 @@ Theory((char c, bool b, short s, int i, long l, long long ll, float f, double d,
|
|||
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_str_eq(str, "test");
|
||||
cr_assert_str_eq(cstr, "other test");
|
||||
cr_assert_eq(obj->foo, 42);
|
||||
|
||||
// abort to see the formatted string of all parameters
|
||||
cr_abort_test(NULL);
|
||||
cr_assert_fail();
|
||||
}
|
||||
|
||||
// Manually generate datapoints
|
||||
|
@ -117,5 +117,5 @@ static void generate_datapoints(void) {
|
|||
|
||||
Theory((int i), theory, gen, .init = generate_datapoints) {
|
||||
(void) i;
|
||||
cr_abort_test(NULL); // we fail to display the parameter
|
||||
cr_assert_fail(); // we fail to display the parameter
|
||||
}
|
||||
|
|
|
@ -103,12 +103,12 @@ Theory((char c, bool b, short s, int i, long l, long long ll, float f, double d,
|
|||
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_str_eq(str, "test");
|
||||
cr_assert_str_eq(cstr, "other test");
|
||||
cr_assert_eq(obj->foo, 42);
|
||||
|
||||
// abort to see the formatted string of all parameters
|
||||
cr_abort_test(NULL);
|
||||
cr_assert_fail();
|
||||
}
|
||||
|
||||
// Manually generate datapoints
|
||||
|
@ -125,5 +125,5 @@ static void generate_datapoints(void) {
|
|||
|
||||
Theory((int i), theory, gen, .init = generate_datapoints) {
|
||||
(void) i;
|
||||
cr_abort_test(NULL); // we fail to display the parameter
|
||||
cr_assert_fail(); // we fail to display the parameter
|
||||
}
|
||||
|
|
63
src/asprintf.c
Normal file
63
src/asprintf.c
Normal file
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright © 2015 Franklin "Snaipe" Mathieu <http://snai.pe/>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "criterion/asprintf-compat.h"
|
||||
|
||||
int cr_asprintf(char **strp, const char *fmt, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
int res = cr_vasprintf(strp, fmt, ap);
|
||||
va_end(ap);
|
||||
return res;
|
||||
}
|
||||
|
||||
int cr_vasprintf(char **strp, const char *fmt, va_list ap) {
|
||||
va_list vl;
|
||||
va_copy(vl, ap);
|
||||
|
||||
int size = vsnprintf(0, 0, fmt, vl);
|
||||
int res = -1;
|
||||
|
||||
if (size < 0 || size >= INT_MAX) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
char *str = malloc(size + 1);
|
||||
if (str) {
|
||||
int res2 = vsnprintf(str, size + 1, fmt, ap);
|
||||
if (res2 < 0 || res2 > size) {
|
||||
free(str);
|
||||
goto cleanup;
|
||||
}
|
||||
*strp = str;
|
||||
res = res2;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
va_end(vl);
|
||||
return res;
|
||||
}
|
46
src/event.c
46
src/event.c
|
@ -37,6 +37,12 @@ void destroy_event(void *ptr, UNUSED void *meta) {
|
|||
free(ev->data);
|
||||
}
|
||||
|
||||
void destroy_assert_event(void *ptr, UNUSED void *meta) {
|
||||
struct event *ev = ptr;
|
||||
free((void*) ((struct criterion_assert_stats *) ev->data)->message);
|
||||
free(ev->data);
|
||||
}
|
||||
|
||||
struct event *read_event(FILE *f) {
|
||||
unsigned kind;
|
||||
if (fread(&kind, sizeof (unsigned), 1, f) == 0)
|
||||
|
@ -45,33 +51,45 @@ struct event *read_event(FILE *f) {
|
|||
switch (kind) {
|
||||
case ASSERT: {
|
||||
const size_t assert_size = sizeof (struct criterion_assert_stats);
|
||||
unsigned char *buf = malloc(assert_size);
|
||||
if (fread(buf, assert_size, 1, f) == 0) {
|
||||
free(buf);
|
||||
return NULL;
|
||||
}
|
||||
struct criterion_assert_stats *buf = NULL;
|
||||
char *msg = NULL;
|
||||
|
||||
buf = malloc(assert_size);
|
||||
if (fread(buf, assert_size, 1, f) == 0)
|
||||
goto fail_assert;
|
||||
|
||||
size_t len = 0;
|
||||
if (fread(&len, sizeof (size_t), 1, f) == 0)
|
||||
goto fail_assert;
|
||||
|
||||
msg = malloc(len);
|
||||
if (fread(msg, len, 1, f) == 0)
|
||||
goto fail_assert;
|
||||
|
||||
buf->message = msg;
|
||||
|
||||
struct event *ev = smalloc(
|
||||
.size = sizeof (struct event),
|
||||
.dtor = destroy_event
|
||||
.dtor = destroy_assert_event
|
||||
);
|
||||
*ev = (struct event) { .kind = kind, .data = buf };
|
||||
return ev;
|
||||
|
||||
fail_assert:
|
||||
free(buf);
|
||||
free(msg);
|
||||
return NULL;
|
||||
}
|
||||
case THEORY_FAIL: {
|
||||
size_t *len = malloc(sizeof (size_t));
|
||||
if (fread(len, sizeof (size_t), 1, f) == 0) {
|
||||
free(len);
|
||||
size_t len = 0;
|
||||
if (fread(&len, sizeof (size_t), 1, f) == 0)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *buf = malloc(*len);
|
||||
if (fread(buf, *len, 1, f) == 0) {
|
||||
free(len);
|
||||
char *buf = malloc(len);
|
||||
if (fread(buf, len, 1, f) == 0) {
|
||||
free(buf);
|
||||
return NULL;
|
||||
}
|
||||
free(len);
|
||||
|
||||
struct event *ev = smalloc(
|
||||
.size = sizeof (struct event),
|
||||
|
|
|
@ -25,6 +25,9 @@
|
|||
# define EVENT_H_
|
||||
|
||||
# include "criterion/event.h"
|
||||
# include <stdio.h>
|
||||
|
||||
extern FILE *g_event_pipe;
|
||||
|
||||
struct event {
|
||||
int kind;
|
||||
|
|
|
@ -160,8 +160,7 @@ void normal_log_post_all(struct criterion_global_stats *stats) {
|
|||
|
||||
void normal_log_assert(struct criterion_assert_stats *stats) {
|
||||
if (!stats->passed) {
|
||||
char *dup = strdup(*stats->message ? stats->message
|
||||
: stats->condition);
|
||||
char *dup = strdup(*stats->message ? stats->message : "");
|
||||
|
||||
#ifdef VANILLA_WIN32
|
||||
char *line = strtok(dup, "\n");
|
||||
|
|
|
@ -86,7 +86,7 @@ void tap_log_post_test(struct criterion_test_stats *stats) {
|
|||
stats->elapsed_time);
|
||||
for (struct criterion_assert_stats *asrt = stats->asserts; asrt; asrt = asrt->next) {
|
||||
if (!asrt->passed) {
|
||||
char *dup = strdup(*asrt->message ? asrt->message : asrt->condition);
|
||||
char *dup = strdup(*asrt->message ? asrt->message : "");
|
||||
#ifdef VANILLA_WIN32
|
||||
char *line = strtok(dup, "\n");
|
||||
#else
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
*/
|
||||
#include <stdbool.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <setjmp.h>
|
||||
#include <dyncall.h>
|
||||
#include <assert.h>
|
||||
|
|
Loading…
Add table
Reference in a new issue