1*d9497217SMartin Matuska // SPDX-License-Identifier: MIT 2*d9497217SMartin Matuska /* µnit Testing Framework 3*d9497217SMartin Matuska * Copyright (c) 2013-2017 Evan Nemerson <evan@nemerson.com> 4*d9497217SMartin Matuska * 5*d9497217SMartin Matuska * Permission is hereby granted, free of charge, to any person 6*d9497217SMartin Matuska * obtaining a copy of this software and associated documentation 7*d9497217SMartin Matuska * files (the "Software"), to deal in the Software without 8*d9497217SMartin Matuska * restriction, including without limitation the rights to use, copy, 9*d9497217SMartin Matuska * modify, merge, publish, distribute, sublicense, and/or sell copies 10*d9497217SMartin Matuska * of the Software, and to permit persons to whom the Software is 11*d9497217SMartin Matuska * furnished to do so, subject to the following conditions: 12*d9497217SMartin Matuska * 13*d9497217SMartin Matuska * The above copyright notice and this permission notice shall be 14*d9497217SMartin Matuska * included in all copies or substantial portions of the Software. 15*d9497217SMartin Matuska * 16*d9497217SMartin Matuska * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17*d9497217SMartin Matuska * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18*d9497217SMartin Matuska * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19*d9497217SMartin Matuska * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 20*d9497217SMartin Matuska * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 21*d9497217SMartin Matuska * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22*d9497217SMartin Matuska * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23*d9497217SMartin Matuska * SOFTWARE. 24*d9497217SMartin Matuska */ 25*d9497217SMartin Matuska 26*d9497217SMartin Matuska #ifndef MUNIT_H 27*d9497217SMartin Matuska #define MUNIT_H 28*d9497217SMartin Matuska 29*d9497217SMartin Matuska #include <stdarg.h> 30*d9497217SMartin Matuska #include <stdlib.h> 31*d9497217SMartin Matuska #include <stdio.h> 32*d9497217SMartin Matuska #include <stddef.h> 33*d9497217SMartin Matuska 34*d9497217SMartin Matuska #define MUNIT_VERSION(major, minor, revision) \ 35*d9497217SMartin Matuska (((major) << 16) | ((minor) << 8) | (revision)) 36*d9497217SMartin Matuska 37*d9497217SMartin Matuska #define MUNIT_CURRENT_VERSION MUNIT_VERSION(0, 4, 1) 38*d9497217SMartin Matuska 39*d9497217SMartin Matuska #if defined(_MSC_VER) && (_MSC_VER < 1600) 40*d9497217SMartin Matuska # define munit_int8_t __int8 41*d9497217SMartin Matuska # define munit_uint8_t unsigned __int8 42*d9497217SMartin Matuska # define munit_int16_t __int16 43*d9497217SMartin Matuska # define munit_uint16_t unsigned __int16 44*d9497217SMartin Matuska # define munit_int32_t __int32 45*d9497217SMartin Matuska # define munit_uint32_t unsigned __int32 46*d9497217SMartin Matuska # define munit_int64_t __int64 47*d9497217SMartin Matuska # define munit_uint64_t unsigned __int64 48*d9497217SMartin Matuska #else 49*d9497217SMartin Matuska # include <stdint.h> 50*d9497217SMartin Matuska # define munit_int8_t int8_t 51*d9497217SMartin Matuska # define munit_uint8_t uint8_t 52*d9497217SMartin Matuska # define munit_int16_t int16_t 53*d9497217SMartin Matuska # define munit_uint16_t uint16_t 54*d9497217SMartin Matuska # define munit_int32_t int32_t 55*d9497217SMartin Matuska # define munit_uint32_t uint32_t 56*d9497217SMartin Matuska # define munit_int64_t int64_t 57*d9497217SMartin Matuska # define munit_uint64_t uint64_t 58*d9497217SMartin Matuska #endif 59*d9497217SMartin Matuska 60*d9497217SMartin Matuska #if defined(_MSC_VER) && (_MSC_VER < 1800) 61*d9497217SMartin Matuska # if !defined(PRIi8) 62*d9497217SMartin Matuska # define PRIi8 "i" 63*d9497217SMartin Matuska # endif 64*d9497217SMartin Matuska # if !defined(PRIi16) 65*d9497217SMartin Matuska # define PRIi16 "i" 66*d9497217SMartin Matuska # endif 67*d9497217SMartin Matuska # if !defined(PRIi32) 68*d9497217SMartin Matuska # define PRIi32 "i" 69*d9497217SMartin Matuska # endif 70*d9497217SMartin Matuska # if !defined(PRIi64) 71*d9497217SMartin Matuska # define PRIi64 "I64i" 72*d9497217SMartin Matuska # endif 73*d9497217SMartin Matuska # if !defined(PRId8) 74*d9497217SMartin Matuska # define PRId8 "d" 75*d9497217SMartin Matuska # endif 76*d9497217SMartin Matuska # if !defined(PRId16) 77*d9497217SMartin Matuska # define PRId16 "d" 78*d9497217SMartin Matuska # endif 79*d9497217SMartin Matuska # if !defined(PRId32) 80*d9497217SMartin Matuska # define PRId32 "d" 81*d9497217SMartin Matuska # endif 82*d9497217SMartin Matuska # if !defined(PRId64) 83*d9497217SMartin Matuska # define PRId64 "I64d" 84*d9497217SMartin Matuska # endif 85*d9497217SMartin Matuska # if !defined(PRIx8) 86*d9497217SMartin Matuska # define PRIx8 "x" 87*d9497217SMartin Matuska # endif 88*d9497217SMartin Matuska # if !defined(PRIx16) 89*d9497217SMartin Matuska # define PRIx16 "x" 90*d9497217SMartin Matuska # endif 91*d9497217SMartin Matuska # if !defined(PRIx32) 92*d9497217SMartin Matuska # define PRIx32 "x" 93*d9497217SMartin Matuska # endif 94*d9497217SMartin Matuska # if !defined(PRIx64) 95*d9497217SMartin Matuska # define PRIx64 "I64x" 96*d9497217SMartin Matuska # endif 97*d9497217SMartin Matuska # if !defined(PRIu8) 98*d9497217SMartin Matuska # define PRIu8 "u" 99*d9497217SMartin Matuska # endif 100*d9497217SMartin Matuska # if !defined(PRIu16) 101*d9497217SMartin Matuska # define PRIu16 "u" 102*d9497217SMartin Matuska # endif 103*d9497217SMartin Matuska # if !defined(PRIu32) 104*d9497217SMartin Matuska # define PRIu32 "u" 105*d9497217SMartin Matuska # endif 106*d9497217SMartin Matuska # if !defined(PRIu64) 107*d9497217SMartin Matuska # define PRIu64 "I64u" 108*d9497217SMartin Matuska # endif 109*d9497217SMartin Matuska #else 110*d9497217SMartin Matuska # include <inttypes.h> 111*d9497217SMartin Matuska #endif 112*d9497217SMartin Matuska 113*d9497217SMartin Matuska #if !defined(munit_bool) 114*d9497217SMartin Matuska # if defined(bool) 115*d9497217SMartin Matuska # define munit_bool bool 116*d9497217SMartin Matuska # elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) 117*d9497217SMartin Matuska # define munit_bool _Bool 118*d9497217SMartin Matuska # else 119*d9497217SMartin Matuska # define munit_bool int 120*d9497217SMartin Matuska # endif 121*d9497217SMartin Matuska #endif 122*d9497217SMartin Matuska 123*d9497217SMartin Matuska #if defined(__cplusplus) 124*d9497217SMartin Matuska extern "C" { 125*d9497217SMartin Matuska #endif 126*d9497217SMartin Matuska 127*d9497217SMartin Matuska #if defined(__GNUC__) 128*d9497217SMartin Matuska # define MUNIT_LIKELY(expr) (__builtin_expect((expr), 1)) 129*d9497217SMartin Matuska # define MUNIT_UNLIKELY(expr) (__builtin_expect((expr), 0)) 130*d9497217SMartin Matuska # define MUNIT_UNUSED __attribute__((__unused__)) 131*d9497217SMartin Matuska #else 132*d9497217SMartin Matuska # define MUNIT_LIKELY(expr) (expr) 133*d9497217SMartin Matuska # define MUNIT_UNLIKELY(expr) (expr) 134*d9497217SMartin Matuska # define MUNIT_UNUSED 135*d9497217SMartin Matuska #endif 136*d9497217SMartin Matuska 137*d9497217SMartin Matuska #if !defined(_WIN32) 138*d9497217SMartin Matuska # define MUNIT_SIZE_MODIFIER "z" 139*d9497217SMartin Matuska # define MUNIT_CHAR_MODIFIER "hh" 140*d9497217SMartin Matuska # define MUNIT_SHORT_MODIFIER "h" 141*d9497217SMartin Matuska #else 142*d9497217SMartin Matuska # if defined(_M_X64) || defined(__amd64__) 143*d9497217SMartin Matuska # define MUNIT_SIZE_MODIFIER "I64" 144*d9497217SMartin Matuska # else 145*d9497217SMartin Matuska # define MUNIT_SIZE_MODIFIER "" 146*d9497217SMartin Matuska # endif 147*d9497217SMartin Matuska # define MUNIT_CHAR_MODIFIER "" 148*d9497217SMartin Matuska # define MUNIT_SHORT_MODIFIER "" 149*d9497217SMartin Matuska #endif 150*d9497217SMartin Matuska 151*d9497217SMartin Matuska #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L 152*d9497217SMartin Matuska # define MUNIT_NO_RETURN _Noreturn 153*d9497217SMartin Matuska #elif defined(__GNUC__) 154*d9497217SMartin Matuska # define MUNIT_NO_RETURN __attribute__((__noreturn__)) 155*d9497217SMartin Matuska #elif defined(_MSC_VER) 156*d9497217SMartin Matuska # define MUNIT_NO_RETURN __declspec(noreturn) 157*d9497217SMartin Matuska #else 158*d9497217SMartin Matuska # define MUNIT_NO_RETURN 159*d9497217SMartin Matuska #endif 160*d9497217SMartin Matuska 161*d9497217SMartin Matuska #if defined(_MSC_VER) && (_MSC_VER >= 1500) 162*d9497217SMartin Matuska # define MUNIT_PUSH_DISABLE_MSVC_C4127_ \ 163*d9497217SMartin Matuska __pragma(warning(push)) __pragma(warning(disable : 4127)) 164*d9497217SMartin Matuska # define MUNIT_POP_DISABLE_MSVC_C4127_ __pragma(warning(pop)) 165*d9497217SMartin Matuska #else 166*d9497217SMartin Matuska # define MUNIT_PUSH_DISABLE_MSVC_C4127_ 167*d9497217SMartin Matuska # define MUNIT_POP_DISABLE_MSVC_C4127_ 168*d9497217SMartin Matuska #endif 169*d9497217SMartin Matuska 170*d9497217SMartin Matuska typedef enum { 171*d9497217SMartin Matuska MUNIT_LOG_DEBUG, 172*d9497217SMartin Matuska MUNIT_LOG_INFO, 173*d9497217SMartin Matuska MUNIT_LOG_WARNING, 174*d9497217SMartin Matuska MUNIT_LOG_ERROR 175*d9497217SMartin Matuska } MunitLogLevel; 176*d9497217SMartin Matuska 177*d9497217SMartin Matuska #if defined(__GNUC__) && !defined(__MINGW32__) 178*d9497217SMartin Matuska # define MUNIT_PRINTF(string_index, first_to_check) \ 179*d9497217SMartin Matuska __attribute__((format(printf, string_index, first_to_check))) 180*d9497217SMartin Matuska #else 181*d9497217SMartin Matuska # define MUNIT_PRINTF(string_index, first_to_check) 182*d9497217SMartin Matuska #endif 183*d9497217SMartin Matuska 184*d9497217SMartin Matuska MUNIT_PRINTF(4, 5) 185*d9497217SMartin Matuska void munit_logf_ex(MunitLogLevel level, const char *filename, int line, 186*d9497217SMartin Matuska const char *format, ...); 187*d9497217SMartin Matuska 188*d9497217SMartin Matuska #define munit_logf(level, format, ...) \ 189*d9497217SMartin Matuska munit_logf_ex(level, __FILE__, __LINE__, format, __VA_ARGS__) 190*d9497217SMartin Matuska 191*d9497217SMartin Matuska #define munit_log(level, msg) munit_logf(level, "%s", msg) 192*d9497217SMartin Matuska 193*d9497217SMartin Matuska MUNIT_NO_RETURN 194*d9497217SMartin Matuska MUNIT_PRINTF(3, 4) 195*d9497217SMartin Matuska void munit_errorf_ex(const char *filename, int line, const char *format, ...); 196*d9497217SMartin Matuska 197*d9497217SMartin Matuska #define munit_errorf(format, ...) \ 198*d9497217SMartin Matuska munit_errorf_ex(__FILE__, __LINE__, format, __VA_ARGS__) 199*d9497217SMartin Matuska 200*d9497217SMartin Matuska #define munit_error(msg) munit_errorf("%s", msg) 201*d9497217SMartin Matuska 202*d9497217SMartin Matuska #define munit_assert(expr) \ 203*d9497217SMartin Matuska do { \ 204*d9497217SMartin Matuska if (!MUNIT_LIKELY(expr)) { \ 205*d9497217SMartin Matuska munit_error("assertion failed: " #expr); \ 206*d9497217SMartin Matuska } \ 207*d9497217SMartin Matuska MUNIT_PUSH_DISABLE_MSVC_C4127_ \ 208*d9497217SMartin Matuska } while (0) MUNIT_POP_DISABLE_MSVC_C4127_ 209*d9497217SMartin Matuska 210*d9497217SMartin Matuska #define munit_assert_true(expr) \ 211*d9497217SMartin Matuska do { \ 212*d9497217SMartin Matuska if (!MUNIT_LIKELY(expr)) { \ 213*d9497217SMartin Matuska munit_error("assertion failed: " #expr " is not true"); \ 214*d9497217SMartin Matuska } \ 215*d9497217SMartin Matuska MUNIT_PUSH_DISABLE_MSVC_C4127_ \ 216*d9497217SMartin Matuska } while (0) MUNIT_POP_DISABLE_MSVC_C4127_ 217*d9497217SMartin Matuska 218*d9497217SMartin Matuska #define munit_assert_false(expr) \ 219*d9497217SMartin Matuska do { \ 220*d9497217SMartin Matuska if (!MUNIT_LIKELY(!(expr))) { \ 221*d9497217SMartin Matuska munit_error("assertion failed: " #expr " is not false"); \ 222*d9497217SMartin Matuska } \ 223*d9497217SMartin Matuska MUNIT_PUSH_DISABLE_MSVC_C4127_ \ 224*d9497217SMartin Matuska } while (0) MUNIT_POP_DISABLE_MSVC_C4127_ 225*d9497217SMartin Matuska 226*d9497217SMartin Matuska #define munit_assert_type_full(prefix, suffix, T, fmt, a, op, b) \ 227*d9497217SMartin Matuska do { \ 228*d9497217SMartin Matuska T munit_tmp_a_ = (a); \ 229*d9497217SMartin Matuska T munit_tmp_b_ = (b); \ 230*d9497217SMartin Matuska if (!(munit_tmp_a_ op munit_tmp_b_)) { \ 231*d9497217SMartin Matuska munit_errorf("assertion failed: %s %s %s (" prefix "%" fmt suffix \ 232*d9497217SMartin Matuska " %s " prefix "%" fmt suffix ")", \ 233*d9497217SMartin Matuska #a, #op, #b, munit_tmp_a_, #op, munit_tmp_b_); \ 234*d9497217SMartin Matuska } \ 235*d9497217SMartin Matuska MUNIT_PUSH_DISABLE_MSVC_C4127_ \ 236*d9497217SMartin Matuska } while (0) MUNIT_POP_DISABLE_MSVC_C4127_ 237*d9497217SMartin Matuska 238*d9497217SMartin Matuska #define munit_assert_type(T, fmt, a, op, b) \ 239*d9497217SMartin Matuska munit_assert_type_full("", "", T, fmt, a, op, b) 240*d9497217SMartin Matuska 241*d9497217SMartin Matuska #define munit_assert_char(a, op, b) \ 242*d9497217SMartin Matuska munit_assert_type_full("'\\x", "'", char, "02" MUNIT_CHAR_MODIFIER "x", a, \ 243*d9497217SMartin Matuska op, b) 244*d9497217SMartin Matuska #define munit_assert_uchar(a, op, b) \ 245*d9497217SMartin Matuska munit_assert_type_full("'\\x", "'", unsigned char, \ 246*d9497217SMartin Matuska "02" MUNIT_CHAR_MODIFIER "x", a, op, b) 247*d9497217SMartin Matuska #define munit_assert_short(a, op, b) \ 248*d9497217SMartin Matuska munit_assert_type(short, MUNIT_SHORT_MODIFIER "d", a, op, b) 249*d9497217SMartin Matuska #define munit_assert_ushort(a, op, b) \ 250*d9497217SMartin Matuska munit_assert_type(unsigned short, MUNIT_SHORT_MODIFIER "u", a, op, b) 251*d9497217SMartin Matuska #define munit_assert_int(a, op, b) munit_assert_type(int, "d", a, op, b) 252*d9497217SMartin Matuska #define munit_assert_uint(a, op, b) \ 253*d9497217SMartin Matuska munit_assert_type(unsigned int, "u", a, op, b) 254*d9497217SMartin Matuska #define munit_assert_long(a, op, b) munit_assert_type(long int, "ld", a, op, b) 255*d9497217SMartin Matuska #define munit_assert_ulong(a, op, b) \ 256*d9497217SMartin Matuska munit_assert_type(unsigned long int, "lu", a, op, b) 257*d9497217SMartin Matuska #define munit_assert_llong(a, op, b) \ 258*d9497217SMartin Matuska munit_assert_type(long long int, "lld", a, op, b) 259*d9497217SMartin Matuska #define munit_assert_ullong(a, op, b) \ 260*d9497217SMartin Matuska munit_assert_type(unsigned long long int, "llu", a, op, b) 261*d9497217SMartin Matuska 262*d9497217SMartin Matuska #define munit_assert_size(a, op, b) \ 263*d9497217SMartin Matuska munit_assert_type(size_t, MUNIT_SIZE_MODIFIER "u", a, op, b) 264*d9497217SMartin Matuska #define munit_assert_ssize(a, op, b) \ 265*d9497217SMartin Matuska munit_assert_type(ssize_t, MUNIT_SIZE_MODIFIER "d", a, op, b) 266*d9497217SMartin Matuska 267*d9497217SMartin Matuska #define munit_assert_float(a, op, b) munit_assert_type(float, "f", a, op, b) 268*d9497217SMartin Matuska #define munit_assert_double(a, op, b) munit_assert_type(double, "g", a, op, b) 269*d9497217SMartin Matuska #define munit_assert_ptr(a, op, b) \ 270*d9497217SMartin Matuska munit_assert_type(const void *, "p", a, op, b) 271*d9497217SMartin Matuska 272*d9497217SMartin Matuska #define munit_assert_int8(a, op, b) \ 273*d9497217SMartin Matuska munit_assert_type(munit_int8_t, PRIi8, a, op, b) 274*d9497217SMartin Matuska #define munit_assert_uint8(a, op, b) \ 275*d9497217SMartin Matuska munit_assert_type(munit_uint8_t, PRIu8, a, op, b) 276*d9497217SMartin Matuska #define munit_assert_int16(a, op, b) \ 277*d9497217SMartin Matuska munit_assert_type(munit_int16_t, PRIi16, a, op, b) 278*d9497217SMartin Matuska #define munit_assert_uint16(a, op, b) \ 279*d9497217SMartin Matuska munit_assert_type(munit_uint16_t, PRIu16, a, op, b) 280*d9497217SMartin Matuska #define munit_assert_int32(a, op, b) \ 281*d9497217SMartin Matuska munit_assert_type(munit_int32_t, PRIi32, a, op, b) 282*d9497217SMartin Matuska #define munit_assert_uint32(a, op, b) \ 283*d9497217SMartin Matuska munit_assert_type(munit_uint32_t, PRIu32, a, op, b) 284*d9497217SMartin Matuska #define munit_assert_int64(a, op, b) \ 285*d9497217SMartin Matuska munit_assert_type(munit_int64_t, PRIi64, a, op, b) 286*d9497217SMartin Matuska #define munit_assert_uint64(a, op, b) \ 287*d9497217SMartin Matuska munit_assert_type(munit_uint64_t, PRIu64, a, op, b) 288*d9497217SMartin Matuska 289*d9497217SMartin Matuska #define munit_assert_ptrdiff(a, op, b) \ 290*d9497217SMartin Matuska munit_assert_type(ptrdiff_t, "td", a, op, b) 291*d9497217SMartin Matuska 292*d9497217SMartin Matuska #define munit_assert_enum(T, a, op, b) munit_assert_type(T, "d", a, op, b) 293*d9497217SMartin Matuska 294*d9497217SMartin Matuska #define munit_assert_double_equal(a, b, precision) \ 295*d9497217SMartin Matuska do { \ 296*d9497217SMartin Matuska const double munit_tmp_a_ = (a); \ 297*d9497217SMartin Matuska const double munit_tmp_b_ = (b); \ 298*d9497217SMartin Matuska const double munit_tmp_diff_ = ((munit_tmp_a_ - munit_tmp_b_) < 0) \ 299*d9497217SMartin Matuska ? -(munit_tmp_a_ - munit_tmp_b_) \ 300*d9497217SMartin Matuska : (munit_tmp_a_ - munit_tmp_b_); \ 301*d9497217SMartin Matuska if (MUNIT_UNLIKELY(munit_tmp_diff_ > 1e-##precision)) { \ 302*d9497217SMartin Matuska munit_errorf("assertion failed: %s == %s (%0." #precision \ 303*d9497217SMartin Matuska "g == %0." #precision "g)", \ 304*d9497217SMartin Matuska #a, #b, munit_tmp_a_, munit_tmp_b_); \ 305*d9497217SMartin Matuska } \ 306*d9497217SMartin Matuska MUNIT_PUSH_DISABLE_MSVC_C4127_ \ 307*d9497217SMartin Matuska } while (0) MUNIT_POP_DISABLE_MSVC_C4127_ 308*d9497217SMartin Matuska 309*d9497217SMartin Matuska #include <string.h> 310*d9497217SMartin Matuska #define munit_assert_string_equal(a, b) \ 311*d9497217SMartin Matuska do { \ 312*d9497217SMartin Matuska const char *munit_tmp_a_ = (a); \ 313*d9497217SMartin Matuska const char *munit_tmp_b_ = (b); \ 314*d9497217SMartin Matuska if (MUNIT_UNLIKELY(strcmp(munit_tmp_a_, munit_tmp_b_) != 0)) { \ 315*d9497217SMartin Matuska munit_hexdump_diff(stderr, munit_tmp_a_, strlen(munit_tmp_a_), \ 316*d9497217SMartin Matuska munit_tmp_b_, strlen(munit_tmp_b_)); \ 317*d9497217SMartin Matuska munit_errorf("assertion failed: string %s == %s (\"%s\" == \"%s\")", #a, \ 318*d9497217SMartin Matuska #b, munit_tmp_a_, munit_tmp_b_); \ 319*d9497217SMartin Matuska } \ 320*d9497217SMartin Matuska MUNIT_PUSH_DISABLE_MSVC_C4127_ \ 321*d9497217SMartin Matuska } while (0) MUNIT_POP_DISABLE_MSVC_C4127_ 322*d9497217SMartin Matuska 323*d9497217SMartin Matuska #define munit_assert_string_not_equal(a, b) \ 324*d9497217SMartin Matuska do { \ 325*d9497217SMartin Matuska const char *munit_tmp_a_ = (a); \ 326*d9497217SMartin Matuska const char *munit_tmp_b_ = (b); \ 327*d9497217SMartin Matuska if (MUNIT_UNLIKELY(strcmp(munit_tmp_a_, munit_tmp_b_) == 0)) { \ 328*d9497217SMartin Matuska munit_errorf("assertion failed: string %s != %s (\"%s\" == \"%s\")", #a, \ 329*d9497217SMartin Matuska #b, munit_tmp_a_, munit_tmp_b_); \ 330*d9497217SMartin Matuska } \ 331*d9497217SMartin Matuska MUNIT_PUSH_DISABLE_MSVC_C4127_ \ 332*d9497217SMartin Matuska } while (0) MUNIT_POP_DISABLE_MSVC_C4127_ 333*d9497217SMartin Matuska 334*d9497217SMartin Matuska #define munit_assert_memory_equal(size, a, b) \ 335*d9497217SMartin Matuska do { \ 336*d9497217SMartin Matuska const unsigned char *munit_tmp_a_ = (const unsigned char *)(a); \ 337*d9497217SMartin Matuska const unsigned char *munit_tmp_b_ = (const unsigned char *)(b); \ 338*d9497217SMartin Matuska const size_t munit_tmp_size_ = (size); \ 339*d9497217SMartin Matuska if (MUNIT_UNLIKELY(memcmp(munit_tmp_a_, munit_tmp_b_, munit_tmp_size_)) != \ 340*d9497217SMartin Matuska 0) { \ 341*d9497217SMartin Matuska size_t munit_tmp_pos_; \ 342*d9497217SMartin Matuska for (munit_tmp_pos_ = 0; munit_tmp_pos_ < munit_tmp_size_; \ 343*d9497217SMartin Matuska munit_tmp_pos_++) { \ 344*d9497217SMartin Matuska if (munit_tmp_a_[munit_tmp_pos_] != munit_tmp_b_[munit_tmp_pos_]) { \ 345*d9497217SMartin Matuska munit_hexdump_diff(stderr, munit_tmp_a_, size, munit_tmp_b_, size); \ 346*d9497217SMartin Matuska munit_errorf("assertion failed: memory %s == %s, at offset " \ 347*d9497217SMartin Matuska "%" MUNIT_SIZE_MODIFIER "u", \ 348*d9497217SMartin Matuska #a, #b, munit_tmp_pos_); \ 349*d9497217SMartin Matuska break; \ 350*d9497217SMartin Matuska } \ 351*d9497217SMartin Matuska } \ 352*d9497217SMartin Matuska } \ 353*d9497217SMartin Matuska MUNIT_PUSH_DISABLE_MSVC_C4127_ \ 354*d9497217SMartin Matuska } while (0) MUNIT_POP_DISABLE_MSVC_C4127_ 355*d9497217SMartin Matuska 356*d9497217SMartin Matuska #define munit_assert_memn_equal(a, a_size, b, b_size) \ 357*d9497217SMartin Matuska do { \ 358*d9497217SMartin Matuska const unsigned char *munit_tmp_a_ = (const unsigned char *)(a); \ 359*d9497217SMartin Matuska const unsigned char *munit_tmp_b_ = (const unsigned char *)(b); \ 360*d9497217SMartin Matuska const size_t munit_tmp_a_size_ = (a_size); \ 361*d9497217SMartin Matuska const size_t munit_tmp_b_size_ = (b_size); \ 362*d9497217SMartin Matuska if (MUNIT_UNLIKELY(munit_tmp_a_size_ != munit_tmp_b_size_) || \ 363*d9497217SMartin Matuska MUNIT_UNLIKELY(munit_tmp_a_size_ && memcmp(munit_tmp_a_, munit_tmp_b_, \ 364*d9497217SMartin Matuska munit_tmp_a_size_)) != 0) { \ 365*d9497217SMartin Matuska munit_hexdump_diff(stderr, munit_tmp_a_, munit_tmp_a_size_, \ 366*d9497217SMartin Matuska munit_tmp_b_, munit_tmp_b_size_); \ 367*d9497217SMartin Matuska munit_errorf("assertion failed: memory %s == %s", #a, #b); \ 368*d9497217SMartin Matuska } \ 369*d9497217SMartin Matuska MUNIT_PUSH_DISABLE_MSVC_C4127_ \ 370*d9497217SMartin Matuska } while (0) MUNIT_POP_DISABLE_MSVC_C4127_ 371*d9497217SMartin Matuska 372*d9497217SMartin Matuska #define munit_assert_memory_not_equal(size, a, b) \ 373*d9497217SMartin Matuska do { \ 374*d9497217SMartin Matuska const unsigned char *munit_tmp_a_ = (const unsigned char *)(a); \ 375*d9497217SMartin Matuska const unsigned char *munit_tmp_b_ = (const unsigned char *)(b); \ 376*d9497217SMartin Matuska const size_t munit_tmp_size_ = (size); \ 377*d9497217SMartin Matuska if (MUNIT_UNLIKELY(memcmp(munit_tmp_a_, munit_tmp_b_, munit_tmp_size_)) == \ 378*d9497217SMartin Matuska 0) { \ 379*d9497217SMartin Matuska munit_errorf("assertion failed: memory %s != %s (%zu bytes)", #a, #b, \ 380*d9497217SMartin Matuska munit_tmp_size_); \ 381*d9497217SMartin Matuska } \ 382*d9497217SMartin Matuska MUNIT_PUSH_DISABLE_MSVC_C4127_ \ 383*d9497217SMartin Matuska } while (0) MUNIT_POP_DISABLE_MSVC_C4127_ 384*d9497217SMartin Matuska 385*d9497217SMartin Matuska #define munit_assert_ptr_equal(a, b) munit_assert_ptr(a, ==, b) 386*d9497217SMartin Matuska #define munit_assert_ptr_not_equal(a, b) munit_assert_ptr(a, !=, b) 387*d9497217SMartin Matuska #define munit_assert_null(ptr) munit_assert_ptr(ptr, ==, NULL) 388*d9497217SMartin Matuska #define munit_assert_not_null(ptr) munit_assert_ptr(ptr, !=, NULL) 389*d9497217SMartin Matuska #define munit_assert_ptr_null(ptr) munit_assert_ptr(ptr, ==, NULL) 390*d9497217SMartin Matuska #define munit_assert_ptr_not_null(ptr) munit_assert_ptr(ptr, !=, NULL) 391*d9497217SMartin Matuska 392*d9497217SMartin Matuska /*** Memory allocation ***/ 393*d9497217SMartin Matuska 394*d9497217SMartin Matuska void *munit_malloc_ex(const char *filename, int line, size_t size); 395*d9497217SMartin Matuska 396*d9497217SMartin Matuska #define munit_malloc(size) munit_malloc_ex(__FILE__, __LINE__, (size)) 397*d9497217SMartin Matuska 398*d9497217SMartin Matuska #define munit_new(type) ((type *)munit_malloc(sizeof(type))) 399*d9497217SMartin Matuska 400*d9497217SMartin Matuska #define munit_calloc(nmemb, size) munit_malloc((nmemb) * (size)) 401*d9497217SMartin Matuska 402*d9497217SMartin Matuska #define munit_newa(type, nmemb) ((type *)munit_calloc((nmemb), sizeof(type))) 403*d9497217SMartin Matuska 404*d9497217SMartin Matuska /*** Random number generation ***/ 405*d9497217SMartin Matuska 406*d9497217SMartin Matuska void munit_rand_seed(munit_uint32_t seed); 407*d9497217SMartin Matuska munit_uint32_t munit_rand_uint32(void); 408*d9497217SMartin Matuska int munit_rand_int_range(int min, int max); 409*d9497217SMartin Matuska double munit_rand_double(void); 410*d9497217SMartin Matuska void munit_rand_memory(size_t size, munit_uint8_t *buffer); 411*d9497217SMartin Matuska 412*d9497217SMartin Matuska /*** Tests and Suites ***/ 413*d9497217SMartin Matuska 414*d9497217SMartin Matuska typedef enum { 415*d9497217SMartin Matuska /* Test successful */ 416*d9497217SMartin Matuska MUNIT_OK, 417*d9497217SMartin Matuska /* Test failed */ 418*d9497217SMartin Matuska MUNIT_FAIL, 419*d9497217SMartin Matuska /* Test was skipped */ 420*d9497217SMartin Matuska MUNIT_SKIP, 421*d9497217SMartin Matuska /* Test failed due to circumstances not intended to be tested 422*d9497217SMartin Matuska * (things like network errors, invalid parameter value, failure to 423*d9497217SMartin Matuska * allocate memory in the test harness, etc.). */ 424*d9497217SMartin Matuska MUNIT_ERROR 425*d9497217SMartin Matuska } MunitResult; 426*d9497217SMartin Matuska 427*d9497217SMartin Matuska typedef struct { 428*d9497217SMartin Matuska char *name; 429*d9497217SMartin Matuska char **values; 430*d9497217SMartin Matuska } MunitParameterEnum; 431*d9497217SMartin Matuska 432*d9497217SMartin Matuska typedef struct { 433*d9497217SMartin Matuska char *name; 434*d9497217SMartin Matuska char *value; 435*d9497217SMartin Matuska } MunitParameter; 436*d9497217SMartin Matuska 437*d9497217SMartin Matuska const char *munit_parameters_get(const MunitParameter params[], 438*d9497217SMartin Matuska const char *key); 439*d9497217SMartin Matuska 440*d9497217SMartin Matuska typedef enum { 441*d9497217SMartin Matuska MUNIT_TEST_OPTION_NONE = 0, 442*d9497217SMartin Matuska MUNIT_TEST_OPTION_SINGLE_ITERATION = 1 << 0, 443*d9497217SMartin Matuska MUNIT_TEST_OPTION_TODO = 1 << 1 444*d9497217SMartin Matuska } MunitTestOptions; 445*d9497217SMartin Matuska 446*d9497217SMartin Matuska typedef MunitResult (*MunitTestFunc)(const MunitParameter params[], 447*d9497217SMartin Matuska void *user_data_or_fixture); 448*d9497217SMartin Matuska typedef void *(*MunitTestSetup)(const MunitParameter params[], void *user_data); 449*d9497217SMartin Matuska typedef void (*MunitTestTearDown)(void *fixture); 450*d9497217SMartin Matuska 451*d9497217SMartin Matuska typedef struct { 452*d9497217SMartin Matuska const char *name; 453*d9497217SMartin Matuska MunitTestFunc test; 454*d9497217SMartin Matuska MunitTestSetup setup; 455*d9497217SMartin Matuska MunitTestTearDown tear_down; 456*d9497217SMartin Matuska MunitTestOptions options; 457*d9497217SMartin Matuska MunitParameterEnum *parameters; 458*d9497217SMartin Matuska } MunitTest; 459*d9497217SMartin Matuska 460*d9497217SMartin Matuska typedef enum { MUNIT_SUITE_OPTION_NONE = 0 } MunitSuiteOptions; 461*d9497217SMartin Matuska 462*d9497217SMartin Matuska typedef struct MunitSuite_ MunitSuite; 463*d9497217SMartin Matuska 464*d9497217SMartin Matuska struct MunitSuite_ { 465*d9497217SMartin Matuska const char *prefix; 466*d9497217SMartin Matuska const MunitTest *tests; 467*d9497217SMartin Matuska const MunitSuite *suites; 468*d9497217SMartin Matuska unsigned int iterations; 469*d9497217SMartin Matuska MunitSuiteOptions options; 470*d9497217SMartin Matuska }; 471*d9497217SMartin Matuska 472*d9497217SMartin Matuska int munit_suite_main(const MunitSuite *suite, void *user_data, int argc, 473*d9497217SMartin Matuska char *const *argv); 474*d9497217SMartin Matuska 475*d9497217SMartin Matuska /* Note: I'm not very happy with this API; it's likely to change if I 476*d9497217SMartin Matuska * figure out something better. Suggestions welcome. */ 477*d9497217SMartin Matuska 478*d9497217SMartin Matuska typedef struct MunitArgument_ MunitArgument; 479*d9497217SMartin Matuska 480*d9497217SMartin Matuska struct MunitArgument_ { 481*d9497217SMartin Matuska char *name; 482*d9497217SMartin Matuska munit_bool (*parse_argument)(const MunitSuite *suite, void *user_data, 483*d9497217SMartin Matuska int *arg, int argc, char *const *argv); 484*d9497217SMartin Matuska void (*write_help)(const MunitArgument *argument, void *user_data); 485*d9497217SMartin Matuska }; 486*d9497217SMartin Matuska 487*d9497217SMartin Matuska int munit_suite_main_custom(const MunitSuite *suite, void *user_data, int argc, 488*d9497217SMartin Matuska char *const *argv, const MunitArgument arguments[]); 489*d9497217SMartin Matuska 490*d9497217SMartin Matuska #if defined(MUNIT_ENABLE_ASSERT_ALIASES) 491*d9497217SMartin Matuska 492*d9497217SMartin Matuska # define assert_true(expr) munit_assert_true(expr) 493*d9497217SMartin Matuska # define assert_false(expr) munit_assert_false(expr) 494*d9497217SMartin Matuska # define assert_char(a, op, b) munit_assert_char(a, op, b) 495*d9497217SMartin Matuska # define assert_uchar(a, op, b) munit_assert_uchar(a, op, b) 496*d9497217SMartin Matuska # define assert_short(a, op, b) munit_assert_short(a, op, b) 497*d9497217SMartin Matuska # define assert_ushort(a, op, b) munit_assert_ushort(a, op, b) 498*d9497217SMartin Matuska # define assert_int(a, op, b) munit_assert_int(a, op, b) 499*d9497217SMartin Matuska # define assert_uint(a, op, b) munit_assert_uint(a, op, b) 500*d9497217SMartin Matuska # define assert_long(a, op, b) munit_assert_long(a, op, b) 501*d9497217SMartin Matuska # define assert_ulong(a, op, b) munit_assert_ulong(a, op, b) 502*d9497217SMartin Matuska # define assert_llong(a, op, b) munit_assert_llong(a, op, b) 503*d9497217SMartin Matuska # define assert_ullong(a, op, b) munit_assert_ullong(a, op, b) 504*d9497217SMartin Matuska # define assert_size(a, op, b) munit_assert_size(a, op, b) 505*d9497217SMartin Matuska # define assert_ssize(a, op, b) munit_assert_ssize(a, op, b) 506*d9497217SMartin Matuska # define assert_float(a, op, b) munit_assert_float(a, op, b) 507*d9497217SMartin Matuska # define assert_double(a, op, b) munit_assert_double(a, op, b) 508*d9497217SMartin Matuska # define assert_ptr(a, op, b) munit_assert_ptr(a, op, b) 509*d9497217SMartin Matuska 510*d9497217SMartin Matuska # define assert_int8(a, op, b) munit_assert_int8(a, op, b) 511*d9497217SMartin Matuska # define assert_uint8(a, op, b) munit_assert_uint8(a, op, b) 512*d9497217SMartin Matuska # define assert_int16(a, op, b) munit_assert_int16(a, op, b) 513*d9497217SMartin Matuska # define assert_uint16(a, op, b) munit_assert_uint16(a, op, b) 514*d9497217SMartin Matuska # define assert_int32(a, op, b) munit_assert_int32(a, op, b) 515*d9497217SMartin Matuska # define assert_uint32(a, op, b) munit_assert_uint32(a, op, b) 516*d9497217SMartin Matuska # define assert_int64(a, op, b) munit_assert_int64(a, op, b) 517*d9497217SMartin Matuska # define assert_uint64(a, op, b) munit_assert_uint64(a, op, b) 518*d9497217SMartin Matuska 519*d9497217SMartin Matuska # define assert_ptrdiff(a, op, b) munit_assert_ptrdiff(a, op, b) 520*d9497217SMartin Matuska 521*d9497217SMartin Matuska # define assert_enum(T, a, op, b) munit_assert_enum(T, a, op, b) 522*d9497217SMartin Matuska 523*d9497217SMartin Matuska # define assert_double_equal(a, b, precision) \ 524*d9497217SMartin Matuska munit_assert_double_equal(a, b, precision) 525*d9497217SMartin Matuska # define assert_string_equal(a, b) munit_assert_string_equal(a, b) 526*d9497217SMartin Matuska # define assert_string_not_equal(a, b) munit_assert_string_not_equal(a, b) 527*d9497217SMartin Matuska # define assert_memory_equal(size, a, b) munit_assert_memory_equal(size, a, b) 528*d9497217SMartin Matuska # define assert_memn_equal(a, a_size, b, b_size) \ 529*d9497217SMartin Matuska munit_assert_memn_equal(a, a_size, b, b_size) 530*d9497217SMartin Matuska # define assert_memory_not_equal(size, a, b) \ 531*d9497217SMartin Matuska munit_assert_memory_not_equal(size, a, b) 532*d9497217SMartin Matuska # define assert_ptr_equal(a, b) munit_assert_ptr_equal(a, b) 533*d9497217SMartin Matuska # define assert_ptr_not_equal(a, b) munit_assert_ptr_not_equal(a, b) 534*d9497217SMartin Matuska # define assert_ptr_null(ptr) munit_assert_null_equal(ptr) 535*d9497217SMartin Matuska # define assert_ptr_not_null(ptr) munit_assert_not_null(ptr) 536*d9497217SMartin Matuska 537*d9497217SMartin Matuska # define assert_null(ptr) munit_assert_null(ptr) 538*d9497217SMartin Matuska # define assert_not_null(ptr) munit_assert_not_null(ptr) 539*d9497217SMartin Matuska 540*d9497217SMartin Matuska #endif /* defined(MUNIT_ENABLE_ASSERT_ALIASES) */ 541*d9497217SMartin Matuska 542*d9497217SMartin Matuska #define munit_void_test_decl(func) \ 543*d9497217SMartin Matuska void func(void); \ 544*d9497217SMartin Matuska \ 545*d9497217SMartin Matuska static inline MunitResult wrap_##func(const MunitParameter params[], \ 546*d9497217SMartin Matuska void *fixture) { \ 547*d9497217SMartin Matuska (void)params; \ 548*d9497217SMartin Matuska (void)fixture; \ 549*d9497217SMartin Matuska \ 550*d9497217SMartin Matuska func(); \ 551*d9497217SMartin Matuska return MUNIT_OK; \ 552*d9497217SMartin Matuska } 553*d9497217SMartin Matuska 554*d9497217SMartin Matuska #define munit_void_test(func) \ 555*d9497217SMartin Matuska {"/" #func, wrap_##func, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL} 556*d9497217SMartin Matuska 557*d9497217SMartin Matuska #define munit_test_end() {NULL, NULL, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL} 558*d9497217SMartin Matuska 559*d9497217SMartin Matuska int munit_hexdump(FILE *fp, const void *data, size_t datalen); 560*d9497217SMartin Matuska 561*d9497217SMartin Matuska int munit_hexdump_diff(FILE *fp, const void *a, size_t alen, const void *b, 562*d9497217SMartin Matuska size_t blen); 563*d9497217SMartin Matuska 564*d9497217SMartin Matuska #if defined(__cplusplus) 565*d9497217SMartin Matuska } 566*d9497217SMartin Matuska #endif 567*d9497217SMartin Matuska 568*d9497217SMartin Matuska #endif /* !defined(MUNIT_H) */ 569*d9497217SMartin Matuska 570*d9497217SMartin Matuska #if defined(MUNIT_ENABLE_ASSERT_ALIASES) 571*d9497217SMartin Matuska #if defined(assert) 572*d9497217SMartin Matuska # undef assert 573*d9497217SMartin Matuska #endif 574*d9497217SMartin Matuska #define assert(expr) munit_assert(expr) 575*d9497217SMartin Matuska #endif 576