added chibi_test submodule

This commit is contained in:
Wei-ju Wu 2016-08-02 16:00:07 -07:00
parent 1fe3e13cfd
commit 4e1e1a7c76
7 changed files with 9 additions and 426 deletions

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "chibi_test"]
path = chibi_test
url = https://github.com/weiju/chibi_test

1
chibi_test Submodule

@ -0,0 +1 @@
Subproject commit 4087457724d652322e8b021c55350826a770a9fb

View File

@ -5,7 +5,7 @@ CFLAGS=-c99 -I$(NDK_INC) -DDEBUG -O2
all: main
clean:
rm -f *.o main
rm -f *.o main dos_compat_test file_list_test
main: main.o filereq.o dos13.o file_list.o dos_compat.o
$(CC) $(CFLAGS) $^ -lamiga -lauto -o $@
@ -13,11 +13,11 @@ main: main.o filereq.o dos13.o file_list.o dos_compat.o
check: file_list_test dos_compat_test
file_list_test: file_list.c file_list_test.c chibi.c
file_list_test: file_list.c file_list_test.c ../chibi_test/chibi.c
gcc $^ -o $@
./file_list_test
dos_compat_test: dos_compat.c dos_compat_test.c chibi.c
dos_compat_test: dos_compat.c dos_compat_test.c ../chibi_test/chibi.c
gcc $^ -o $@
./dos_compat_test

View File

