#include #include #include "msgpack.h" #define _IN " " #define _assert1(c) _assert2(c, ;) #define _assert2(c, b) _assert3(#c, c, b) #define _assert3(n, c, b) \ do { \ if(!(c)) { \ printf("Assertion error '%s' in %s:%d\n", n, __FILE__, __LINE__); \ b; \ failed_asserts++; \ } \ } while (0); #define _logvar2(v, fmt) _logvar3(v, v, fmt) #define _logvar3(n, v, fmt) printf(_IN #n" = "fmt"\n", v) #define _logbuf3(b, l, fmt) _logbuf4(b, b, l, fmt) #define _logbuf4(n, b, l, fmt) \ do { \ printf(_IN #n" = { "fmt, b[0]); \ for(size_t i = 1; i < l; i++) printf(", "fmt, b[i]); \ printf(" }\n"); \ } while(0) #define OVERLOAD_MACRO_4(_1, _2, _3, _4, NAME, ...) NAME #define assert(...) OVERLOAD_MACRO_4(__VA_ARGS__, _, _assert3, _assert2, _assert1) (__VA_ARGS__) #define logvar(...) OVERLOAD_MACRO_4(__VA_ARGS__, _, _logvar3, _logvar2, _) (__VA_ARGS__) #define logbuf(...) OVERLOAD_MACRO_4(__VA_ARGS__, _logbuf4, _logbuf3, _, _) (__VA_ARGS__) #define logbytes(...) logbuf(__VA_ARGS__, "0x%hhx") #define make_template(call, body) \ do { \ int prev_failed_asserts = failed_asserts; \ call; \ assert("Failed Test Condition", \ prev_failed_asserts == failed_asserts, \ body); \ } while(0) static int passed_test_counter; static int failed_test_counter; static int failed_asserts; int test_bool(); int test_int(); #define TEST(test) \ do { \ if(test) { \ printf("[FAILED] "#test"\n"); \ failed_test_counter++; \ } else { \ printf("[PASSED] "#test"\n"); \ passed_test_counter++; \ } \ } while(0) int main(void) { TEST(test_bool()); TEST(test_int()); printf("\n------------------------------\n"); printf("PASSED %d/%d tests, (%.1f%%)\n", passed_test_counter, failed_test_counter + passed_test_counter, 100.0f * passed_test_counter / (failed_test_counter + passed_test_counter)); return 0; } #define BODY_SUCCESS_1(type) \ { \ assert(t == type, \ logvar(t, msgpack_type_string[t], "%s")); \ } #define BODY_FAILED_1(t, e, a) \ { \ assert("Failed Call", 0, ;); \ logvar(t, msgpack_type_string[t], "%s"); \ logvar(e, msgpack_error_string[e], "%s"); \ if(e == MSGPACK_ERROR_WRONG_TYPE) \ logvar(a, msgpack_type_string[a], "%s"); \ else logvar(a, "%hhx"); \ return; \ } void bool_1(uint8_t *buf, size_t size, bool value) { uint8_t b[1]; bool v; MSGPACK_CHECK2(msgpack_read_bool(&msgpack_init(buf, size, NULL), &v), (t, e, a), BODY_SUCCESS_1(MSGPACK_BOOL), BODY_FAILED_1(t, e, a)); assert(v == value, logvar(v, "%d")); MSGPACK_CHECK2(msgpack_write_bool(&msgpack_init(b, size, NULL), &value), (t, e, a), BODY_SUCCESS_1(MSGPACK_BOOL), BODY_FAILED_1(t, e, a)); assert(memcmp(buf, b, size) == 0, logbytes(b, size)); } #define bool_template(n, _buf, _value) \ make_template(bool_##n(_buf, sizeof(_buf), _value), { \ logbytes(buf, _buf, sizeof(_buf)); \ logvar(value, _value, "%d"); \ printf("\n"); \ }); \ int test_bool() { failed_asserts = 0; bool_template(1, (uint8_t []){0xC2}, true); bool_template(1, (uint8_t []){0xC3}, false); return failed_asserts; } #define int_template(n, _buf, _value) \ make_template(bool_##n(_buf, sizeof(_buf), _value), { \ logbytes(buf, _buf, sizeof(_buf)); \ logvar(value, _value, "%d"); \ printf("\n"); \ }); \ int test_int() { failed_asserts = 0; // char buf[] = {0xD3, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x01}; // char buf[] = {0xCC, 0xFF}; return failed_asserts; }