picom/test.h

132 lines
4.7 KiB
C
Raw Normal View History

2019-03-12 23:27:00 +00:00
// SPDX-License-Identifier: MIT
#pragma once
#ifdef UNIT_TEST
2019-03-13 21:05:12 +00:00
#include <stdbool.h>
2019-03-12 23:27:00 +00:00
#include <stdio.h>
#include <stdlib.h>
2019-03-13 21:18:08 +00:00
#include <string.h>
2019-03-13 21:05:12 +00:00
struct test_file_metadata;
struct test_failure {
bool present;
const char *message;
const char *file;
int line;
};
2019-03-12 23:27:00 +00:00
struct test_case_metadata {
2019-03-13 21:05:12 +00:00
void (*fn)(struct test_case_metadata *, struct test_file_metadata *);
struct test_failure failure;
const char *name;
2019-03-12 23:27:00 +00:00
struct test_case_metadata *next;
};
2019-03-13 21:05:12 +00:00
struct test_file_metadata {
bool registered;
const char *name;
struct test_file_metadata *next;
struct test_case_metadata *tests;
};
struct test_file_metadata __attribute__((weak)) * test_file_head;
2019-03-12 23:27:00 +00:00
2019-03-13 21:05:12 +00:00
#define SET_FAILURE(_message) \
metadata->failure = (struct test_failure) { \
.message = _message, .file = __FILE__, .line = __LINE__, .present = true, \
}
#define TEST_EQUAL(a, b) \
do { \
if ((a) != (b)) { \
SET_FAILURE(#a " != " #b); \
return; \
} \
} while (0)
#define TEST_TRUE(a) \
do { \
if (!(a)) { \
SET_FAILURE(#a " is not true"); \
return; \
} \
} while (0)
#define TEST_CASE(_name) \
static void __test_h_##_name(struct test_case_metadata *, \
struct test_file_metadata *); \
static struct test_file_metadata __test_h_file; \
static struct test_case_metadata __test_h_meta_##_name = { \
.name = #_name, \
.fn = __test_h_##_name, \
}; \
static void __attribute__((constructor)) __test_h_##_name##_register(void) { \
__test_h_meta_##_name.next = __test_h_file.tests; \
__test_h_file.tests = &__test_h_meta_##_name; \
if (!__test_h_file.registered) { \
__test_h_file.name = __FILE__; \
__test_h_file.next = test_file_head; \
test_file_head = &__test_h_file; \
__test_h_file.registered = true; \
} \
} \
static void __test_h_##_name(struct test_case_metadata *metadata, \
struct test_file_metadata *file_metadata)
2019-03-12 23:27:00 +00:00
2019-03-13 21:05:12 +00:00
/// Run defined tests, return true if all tests succeeds
2019-03-13 21:18:08 +00:00
static inline bool __attribute__((unused)) run_tests(int argc, char *const *argv) {
bool should_run = false;
for (int i = 0; i < argc; i++) {
if (strcmp(argv[i], "--unittest") == 0) {
should_run = true;
break;
}
}
if (!should_run) {
return true;
}
2019-03-13 21:05:12 +00:00
struct test_file_metadata *i = test_file_head;
int failed = 0, success = 0;
while (i) {
fprintf(stderr, "Running tests from %s:\n", i->name);
struct test_case_metadata *j = i->tests;
while (j) {
fprintf(stderr, "\t%s ... ", j->name);
j->failure.present = false;
j->fn(j, i);
if (j->failure.present) {
fprintf(stderr, "failed (%s at %s:%d)\n", j->failure.message,
j->failure.file, j->failure.line);
failed++;
} else {
fprintf(stderr, "passed\n");
success++;
}
j = j->next;
2019-03-12 23:27:00 +00:00
}
2019-03-13 21:05:12 +00:00
fprintf(stderr, "\n");
2019-03-12 23:27:00 +00:00
i = i->next;
}
2019-03-13 21:05:12 +00:00
int total = failed + success;
fprintf(stderr, "Test results: passed %d/%d, failed %d/%d\n", success, total,
failed, total);
return failed == 0;
2019-03-12 23:27:00 +00:00
}
#else
2019-03-13 21:10:11 +00:00
#include <stdbool.h>
2019-03-13 21:05:12 +00:00
#define TEST_CASE(name) static void __attribute__((unused)) __test_h_##name(void)
2019-03-12 23:27:00 +00:00
2019-03-13 21:05:12 +00:00
#define TEST_EQUAL(a, b)
#define TEST_TRUE(a)
2019-03-12 23:27:00 +00:00
2019-03-13 21:18:08 +00:00
static inline bool __attribute__((unused)) run_tests(int argc, char *const *argv) {
return true;
}
2019-03-12 23:27:00 +00:00
#endif