From 612c64ca212cf4cfb47495ac37fc7d419efb052f Mon Sep 17 00:00:00 2001 From: dm1sh Date: Mon, 15 Feb 2021 07:47:13 +0500 Subject: [PATCH] Added basic test execution collector and runner and some reference assertions --- .gitignore | 3 ++ .vscode/settings.json | 7 +++ Makefile | 49 ++++++++++++++++++ README.md | 15 ++++++ include/ctest.h | 19 +++++++ include/funcs.h | 8 +++ obj/ctest.o | Bin 0 -> 4352 bytes obj/funcs.o | Bin 0 -> 1448 bytes src/ctest.c | 114 ++++++++++++++++++++++++++++++++++++++++++ src/funcs.c | 16 ++++++ 10 files changed, 231 insertions(+) create mode 100644 .gitignore create mode 100644 .vscode/settings.json create mode 100644 Makefile create mode 100644 README.md create mode 100644 include/ctest.h create mode 100644 include/funcs.h create mode 100644 obj/ctest.o create mode 100644 obj/funcs.o create mode 100644 src/ctest.c create mode 100644 src/funcs.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..869c0e6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +obj/ +.vscode +*.so* \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..a2c0541 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "files.associations": { + "ctest.h": "c", + "typeinfo": "c", + "*.a": "c" + } +} \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..aec38fd --- /dev/null +++ b/Makefile @@ -0,0 +1,49 @@ +CC=gcc + +CFLAGS=-Wall -pedantic -std=c11 -fPIC +LDFLAGS= +DFLAGS=-gdb3 + +NAMES=ctest funcs + +set_values = $(addprefix $(1),$(addsuffix $(2),$(3))) + +sourcefy = $(call set_values,./src/,.c,$(1)) +objectify = $(call set_values,./obj/,.o,$(1)) + +SOURCES=$(foreach N,$(NAMES),$(call sourcefy,$(N))) +OBJECTS=$(foreach N,$(NAMES),$(call objectify,$(N))) + +all: libctest + +libctest: $(OBJECTS) check-env + gcc -shared -Wl,-soname,$(addsuffix .so.$(CT_VERSION),$@) -o $(addsuffix .so.$(CT_VERSION).0,$@) $(OBJECTS) + + +$(OBJECTS):%.o: $($(call sourcefy $@)) objdir + $(CC) $(CFLAGS) -c -o $@ $(call sourcefy,$(subst .o,,$(@F))) + +objdir: + mkdir -p obj + +install: check-env + cp libctest.so.$(CT_VERSION).0 /usr/local/lib/ + ln -sf /usr/local/lib/libctest.so.$(CT_VERSION).0 /usr/local/lib/libctest.so.$(CT_VERSION) + ln -sf /usr/local/lib/libctest.so.$(CT_VERSION).0 /usr/local/lib/libctest.so + mkdir -p /usr/local/include/ctest + cp $(wildcard ./include/*) /usr/local/include/ctest + +uninstall: check-env + rm -f $(wildcard /usr/local/lib/libctest.so*) + rm -rf $(wildcard /usr/local/include/ctest/*) + +check-env: +ifndef CT_VERSION + $(error CT_VERSION is undefined) +endif + +.PHONY: + clean +clean: + rm -rf obj + rm $(wildcard libctest.so*) \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..dadf814 --- /dev/null +++ b/README.md @@ -0,0 +1,15 @@ +# Testing library for C + +Mostly specialized on unit tests library for improved testing experience + +# Example: + +```c +#include "ctest.h" +#include "funcs.h" +... +test(is_true(some_function()), "Function is true"); +run_tests(); +... + +``` diff --git a/include/ctest.h b/include/ctest.h new file mode 100644 index 0000000..3b34dc5 --- /dev/null +++ b/include/ctest.h @@ -0,0 +1,19 @@ +#ifndef CTEST_H +#define CTEST_H + +#include +#include +#include + +typedef struct test_structure +{ + int result; + char *name; +} test_t; + +void run_tests(int *which); +test_t *new_test(int res, char *name); +void free_test(test_t *o_t); +void test(int res, char *name); + +#endif \ No newline at end of file diff --git a/include/funcs.h b/include/funcs.h new file mode 100644 index 0000000..0d48e75 --- /dev/null +++ b/include/funcs.h @@ -0,0 +1,8 @@ +#ifndef FUNCS_H +#define FUNCS_H + +int is_equal(void *res, void *correct); +int is_true(void *res); +int is_false(void *res); + +#endif \ No newline at end of file diff --git a/obj/ctest.o b/obj/ctest.o new file mode 100644 index 0000000000000000000000000000000000000000..f180cb74013c18ab108706b8901ad20511764350 GIT binary patch literal 4352 zcmbuBU1$_n6oAj}`qyYQRZCN%Wuc@^t636jABh6k0BES-XgRnAU3NT%}(r=gDcBq9-&@a5-M5!DX-uRO6iVI$U zS(L_?pqTKj@?>vB_-jd9_#h_VkUekq4&CSJGDSH8yM_N8bubQbL(I&@MC3ju#K%-k9-kN9Pr{p(b|tGE3G%hiDqp(y z=u0%3wHCOso!h%h5_n97y%!rge^%1ZL6lCZ-1%U&IIDhFLB3s)9f`vyLTz$7>mRTF(!$}0sN97kz7BG2pxLTu?hs4Nv&afJk_2#REKM^yOzb5u3n163iy zi&fkPme+-U7PoUEA9srB^KsX9+_rdQ1{$53hId-_zrH8en29&XdsB{MXOQG-K=M}N zT^&cet-}F5g_dX-&!z^4Gj;~7F*{v!2S?tOKApB2z)5oNNEOuR7#>z&RC)(E(%IP- zZ#r_K|J8VFOJYx=1-8?+Q6d*lLS(Ei(y(d$hU@s)>_A41z%?S|0Up0xLCsXuD zSbyDWfFpX%ZPoTA&kEU#*y!OiWiNtie18b<4B;Y#_aLWuI1X7G$leaoA5i-FD0Wa} zz2JQiTeUbxL-+;cwC-2RkE|NwPGCBbnscA)^-(Zb+}n?;L3msq~&LZLV!Egi^SC=9wb zjMx_fSGm;ia6XNCg-mf2vISc$K|Ltg!7RW_7$?bV*yykSFMPL?G!sOjZBcbGZzG68 zb-5WE^TPyDh;PBhJWUXV{L?uw&k;mn|NPl;F~Cpw_Y^n%e55%0X;R~x>TbsQh2rLZ zZ!6Az4yy6@A%1?>{OJ2yOD_%-_H!Z_LXF}S&sJ=lhbB#*=9nMV^fzj}&(J3ul4~LS zrsC#)Z)y7a`QBEX{OadBqjCLw?`nSZ_#bKddi*;nF(_s{uPDxW8<1K6dlfh1IjC_x z9!qhvPR=M!H`*^f|0F5RkA5yg8rS__);Rs=@p*l$ar($&{GY04X4SJuGupj;(_%y&3&hL9jIPc}$)H%Gnh2Vakdj)$q zm2mAb7ZRD2n}WnS$ALs49}Lp@T+SZBxskkUC-7UU*>O|pAygnU`+PE6Nabv`?Ek*S z(E~k_=0ATsGLow*ufZtLdW7DNxePY~I2U>%Zv<`oH(Dxn5%h-q;%fMX| zkTQyTeFOu%?#4zwO?9^4RM8ANyguVr?2u2rHfWCRCupFFx&A(!Bi5qnQ1`gnH`T5# zY|r;YILUooZ-5^J9ahnOOEEKkw!dT8oBKbB^VQC8P9=`Nqv`y}mhJicD0XvgL{P6j sNk`Qrz3Zu&_VitAo*g2%sy(LfV3SM+^a&Hl9da7byk)HUt@1_}xooB#j- literal 0 HcmV?d00001 diff --git a/obj/funcs.o b/obj/funcs.o new file mode 100644 index 0000000000000000000000000000000000000000..258666c93ac7c31022c66a841730742b43aee8c0 GIT binary patch literal 1448 zcmbVL&r2IY6n>ki^;a9K7DPQndT0wesNh9KwuI;+A|i^H7Q3b!EKMS2HxLE!APB*W z2R(T6ukbARw-kERTWYV2$;^>Au7Tjw4SGMTlSD4VmPha8{dP>ptc^_t3l>v9PSNr zqs-4BQV0*lTBYEt0{rrKy~CPYq9mx+Ji?+|^1Y}&8$tM``q$b9FMWR)yz~X-AC&`l z4>71lxG!1Y)dNsJ-M|I4=lh@v2j#L?L9TKTcnWXNlpnZ--=L~q$yMI|Zn5f?d4b&T zwJ?T8I(zd3Y@TqLQNa9%CQu;GJn?fe7-;%Gp-%Vuwf;%;(wy;+g*k=vABu+YTlx#m zp(1%)gvpIQ&~meO6*c1YyFul*^unk|5WneL^~mFZZn>?Km^(b7!#w%ujKn{}d{S?c qMtGs!jP&1-*Yp!_?mbeF<^CUOpaoACGw(4=@?WxlE3S+Z)BgfD?q^B> literal 0 HcmV?d00001 diff --git a/src/ctest.c b/src/ctest.c new file mode 100644 index 0000000..391c6ee --- /dev/null +++ b/src/ctest.c @@ -0,0 +1,114 @@ +#include "../include/ctest.h" + +static test_t **tests; +static int tests_k; + +/** + * Executes one test check. Fails if NULL passed + * @param test Test to execute + * @param failde_k Counter of failed tests. Link is passed because it is incremented inside function body + * @param n Test number to print + */ +void execute_test(test_t *test, int *failed_k, int n) +{ + if (test == NULL) + { + fprintf(stderr, "No such test: %d", n + 1); + exit(EXIT_FAILURE); + } + + if (test->result) + fprintf(stdout, "%s\n\033[0;32m%d - Passed\033[0m\n", test->name, n + 1); + else + { + fprintf(stdout, "\033[0;31m%d FAILED\033[0m\n", n + 1); + fprintf(stderr, "Test %d failded", n + 1); + failed_k++; + } +} + +/** + * Runs all tests + * Execute after all test declarations. + * @param which Array of numbers of tests to execute ending with -1 or NULL if all tests must be run. + */ +void run_tests(int *which) +{ + fprintf(stdout, "Executing tests:\n"); + + int failed_k = 0; + + if (which == NULL) + { + for (int i = 0; i < tests_k; i++) + execute_test(tests[i], &failed_k, i); + } + else + { + int i = 0; + while (which[i] != -1) + { + int j = which[i]; + + if (j < 0 || j >= tests_k) + { + fprintf(stderr, "No such test: %d", j + 1); + exit(EXIT_FAILURE); + } + + execute_test(tests[j], &failed_k, j); + i++; + } + } + + if (failed_k > 0) + { + fprintf(stderr, "%d tests failed", failed_k); + exit(EXIT_FAILURE); + } + else + { + fprintf(stdout, "All tests passed"); + exit(EXIT_SUCCESS); + } +} + +/** + * Creates new test struct + */ +test_t *new_test(int res, char *name) +{ + test_t *n_t = (test_t *)malloc(sizeof(test_t)); + + n_t->name = strdup(name); + n_t->result = res; + + return n_t; +} + +/** + * Frees memory allocated for test structure + */ +void free_test(test_t *o_t) +{ + free(o_t->name); + free(o_t); +} + +/** + * Test declarator. Adds specified test to list of tests + * @param res Response of testing function + * @param name Test name + */ +void test(int res, char *name) +{ + if (tests == NULL) + { + tests = malloc(0); + tests_k = 0; + } + + tests = realloc(tests, (tests_k + 1) * sizeof(test_t *)); + tests[tests_k] = new_test(res, name); + tests_k++; +} \ No newline at end of file diff --git a/src/funcs.c b/src/funcs.c new file mode 100644 index 0000000..3495bb8 --- /dev/null +++ b/src/funcs.c @@ -0,0 +1,16 @@ +#include "../include/funcs.h" + +int is_equal(void *res, void *correct) +{ + return res == correct; +} + +int is_true(void *res) +{ + return res && 1; +} + +int is_false(void *res) +{ + return !res; +} \ No newline at end of file