@ -1,336 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "chibi.h"
#define MAX_DIGITS_INT 10
chibi_suite *chibi_suite_new_fixture(chibi_fixfunc setup,
chibi_fixfunc teardown,
void *userdata)
{
chibi_suite *result = calloc(1, sizeof(chibi_suite));
result->head = NULL;
result->setup = setup;
result->teardown = teardown;
result->userdata = userdata;
result->first_child = NULL;
result->next = NULL;
return result;
}
chibi_suite *chibi_suite_new()
{
return chibi_suite_new_fixture(NULL, NULL, NULL);
}
void chibi_suite_delete(chibi_suite *suite)
{
if (suite) {
struct _chibi_testcase *tc = suite->head, *tmp;
while (tc) {
tmp = tc->next;
if (tc->error_msg) free(tc->error_msg);
free(tc);
tc = tmp;
}
/* recursively free the children and siblings */
if (suite->first_child) chibi_suite_delete(suite->first_child);
if (suite->next) chibi_suite_delete(suite->next);
free(suite);
}
}
void chibi_suite_add_suite(chibi_suite *suite, chibi_suite *toadd)
{
if (!suite->first_child) suite->first_child = toadd;
else {
chibi_suite *cur = suite->first_child;
while (cur->next) cur = cur->next;
cur->next = toadd;
}
}
void _chibi_suite_add_test(chibi_suite *suite, chibi_testfunc fun, const char *fname)
{
struct _chibi_testcase *tc, *newtc;
newtc = calloc(1, sizeof(struct _chibi_testcase));
newtc->fun = fun;
newtc->fname = fname;
newtc->next = NULL;
newtc->success = 1;
newtc->error_msg = NULL;
newtc->userdata = suite->userdata;
if (!suite->head) suite->head = newtc;
else {
tc = suite->head;
while (tc->next) tc = tc->next;
tc->next = newtc;
}
}
static void _chibi_suite_summary_data(chibi_suite *suite, chibi_summary_data *summary, int level)
{
if (suite && summary) {
chibi_testcase *tc = suite->head;
if (!level) {
summary->num_runs = 0;
summary->num_failures = 0;
summary->num_pass = 0;
}
while (tc) {
summary->num_runs++;
if (!tc->success) {
summary->num_failures++;
}
tc = tc->next;
}
if (suite->first_child) _chibi_suite_summary_data(suite->first_child, summary, level + 1);
if (suite->next) _chibi_suite_summary_data(suite->next, summary, level + 1);
if (!level) summary->num_pass = summary->num_runs - summary->num_failures;
}
}
static int _print_messages(chibi_suite *suite, int testnum)
{
chibi_testcase *tc = suite->head;
while (tc) {
if (!tc->success) {
fprintf(stderr, "%d. %s\n", testnum, tc->error_msg);
testnum++;
}
tc = tc->next;
}
if (suite->first_child) testnum = _print_messages(suite->first_child, testnum);
if (suite->next) testnum = _print_messages(suite->next, testnum);
return testnum;
}
static void chibi_suite_print_summary(chibi_suite *suite)
{
chibi_summary_data summary;
_chibi_suite_summary_data(suite, &summary, 0);
fprintf(stderr, "\n\nSummary (chibitest %s)\n\n", CHIBI_TEST_GIT_SHA);
if (summary.num_failures > 0) {
fprintf(stderr, "# of failures: %d\n\n", summary.num_failures);
_print_messages(suite, 0);
fprintf(stderr, "\n");
}
fprintf(stderr, "Runs: %d Pass: %d Fail: %d\n\n", summary.num_runs,
summary.num_runs - summary.num_failures, summary.num_failures);
}
/*
* Reused by assertions to generate a standard format error message.
*/
static char *assemble_message(const char *msg, const char *srcfile,
const char *funname, int line)
{
char *msgbuffer = calloc(strlen(msg) + strlen(srcfile) + strlen(funname) + MAX_DIGITS_INT + 8,
sizeof(char));
sprintf(msgbuffer, "%s:%d - %s() - %s", srcfile, line, funname, msg);
return msgbuffer;
}
static char *assemble_message2(const char *msg1, const char *msg2,
const char *srcfile, const char *funname,
int line)
{
char *msgbuffer = calloc(strlen(msg1) + strlen(msg2) + strlen(srcfile) + strlen(funname)
+ MAX_DIGITS_INT + 10, sizeof(char));
sprintf(msgbuffer, "%s:%d - %s() - %s %s", srcfile, line, funname, msg1, msg2);
return msgbuffer;
}
/**********************************************************************
*
* ASSERTIONS
*
* TODO: test exit after first fail: make a test case with 2 assertions and ensure
* that the second is not executed when the first fails
* Note: setjmp()/longjmp() seem to be broken on Amiga/VBCC
*
**********************************************************************/
void _exit_on_fail(chibi_testcase *tc)
{
#ifndef AMIGA
longjmp(tc->env, 0);
#endif
}
void _chibi_assert_not_null(chibi_testcase *tc, void *ptr, const char *msg, const char *srcfile,
int line)
{
if (ptr == NULL) {
tc->error_msg = assemble_message(msg, srcfile, tc->fname, line);
tc->success = 0;
_exit_on_fail(tc);
}
}
void _chibi_fail(chibi_testcase *tc, const char *msg, const char *srcfile, int line)
{
tc->error_msg = assemble_message(msg, srcfile, tc->fname, line);
tc->success = 0;
_exit_on_fail(tc);
}
void _chibi_assert(chibi_testcase *tc, int cond, const char *cond_str, const char *msg,
const char *srcfile, int line)
{
if (!cond) {
tc->error_msg = assemble_message2(msg, cond_str, srcfile, tc->fname, line);
tc->success = 0;
_exit_on_fail(tc);
}
}
void _chibi_assert_eq_int(chibi_testcase *tc, int expected, int value,
const char *srcfile, int line)
{
if (value != expected) {
char *fmt = "%s:%d - %s() - expected:<%d> but was:<%d>";
char *msgbuffer = calloc(strlen(fmt) + strlen(srcfile) + strlen(tc->fname)
+ MAX_DIGITS_INT * 3 + 10, sizeof(char));
sprintf(msgbuffer, fmt, srcfile, line, tc->fname, expected, value);
tc->error_msg = msgbuffer;
tc->success = 0;
_exit_on_fail(tc);
}
}
void _chibi_assert_eq_cstr(chibi_testcase *tc, const char *expected, const char *value,
const char *srcfile, int line)
{
if (value == expected) return;
if (!value || !expected || strcmp(value, expected)) {
char *fmt, *msgbuffer;
if (!expected) expected = "(null)";
if (!value) value = "(null)";
fmt = "%s:%d - %s() - expected:<%s> but was:<%s>";
msgbuffer = calloc(strlen(fmt) + strlen(srcfile) + strlen(tc->fname)
+ strlen(expected) + strlen(value)
+ MAX_DIGITS_INT + 10, sizeof(char));
sprintf(msgbuffer, fmt, srcfile, line, tc->fname, expected, value);
tc->error_msg = msgbuffer;
tc->success = 0;
_exit_on_fail(tc);
}
}
/**********************************************************************
*
* TEST RUNNERS
*
**********************************************************************/
/*
* Generic runner. Supports fixtures and report function customization.
* If the suite was defined with setup and/or teardown functions, those
* are run on the optional userdata object.
* The report_num_tests(int), report_success(int, chibi_testcase *) and
* report_fail(int, chibi_testcase *) functions are used to support
* different output protocols (e.g. for reporting the success/failure of
* tests while they are run).
*/
static int _count_tests(chibi_suite *suite) {
chibi_testcase *testcase = suite->head;
int result = 0;
if (suite->first_child) result += _count_tests(suite->first_child);
if (suite->next) result += _count_tests(suite->next);
while (testcase) {
result++;
testcase = testcase->next;
}
return result;
}
static int _chibi_suite_run(chibi_suite *suite, void (*report_num_tests)(int),
void (*report_success)(int, chibi_testcase *),
void (*report_fail)(int, chibi_testcase *),
int tcnum, int level)
{
if (suite) {
chibi_testcase *testcase;
if (suite->first_child) {
tcnum = _chibi_suite_run(suite->first_child, report_num_tests,
report_success, report_fail, tcnum, level + 1);
}
if (suite->next) {
tcnum = _chibi_suite_run(suite->next, report_num_tests,
report_success, report_fail, tcnum, level + 1);
}
/* only report the number of tests at the top level */
if (level == 0) report_num_tests(_count_tests(suite));
/* run this level's tests */
testcase = suite->head;
while (testcase) {
#ifndef AMIGA
if (!setjmp(testcase->env)) {
#endif
if (suite->setup) suite->setup(suite->userdata);
testcase->fun(testcase);
if (suite->teardown) suite->teardown(suite->userdata);
#ifndef AMIGA
}
#endif
if (testcase->success) report_success(tcnum, testcase);
else report_fail(tcnum, testcase);
testcase = testcase->next;
tcnum++;
}
}
return tcnum;
}
/*
* Standard Runner
*/
static void report_num_tests_silent(int num_tests) { }
static void report_success_silent(int testnum, chibi_testcase *testcase) { }
static void report_fail_silent(int testnum, chibi_testcase *testcase) { }
static void report_success_std(int testnum, chibi_testcase *testcase) { fprintf(stderr, "."); }
static void report_fail_std(int testnum, chibi_testcase *testcase) { fprintf(stderr, "F"); }
void chibi_suite_run(chibi_suite *suite, chibi_summary_data *summary)
{
_chibi_suite_run(suite, report_num_tests_silent, report_success_std, report_fail_std, 0, 0);
if (summary) _chibi_suite_summary_data(suite, summary, 0);
chibi_suite_print_summary(suite);
}
void chibi_suite_run_silently(chibi_suite *suite, chibi_summary_data *summary)
{
_chibi_suite_run(suite, report_num_tests_silent, report_success_silent, report_fail_silent, 0, 0);
if (summary) _chibi_suite_summary_data(suite, summary, 0);
}
/*
* TAP Runner
*/
static void report_num_tests_tap(int num_tests) { fprintf(stdout, "1..%d\n", num_tests); }
static void report_success_tap(int testnum, chibi_testcase *testcase)
{
fprintf(stdout, "ok %d - %s\n", testnum + 1, testcase->fname);
}
static void report_fail_tap(int testnum, chibi_testcase *testcase)
{
fprintf(stdout, "not ok %d - %s\n", testnum + 1, testcase->fname);
}
void chibi_suite_run_tap(chibi_suite *suite, chibi_summary_data *summary)
{
_chibi_suite_run(suite, report_num_tests_tap, report_success_tap, report_fail_tap, 0, 0);
if (summary) _chibi_suite_summary_data(suite, summary, 0);
}

