ex32 plus runtests improvements
This commit is contained in:
parent
23bb2b1eed
commit
508ac1a5d1
3
lcthw-remnants-2/c-skeleton/.gitignore
vendored
3
lcthw-remnants-2/c-skeleton/.gitignore
vendored
@ -1,2 +1,3 @@
|
||||
tests/runtests
|
||||
tests/your_library_tests
|
||||
tests/*_tests
|
||||
tests/**/*_tests
|
||||
|
@ -20,17 +20,25 @@ int run_tests_file(char *filename)
|
||||
return -1;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int entcount = 0;
|
||||
int rc = 0;
|
||||
int i = 0;
|
||||
int ntests = 0;
|
||||
char *testsdir = getenv("TESTS");
|
||||
char *testsdir = NULL;
|
||||
char *valgrind = getenv("VALGRIND");
|
||||
struct dirent **namelist = NULL;
|
||||
struct dirent *ep = NULL;
|
||||
|
||||
if(argc > 1) {
|
||||
testsdir = argv[1];
|
||||
}
|
||||
|
||||
if(!testsdir) {
|
||||
testsdir = getenv("TESTS");
|
||||
}
|
||||
|
||||
if(!testsdir) {
|
||||
testsdir = "./tests";
|
||||
}
|
||||
@ -70,14 +78,19 @@ int main(void)
|
||||
continue;
|
||||
}
|
||||
|
||||
printf("ERROR in test %s: here's tests/tests.log\n", filename);
|
||||
printf("------\n");
|
||||
rc = system("tail tests/tests.log");
|
||||
printf("ERROR in test %s", filename);
|
||||
if(access("tests/tests.log", R_OK) == 0) {
|
||||
printf(": here's tests/tests.log\n");
|
||||
printf("------\n");
|
||||
rc = system("tail tests/tests.log");
|
||||
} else {
|
||||
printf("\n");
|
||||
}
|
||||
goto error;
|
||||
}
|
||||
|
||||
printf("------\n");
|
||||
printf("Total of %d test files run.\n", ntests);
|
||||
printf("Total of %d test file%s run.\n", ntests, ntests > 1 ? "s" : "");
|
||||
|
||||
if(namelist) {
|
||||
free(namelist);
|
||||
|
3
lcthw-remnants-2/liblcthw/.gitignore
vendored
3
lcthw-remnants-2/liblcthw/.gitignore
vendored
@ -1,2 +1,3 @@
|
||||
tests/runtests
|
||||
tests/your_library_tests
|
||||
tests/*_tests
|
||||
tests/**/*_tests
|
||||
|
@ -6,7 +6,7 @@ PREFIX ?= /usr/local
|
||||
SOURCES = $(wildcard src/**/*.c src/*.c)
|
||||
OBJECTS = $(patsubst %.c,%.o,$(SOURCES))
|
||||
|
||||
TEST_SRC = $(wildcard tests/*_tests.c)
|
||||
TEST_SRC = $(wildcard tests/**/*_tests.c tests/*_tests.c)
|
||||
TESTS = $(patsubst %.c,%,$(TEST_SRC))
|
||||
|
||||
LIBNAME = lcthw
|
||||
@ -35,7 +35,7 @@ build:
|
||||
.PHONY: tests
|
||||
tests: LDLIBS += -static -l$(LIBNAME)
|
||||
tests: ./tests/runtests $(TESTS)
|
||||
./tests/runtests
|
||||
./tests/runtests ./tests/lcthw
|
||||
|
||||
valgrind:
|
||||
VALGRIND="valgrind --log-file=/tmp/valgrind-%p.log" $(MAKE)
|
||||
|
124
lcthw-remnants-2/liblcthw/src/lcthw/list.c
Normal file
124
lcthw-remnants-2/liblcthw/src/lcthw/list.c
Normal file
@ -0,0 +1,124 @@
|
||||
#include <lcthw/list.h>
|
||||
#include <lcthw/dbg.h>
|
||||
|
||||
List *List_create()
|
||||
{
|
||||
return calloc(1, sizeof(List));
|
||||
}
|
||||
|
||||
void List_destroy(List *list)
|
||||
{
|
||||
LIST_FOREACH(list, first, next, cur) {
|
||||
if(cur->prev) {
|
||||
free(cur->prev);
|
||||
}
|
||||
}
|
||||
|
||||
free(list->last);
|
||||
free(list);
|
||||
}
|
||||
|
||||
|
||||
void List_clear(List *list)
|
||||
{
|
||||
LIST_FOREACH(list, first, next, cur) {
|
||||
free(cur->value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void List_clear_destroy(List *list)
|
||||
{
|
||||
List_clear(list);
|
||||
List_destroy(list);
|
||||
}
|
||||
|
||||
|
||||
void List_push(List *list, void *value)
|
||||
{
|
||||
ListNode *node = calloc(1, sizeof(ListNode));
|
||||
check_mem(node);
|
||||
|
||||
node->value = value;
|
||||
|
||||
if(list->last == NULL) {
|
||||
list->first = node;
|
||||
list->last = node;
|
||||
} else {
|
||||
list->last->next = node;
|
||||
node->prev = list->last;
|
||||
list->last = node;
|
||||
}
|
||||
|
||||
list->count++;
|
||||
|
||||
error:
|
||||
return;
|
||||
}
|
||||
|
||||
void *List_pop(List *list)
|
||||
{
|
||||
ListNode *node = list->last;
|
||||
return node != NULL ? List_remove(list, node) : NULL;
|
||||
}
|
||||
|
||||
void List_unshift(List *list, void *value)
|
||||
{
|
||||
ListNode *node = calloc(1, sizeof(ListNode));
|
||||
check_mem(node);
|
||||
|
||||
node->value = value;
|
||||
|
||||
if(list->first == NULL) {
|
||||
list->first = node;
|
||||
list->last = node;
|
||||
} else {
|
||||
node->next = list->first;
|
||||
list->first->prev = node;
|
||||
list->first = node;
|
||||
}
|
||||
|
||||
list->count++;
|
||||
|
||||
error:
|
||||
return;
|
||||
}
|
||||
|
||||
void *List_shift(List *list)
|
||||
{
|
||||
ListNode *node = list->first;
|
||||
return node != NULL ? List_remove(list, node) : NULL;
|
||||
}
|
||||
|
||||
void *List_remove(List *list, ListNode *node)
|
||||
{
|
||||
void *result = NULL;
|
||||
|
||||
check(list->first && list->last, "List is empty.");
|
||||
check(node, "node can't be NULL");
|
||||
|
||||
if(node == list->first && node == list->last) {
|
||||
list->first = NULL;
|
||||
list->last = NULL;
|
||||
} else if(node == list->first) {
|
||||
list->first = node->next;
|
||||
check(list->first != NULL, "Invalid list, somehow got a first that is NULL.");
|
||||
list->first->prev = NULL;
|
||||
} else if(node == list->last) {
|
||||
list->last = node->prev;
|
||||
check(list->last != NULL, "INvalid list, somehow got a next that is NULL.");
|
||||
list->last->next = NULL;
|
||||
} else {
|
||||
ListNode *after = node->next;
|
||||
ListNode *before = node->prev;
|
||||
after->prev = before;
|
||||
before->next = after;
|
||||
}
|
||||
|
||||
list->count--;
|
||||
result = node->value;
|
||||
free(node);
|
||||
|
||||
error:
|
||||
return result;
|
||||
}
|
41
lcthw-remnants-2/liblcthw/src/lcthw/list.h
Normal file
41
lcthw-remnants-2/liblcthw/src/lcthw/list.h
Normal file
@ -0,0 +1,41 @@
|
||||
#ifndef lcthw_List_h
|
||||
#define lcthw_List_h
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
struct ListNode;
|
||||
|
||||
typedef struct ListNode {
|
||||
struct ListNode *next;
|
||||
struct ListNode *prev;
|
||||
void *value;
|
||||
} ListNode;
|
||||
|
||||
typedef struct List {
|
||||
int count;
|
||||
ListNode *first;
|
||||
ListNode *last;
|
||||
} List;
|
||||
|
||||
List *List_create();
|
||||
void List_destroy(List *list);
|
||||
void List_clear(List *list);
|
||||
void List_clear_destroy(List *list);
|
||||
|
||||
#define List_count(A) ((A)->count)
|
||||
#define List_first(A) ((A)->first != NULL ? (A)->first->value : NULL)
|
||||
#define List_last(A) ((A)->last != NULL ? (A)->last->value : NULL)
|
||||
|
||||
void List_push(List *list, void *value);
|
||||
void *List_pop(List *list);
|
||||
|
||||
void List_unshift(List *list, void *value);
|
||||
void *List_shift(List *list);
|
||||
|
||||
void *List_remove(List *list, ListNode *node);
|
||||
|
||||
#define LIST_FOREACH(L, S, M, V) ListNode *_node = NULL;\
|
||||
ListNode *V = NULL;\
|
||||
for(V = _node = L->S; _node != NULL; V = _node = _node->M)
|
||||
|
||||
#endif
|
112
lcthw-remnants-2/liblcthw/tests/lcthw/list_tests.c
Normal file
112
lcthw-remnants-2/liblcthw/tests/lcthw/list_tests.c
Normal file
@ -0,0 +1,112 @@
|
||||
#include "../minunit.h"
|
||||
#include <lcthw/list.h>
|
||||
#include <assert.h>
|
||||
|
||||
static List *list = NULL;
|
||||
char *test1 = "test1 data";
|
||||
char *test2 = "test2 data";
|
||||
char *test3 = "test3 data";
|
||||
|
||||
|
||||
char *test_create()
|
||||
{
|
||||
list = List_create();
|
||||
mu_assert(list != NULL, "Failed to create list.");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
char *test_destroy()
|
||||
{
|
||||
List_clear_destroy(list);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
char *test_push_pop()
|
||||
{
|
||||
List_push(list, test1);
|
||||
mu_assert(List_last(list) == test1, "Wrong last value.");
|
||||
|
||||
List_push(list, test2);
|
||||
mu_assert(List_last(list) == test2, "Wrong last value");
|
||||
|
||||
List_push(list, test3);
|
||||
mu_assert(List_last(list) == test3, "Wrong last value");
|
||||
mu_assert(List_count(list) == 3, "Wrong count on push.");
|
||||
|
||||
char *val = List_pop(list);
|
||||
mu_assert(val == test3, "Wrong value on pop.");
|
||||
|
||||
val = List_pop(list);
|
||||
mu_assert(val == test2, "Wrong value on pop.");
|
||||
|
||||
val = List_pop(list);
|
||||
mu_assert(val == test1, "Wrong value on pop.");
|
||||
mu_assert(List_count(list) == 0, "Wrong count after pop.");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *test_unshift()
|
||||
{
|
||||
List_unshift(list, test1);
|
||||
mu_assert(List_first(list) == test1, "Wrong first value.");
|
||||
|
||||
List_unshift(list, test2);
|
||||
mu_assert(List_first(list) == test2, "Wrong first value.");
|
||||
|
||||
List_unshift(list, test3);
|
||||
mu_assert(List_first(list) == test3, "Wrong first value.");
|
||||
mu_assert(List_count(list) == 3, "Wrong count on unshift.");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *test_remove()
|
||||
{
|
||||
// we only need to test the middle remove case since push/shift
|
||||
// already tests the other cases
|
||||
|
||||
char *val = List_remove(list, list->first->next);
|
||||
mu_assert(val == test2, "Wrong removed element.");
|
||||
mu_assert(List_count(list) == 2, "Wrong count after remove.");
|
||||
mu_assert(List_first(list) == test3, "Wrong first after remove.");
|
||||
mu_assert(List_last(list) == test1, "Wrong last after remove.");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
char *test_shift()
|
||||
{
|
||||
mu_assert(List_count(list) != 0, "Wrong count before shift.");
|
||||
|
||||
char *val = List_shift(list);
|
||||
mu_assert(val == test3, "Wrong value on shift.");
|
||||
|
||||
val = List_shift(list);
|
||||
mu_assert(val == test1, "Wrong value on shift.");
|
||||
mu_assert(List_count(list) == 0, "Wrong count after shift.");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
char *all_tests() {
|
||||
mu_suite_start();
|
||||
|
||||
mu_run_test(test_create);
|
||||
mu_run_test(test_push_pop);
|
||||
mu_run_test(test_unshift);
|
||||
mu_run_test(test_remove);
|
||||
mu_run_test(test_shift);
|
||||
mu_run_test(test_destroy);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RUN_TESTS(all_tests);
|
@ -13,7 +13,8 @@
|
||||
message = test(); tests_run++; if (message) return message;
|
||||
|
||||
#define RUN_TESTS(name) int main(int argc, char *argv[]) {\
|
||||
argc = 1; \
|
||||
argc = argc; \
|
||||
argv = argv; \
|
||||
debug("----- RUNNING: %s", argv[0]);\
|
||||
printf("----\nRUNNING: %s\n", argv[0]);\
|
||||
char *result = name();\
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
#include <fnmatch.h>
|
||||
#include <dbg.h>
|
||||
#include <lcthw/dbg.h>
|
||||
|
||||
int test_selector(const struct dirent *ep)
|
||||
{
|
||||
@ -20,17 +20,25 @@ int run_tests_file(char *filename)
|
||||
return -1;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int entcount = 0;
|
||||
int rc = 0;
|
||||
int i = 0;
|
||||
int ntests = 0;
|
||||
char *testsdir = getenv("TESTS");
|
||||
char *testsdir = NULL;
|
||||
char *valgrind = getenv("VALGRIND");
|
||||
struct dirent **namelist = NULL;
|
||||
struct dirent *ep = NULL;
|
||||
|
||||
if(argc > 1) {
|
||||
testsdir = argv[1];
|
||||
}
|
||||
|
||||
if(!testsdir) {
|
||||
testsdir = getenv("TESTS");
|
||||
}
|
||||
|
||||
if(!testsdir) {
|
||||
testsdir = "./tests";
|
||||
}
|
||||
@ -70,14 +78,19 @@ int main(void)
|
||||
continue;
|
||||
}
|
||||
|
||||
printf("ERROR in test %s: here's tests/tests.log\n", filename);
|
||||
printf("------\n");
|
||||
rc = system("tail tests/tests.log");
|
||||
printf("ERROR in test %s", filename);
|
||||
if(access("tests/tests.log", R_OK) == 0) {
|
||||
printf(": here's tests/tests.log\n");
|
||||
printf("------\n");
|
||||
rc = system("tail tests/tests.log");
|
||||
} else {
|
||||
printf("\n");
|
||||
}
|
||||
goto error;
|
||||
}
|
||||
|
||||
printf("------\n");
|
||||
printf("Total of %d test files run.\n", ntests);
|
||||
printf("Total of %d test file%s run.\n", ntests, ntests > 1 ? "s" : "");
|
||||
|
||||
if(namelist) {
|
||||
free(namelist);
|
||||
|
Loading…
Reference in New Issue
Block a user