blob: fda62634549835cab5582a271e547917882f6365 [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#pragma once
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#ifdef __cplusplus
extern "C" {
#endif
// Defines acceptable types for functions.
typedef void (*zxtest_test_fn_t)(void);
// C equivalent of zxtest::TestRef
typedef struct zxtest_test_ref {
size_t test_index;
size_t test_case_index;
} zxtest_test_ref_t;
// C test registering function.
zxtest_test_ref_t zxtest_runner_register_test(const char* testcase_name, const char* test_name,
const char* file, int line_number,
zxtest_test_fn_t test_fn);
// C test assertion function. Since we have no function overloading, the types of variables that we
// can accept on each macro will be more restricted.
void zxtest_runner_notify_assertion(const char* desc, const char* expected,
const char* expected_var, const char* actual,
const char* actual_var, const char* file, int64_t line,
bool is_fatal);
// When an assertion happens out of the main test body, this allows keeping track of whether the
// current flow should abort.
bool zxtest_runner_should_abort_current_test(void);
// Entry point for executing all tests.
int zxtest_run_all_tests(int argc, char** argv);
// Internal for generating human readable output in C.
size_t _zxtest_print_int32(int32_t val, char* buffer, size_t buffer_size);
size_t _zxtest_print_uint32(int32_t val, char* buffer, size_t buffer_size);
size_t _zxtest_print_int64(int64_t val, char* buffer, size_t buffer_size);
size_t _zxtest_print_uint64(uint64_t val, char* buffer, size_t buffer_size);
size_t _zxtest_print_bool(bool val, char* buffer, size_t buffer_size);
size_t _zxtest_print_str(const char* val, char* buffer, size_t buffer_size);
size_t _zxtest_print_ptr(const void* val, char* buffer, size_t buffer_size);
size_t _zxtest_print_hex(const void* val, size_t size, char* buffer, size_t buffer_size);
void zxtest_c_clean_buffer(char** buffer);
#ifdef __cplusplus
}
#endif
// C specific macros for registering tests.
#define RUN_ALL_TESTS(argc, argv) zxtest_run_all_tests(argc, argv)
#define _ZXTEST_TEST_REF(TestCase, Test) TestCase##_##Test##_ref
#define _ZXTEST_TEST_FN(TestCase, Test) TestCase##_##Test##_fn
#define _ZXTEST_REGISTER_FN(TestCase, Test) TestCase##_##Test##_register_fn
// Register a test as part of a TestCase.
#define TEST(TestCase, Test) \
static zxtest_test_ref_t _ZXTEST_TEST_REF(TestCase, Test) = {.test_index = 0, \
.test_case_index = 0}; \
static void _ZXTEST_TEST_FN(TestCase, Test)(void); \
static void _ZXTEST_REGISTER_FN(TestCase, Test)(void) __attribute__((constructor)); \
void _ZXTEST_REGISTER_FN(TestCase, Test)(void) { \
_ZXTEST_TEST_REF(TestCase, Test) = zxtest_runner_register_test( \
#TestCase, #Test, __FILE__, __LINE__, &_ZXTEST_TEST_FN(TestCase, Test)); \
} \
void _ZXTEST_TEST_FN(TestCase, Test)(void)
// Helper function to print variables.
// clang-format off
#define _ZXTEST_SPRINT_PRINTER(var, buffer, size) \
_Generic((var), \
int8_t: _zxtest_print_int32, \
uint8_t: _zxtest_print_int32, \
int16_t: _zxtest_print_int32, \
uint16_t: _zxtest_print_int32, \
int32_t: _zxtest_print_int32, \
uint32_t: _zxtest_print_uint32, \
int64_t: _zxtest_print_int64, \
uint64_t: _zxtest_print_uint64, \
bool: _zxtest_print_bool, \
default: _zxtest_print_ptr)(var, buffer, size)
// clang-format on
#define _ZXTEST_NULLPTR NULL
#define _ZXTEST_HEX_PRINTER(var, buffer, size) \
_zxtest_print_hex((const void*)&var, sizeof(__typeof__(var)), buffer, size)
#define _ZXTEST_PRINT_BUFFER_NAME(var, type, line, printer) \
char str_placeholder_##type##_##line = '\0'; \
size_t buff_size_##type##_##line = printer(var, &str_placeholder_##type##_##line, 1) + 1; \
char* str_buffer_##type##_##line __attribute__((cleanup(zxtest_c_clean_buffer))) = \
(char*)malloc(buff_size_##type##_##line * sizeof(char)); \
memset(str_buffer_##type##_##line, '\0', buff_size_##type##_##line); \
printer(var, str_buffer_##type##_##line, buff_size_##type##_##line)
#define _ZXTEST_LOAD_PRINT_VAR(var, type, line) \
_ZXTEST_PRINT_BUFFER_NAME(var, type, line, _ZXTEST_SPRINT_PRINTER)
#define _ZXTEST_LOAD_PRINT_HEX(var, type, line) \
_ZXTEST_PRINT_BUFFER_NAME(var, type, line, _ZXTEST_HEX_PRINTER)
#define _ZXTEST_TOKEN(token) token
#define _ZXTEST_GET_PRINT_VAR(var, type, line) str_buffer_##type##_##line
// Provides an alias for assertion mechanisms.
#define _ZXTEST_ASSERT(desc, expected, expected_var, actual, actual_var, file, line, is_fatal) \
zxtest_runner_notify_assertion(desc, expected, expected_var, actual, actual_var, file, line, \
is_fatal)
#define _ZXTEST_ABORT_IF_ERROR zxtest_runner_should_abort_current_test()
#define _ZXTEST_STRCMP(actual, expected) (strcmp(actual, expected) == 0)
#define _ZXTEST_AUTO_VAR_TYPE(var) __typeof__(var)