View File

@ -1,85 +0,0 @@
#pragma once
#ifndef __CHIBI_H__
#define __CHIBI_H__
#include <setjmp.h>
#define CHIBI_TEST_GIT_SHA "$Id: 72c6f3db3710d13bf1995a89992041e29ab2f43d $"
/* DATA STRUCTURES */
typedef struct _chibi_testcase {
void (*fun)(struct _chibi_testcase *);
const char *fname;
struct _chibi_testcase *next;
int success;
char *error_msg;
void *userdata;
jmp_buf env;
} chibi_testcase;
typedef void (*chibi_testfunc)(chibi_testcase *);
typedef void (*chibi_fixfunc)(void *);
typedef struct _chibi_suite {
chibi_testcase *head;
chibi_fixfunc setup, teardown;
void *userdata;
/* defines the head of the child list */
struct _chibi_suite *first_child;
/* next member in the child list */
struct _chibi_suite *next;
} chibi_suite;
typedef struct _chibi_summary_data {
int num_runs;
int num_pass;
int num_failures;
} chibi_summary_data;
/* SUITE MANAGEMENT */
extern chibi_suite *chibi_suite_new();
extern chibi_suite *chibi_suite_new_fixture(chibi_fixfunc setup, chibi_fixfunc teardown, void *userdata);
extern void chibi_suite_delete(chibi_suite *suite);
extern void chibi_suite_run(chibi_suite *suite, chibi_summary_data *summary);
extern void chibi_suite_run_silently(chibi_suite *suite, chibi_summary_data *summary);
extern void chibi_suite_run_tap(chibi_suite *suite, chibi_summary_data *summary);
/*
* We can nest suites. Since every suite can define a fixture, we might define
* a number of fixtures and run them as part of a larger suite.
*/
extern void chibi_suite_add_suite(chibi_suite *suite, chibi_suite *toadd);
/* don't use this directly */
extern void _chibi_suite_add_test(chibi_suite *suite, chibi_testfunc fun, const char *fname);
/*
* ASSERTIONS
* don't use these directly, use the macros instead, they are more convenient
* to use.
*/
extern void _chibi_assert_not_null(chibi_testcase *tc, void *ptr, const char *msg,
const char *srcfile, int line);
extern void _chibi_fail(chibi_testcase *tc, const char *msg, const char *srcfile, int line);
extern void _chibi_assert(chibi_testcase *tc, int cond, const char *cond_str, const char *msg,
const char *srcfile, int line);
extern void _chibi_assert_eq_int(chibi_testcase *tc, int expected, int value,
const char *srcfile, int line);
extern void _chibi_assert_eq_cstr(chibi_testcase *tc, const char *expected, const char *value,
const char *srcfile, int line);
/* MACROS */
#define chibi_suite_add_test(suite, testfun) (_chibi_suite_add_test(suite, testfun, #testfun))
#define CHIBI_TEST(funname) void funname(chibi_testcase *_tc)
#define chibi_assert_not_null(arg) (_chibi_assert_not_null(_tc, arg, "argument was NULL", __FILE__, __LINE__))
#define chibi_fail(msg) (_chibi_fail(_tc, msg, __FILE__, __LINE__))
#define chibi_assert(cond) (_chibi_assert(_tc, cond, #cond, "condition was wrong:", __FILE__, __LINE__))
#define chibi_assert_msg(cond, msg) (_chibi_assert(_tc, cond, "", msg, __FILE__, __LINE__))
#define chibi_assert_eq_int(expected, value) (_chibi_assert_eq_int(_tc, expected, value, __FILE__, __LINE__))
#define chibi_assert_eq_cstr(expected, value) (_chibi_assert_eq_cstr(_tc, expected, value, __FILE__, __LINE__))
#define TC_USERDATA (_tc->userdata)
#endif /* __CHIBI_H__ */

View File

@ -1,7 +1,7 @@
#include <stddef.h>
#include <string.h>
#include "chibi.h"
#include "../chibi_test/chibi.h"
#include "dos_compat.h"
CHIBI_TEST(TestPathPartNull)

View File

@ -1,6 +1,6 @@
#include <string.h>
#include "chibi.h"
#include "../chibi_test/chibi.h"
#include "file_list.h"
CHIBI_TEST(TestMakeEntry)