From 09d4532e0184ed33a7a901fc64326300d8975779 Mon Sep 17 00:00:00 2001 From: fanasina Date: Tue, 17 Oct 2023 14:13:07 +0200 Subject: [PATCH] restruct repository to ytest, create shared library for ytest --- Makefile | 82 +- README.md | 71 +- compile.sh | 6 - .../include}/bar_progress/bar_progress.h | 0 {src => include_ytest/include}/fmock/fmock.h | 0 {src => include_ytest/include}/ftest/ftest.h | 3 +- .../include}/tools_t/tools_t.h | 0 kreate_library_ytest.sh | 15 + libytest.so | Bin 0 -> 173280 bytes src/fmock/cp0fmock.h | 93 -- src/launch_is_good | Bin 182856 -> 0 bytes test/Makefile | 61 ++ test/compile.sh | 22 + test/is_good.c | 7 +- {src => test/src}/Makefile | 2 +- {src => test/src}/coordinate/coordinate.h | 0 {src => test/src}/dimension/dimension.cpp | 0 {src => test/src}/dimension/dimension.h | 0 {src => test/src}/dimension/dimension.hpp | 0 {src => test/src}/is_good.c | 0 .../src}/permutation_t/permutation_t.c | 0 .../src}/permutation_t/permutation_t.h | 0 .../src}/set_theoric_t/set_theoric_t.c | 0 .../src}/set_theoric_t/set_theoric_t.h | 0 .../src}/tensor/tens0neD/tens0neD.cpp | 0 {src => test/src}/tensor/tens0neD/tens0neD.h | 0 .../src}/tensor/tensCuda/d_tensCuda.cu | 0 .../src}/tensor/tensCuda/d_tensCuda.h | 0 {src => test/src}/tensor/tensCuda/tensCuda.cu | 0 {src => test/src}/tensor/tensCuda/tensCuda.h | 0 ybar_progress/Makefile | 17 + .../include/bar_progress/bar_progress.h | 30 + .../src}/bar_progress/bar_progress.c | 2 +- ybar_progress/src/bar_progress/bar_progress.h | 30 + yfmock/Makefile | 20 + yfmock/include/fmock/fmock.h | 286 +++++++ {src => yfmock/src}/fmock/fmock.c | 6 +- yftest/Makefile | 24 + yftest/include/ftest/ftest.h | 800 ++++++++++++++++++ {src => yftest/src}/ftest/ftest.c | 4 +- ytools_t/Makefile | 17 + ytools_t/include/tools_t/tools_t.h | 119 +++ {src => ytools_t/src}/tools_t/tools_t.c | 0 ytools_t/src/tools_t/tools_t.h | 119 +++ 44 files changed, 1673 insertions(+), 163 deletions(-) delete mode 100755 compile.sh rename {src => include_ytest/include}/bar_progress/bar_progress.h (100%) rename {src => include_ytest/include}/fmock/fmock.h (100%) rename {src => include_ytest/include}/ftest/ftest.h (99%) rename {src => include_ytest/include}/tools_t/tools_t.h (100%) mode change 100755 => 100644 create mode 100644 kreate_library_ytest.sh create mode 100644 libytest.so delete mode 100644 src/fmock/cp0fmock.h delete mode 100755 src/launch_is_good create mode 100644 test/Makefile create mode 100644 test/compile.sh rename {src => test/src}/Makefile (97%) rename {src => test/src}/coordinate/coordinate.h (100%) rename {src => test/src}/dimension/dimension.cpp (100%) rename {src => test/src}/dimension/dimension.h (100%) mode change 100755 => 100644 rename {src => test/src}/dimension/dimension.hpp (100%) mode change 100755 => 100644 rename {src => test/src}/is_good.c (100%) rename {src => test/src}/permutation_t/permutation_t.c (100%) rename {src => test/src}/permutation_t/permutation_t.h (100%) rename {src => test/src}/set_theoric_t/set_theoric_t.c (100%) rename {src => test/src}/set_theoric_t/set_theoric_t.h (100%) rename {src => test/src}/tensor/tens0neD/tens0neD.cpp (100%) rename {src => test/src}/tensor/tens0neD/tens0neD.h (100%) rename {src => test/src}/tensor/tensCuda/d_tensCuda.cu (100%) mode change 100755 => 100644 rename {src => test/src}/tensor/tensCuda/d_tensCuda.h (100%) rename {src => test/src}/tensor/tensCuda/tensCuda.cu (100%) rename {src => test/src}/tensor/tensCuda/tensCuda.h (100%) create mode 100644 ybar_progress/Makefile create mode 100644 ybar_progress/include/bar_progress/bar_progress.h rename {src => ybar_progress/src}/bar_progress/bar_progress.c (99%) create mode 100644 ybar_progress/src/bar_progress/bar_progress.h create mode 100644 yfmock/Makefile create mode 100644 yfmock/include/fmock/fmock.h rename {src => yfmock/src}/fmock/fmock.c (98%) create mode 100644 yftest/Makefile create mode 100644 yftest/include/ftest/ftest.h rename {src => yftest/src}/ftest/ftest.c (99%) create mode 100644 ytools_t/Makefile create mode 100644 ytools_t/include/tools_t/tools_t.h rename {src => ytools_t/src}/tools_t/tools_t.c (100%) create mode 100644 ytools_t/src/tools_t/tools_t.h diff --git a/Makefile b/Makefile index 1ea95f6..07473cc 100644 --- a/Makefile +++ b/Makefile @@ -1,63 +1,49 @@ - -NAME_TEST=is_good +# lib: -lytest +PROJECT_LIB=libytest.so CC=gcc -LDFLAGS=-lpthread #-D DEBUG=1 -ROOT_DIR=$(shell pwd) -INCLUDE_DIR=$(ROOT_DIR)/src -CFLAGS=-I$(INCLUDE_DIR) -SRC_DIR=$(ROOT_DIR)/src -#SRC=$(wildcard */*/*.c) -SRC=$(wildcard **/**/*.c) +#LDFLAGS= +INCLUDE_DIRS=$(PWD) +#$(wildcard $(PWD)/**/include) +INCLUDE=-I$(PWD)/yftest/include -I$(PWD)/yfmock/include -I$(PWD)/ytools_t/include -I$(PWD)/ybar_progress/include +CFLAGS=-lpthread -Wall -Werror -fpic $(INCLUDE) + +TOPTARGETS := all clean #update_headers + +#SRC=$(wildcard y*/src/**/**/*.c) +SRC=$(wildcard y*/*/*/*.c) OBJ=$(SRC:.c=.o) -#HEADS=$(OBJS:.o=.h) -TEST_DIR=$(ROOT_DIR)/test -EXECSRC=$(TEST_DIR)/$(NAME_TEST).c -EXEC=$(ROOT_DIR)/launch_$(NAME_TEST)_m -PERMSRC=src/permutation_t/permutation_t.c -PERMSRC_O=$(PERMSRC:.c=.o) -SETTSRC=src/set_theoric_t/set_theoric_t.c -SETTSRC_O=$(SETTSRC:.c=.o) -TOOLSRC=src/tools_t/tools_t.c -TOOLSRC_O=$(TOOLSRC:.c=.o) -FTESTSRC=src/ftest/ftest.c -FTESTSRC_O=$(FTESTSRC:.c=.o) -FMOCKSRC=src/fmock/fmock.c -FMOCKSRC_O=$(FMOCKSRC:.c=.o) -BPROGRESSRC=src/bar_progress/bar_progress.c -BPROGRESSRC_0=$(BPROGRESSRC:.c=.o) -all: $(EXEC) +SUBDIRS :=$(wildcard y*) -$(EXEC): $(EXECSRC) $(OBJ) - $(CC) -o $@ $^ -I$(INCLUDE_DIR) $(LDFLAGS) +export -$(FMOCKSRC_O): $(FMOCKSRC) $(FTESTSRC_O) - $(CC) -o $@ -c $< $(CFLAGS) -$(FTESTSRC_O): $(FTESTSRC) $(TOOLSRC_O) - $(CC) -o $@ -c $< $(CFLAGS) +$(TOPTARGETS): $(SUBDIRS) -$(PERMSRC_O): $(PERMSRC) $(SETTSRC_O) - $(CC) -o $@ -c $< $(CFLAGS) +all: $(PROJECT_LIB) -$(SETTSRC_O) : $(SETTSRC) $(TOOLSRC_O) - $(CC) -o $@ -c $< $(CFLAGS) -$(TOOLSRC_O): $(TOOLSRC) - $(CC) -o $@ -c $< $(CFLAGS) +$(PROJECT_LIB): $(OBJ) + echo $(OBJ) + #$(CC) -shared -o $@ $^ $(INCLUDE) $(LDFLAGS) + $(CC) -shared -o $@ $^ $(LDFLAGS) -$(BPROGRESSRC_0): $(BPROGRESSRC) - $(CC) -o $@ -c $< $(CFLAGS) -.PHONY: clean mrproper +$(SUBDIRS): + $(MAKE) -C $@ $(MAKECMDGOALS) + +update_headers: $(PROJECT_LIB) + for file_h in $(SUBDIRS); do cp -r "$$file_h/include" include_ytest/; done + +.PHONY: $(TOPTARGETS) $(SUBDIRS) clean: - echo "all src : $(SRC)" - echo "all obj : $(OBJ)" - rm -f $(OBJ) + rm -f $(PROJECT_LIB) -mrproper: clean - rm -f $(EXEC) +remove_headers: + rm -r include_ytest/* -run: $(EXEC) - $(EXEC) -h +#SRC_test=test/is_good.c + +#compile: $(SRC_test) $(PROJECT_LIB) +# $(CC) -o launch_is_good_m $< -L. test/src/permutation_t/permutation_t.o test/src/set_theoric_t/set_theoric_t.o -lytest -I./test/src -I./include_ytest diff --git a/README.md b/README.md index 881ad61..be9ec67 100644 --- a/README.md +++ b/README.md @@ -4,29 +4,79 @@ C library like `gtest / gmock` like, but works mainly with functions ## env linux +## install +``` +make +``` +or +``` +./kreate_library_ytest.sh +``` + +### make options +``` +make update_headers +``` +it copy all headers of `ytest` in `include_ytest/include/` + +## compile +if the code is in `test/is_good.c` we compile in the main directory by: +``` +gcc -o launch_ex test/is_good.c -I./include_ytest -L. -lytest \ + src/permutation/permutation.c src/set_theoric/set_theoric.c -I./src # this line is the library we need to test! +``` +if we change the directory, we need to notice the /Path_to_dir_ytest, then change the option compile by +``` +gcc -o launch_ex path_to_file/is_good.c -I/Path_to_dir_ytest/include_ytest -L/Path_to_dir_ytest -lytest \ + /Path_tolib/src/permutation/permutation.c /Path_tolib/src/set_theoric/set_theoric.c -I./Path_tolib # this line is the library we need to test! +``` + +## install lib ytest + +copy the headers in `include_ytest` to include directory, for example +``` +cp include_ytest/include/* /usr/include/ +``` +or +``` +cp include_ytest/include/* ~/.local/include/ +``` +if `/usr/include` or `~/.local/include` is in `CPATH` +or +add ```export CPATH=/Path_to_dir_ytest/include_ytest/include:$CPATH``` in `~/.bashrc`. + +So, we do not need to add `-I/Path_to_dir_ytest/include_ytest/include` when compiling, + +To avoid `-L/Path_to_dir_ytest` when compiling, we can copy `libytest.so` in a directory in `/usr/lib/` or copy `libytest.so` in `/path_to/lib_ytest/` and then +add ```export LD_LIBRARY_PATH=/path_to/lib_ytest:$LD_LIBRARY_PATH``` in `~/.bashrc`. + + + + ## test examples `test/is_good.c` -## compile and run +## compile and run the example ``` -make +cd test +make ./launch_is_good_m ``` or ``` chmod +x compile.sh -./compile.sh +./compile.sh "is_good.c" ./launch_is_good_c ``` ## some compile options ### if need debug print -`./compile "-D DEBUG=1"` +`./compile "s_good.c" "-D DEBUG=1"` ### if need gdb -`./compile "-g"` +`./compile "test/is_good.c" "-g"` ### if need prompt googletest like -`./compile "-D HK"` +`./compile "test/is_good.c" "-D HK"` -We can combine these options, for example: `./compile "-D DEBUG=1 -D HK -g"` +We can combine these options, for example: `./compile "test/is_good.c" "-D DEBUG=1 -D HK -g"` ## launch options if using run_all_tests_args(argc, argv); By default `./launch_is_good_{c,m}` is on 1 thread but we can add some options to run tests in parallel, or change colors, to disable progress bar, ..., to print help @@ -89,6 +139,12 @@ For example, to launch tests (`test/is_good.c`) on 4 threads, using unicolor(bla # How to create test + +This need to add `path_to/include_ytest/include` in `CPATH` by `export CPATH=/path_to/include_ytest/include:$CPATH` in terminal or in `~/.bashrc` file for example, or add `-I/path_to/include_ytest/include` when compiling, +the others option when compiling are `-L/path_to/directorytest` this path must contain `libytest.so` generated by `make` or `./kreate_library_ytest` or we can put this path in `LD_LIBRARY_PATH`. +And we must add `lytest` to add the shared library in compilation. + +## include ``` #include "ftest/ftest.h" @@ -102,6 +158,7 @@ TEST(){ EXPECT_TRUE(true); } ``` + ## in main func ### if using options: ``` diff --git a/compile.sh b/compile.sh deleted file mode 100755 index 21909b8..0000000 --- a/compile.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash - -gcc test/is_good.c src/ftest/ftest.c src/fmock/fmock.c \ - src/tools_t/tools_t.c src/bar_progress/bar_progress.c \ - src/permutation_t/permutation_t.c src/set_theoric_t/set_theoric_t.c \ - -Isrc $1 -o launch_is_good_c -lpthread diff --git a/src/bar_progress/bar_progress.h b/include_ytest/include/bar_progress/bar_progress.h similarity index 100% rename from src/bar_progress/bar_progress.h rename to include_ytest/include/bar_progress/bar_progress.h diff --git a/src/fmock/fmock.h b/include_ytest/include/fmock/fmock.h similarity index 100% rename from src/fmock/fmock.h rename to include_ytest/include/fmock/fmock.h diff --git a/src/ftest/ftest.h b/include_ytest/include/ftest/ftest.h similarity index 99% rename from src/ftest/ftest.h rename to include_ytest/include/ftest/ftest.h index 0eebbbd..9797e9c 100644 --- a/src/ftest/ftest.h +++ b/include_ytest/include/ftest/ftest.h @@ -782,8 +782,9 @@ do{ void CONCAT(TEST_##name_f##____,count)(void) -//#define TEST(name_f)\ +/*#define TEST(name_f)\ FTEST_(__COUNTER__,name_f) +*/ #define TEST(name_f) \ FTEST__(__COUNTER__,name_f) diff --git a/src/tools_t/tools_t.h b/include_ytest/include/tools_t/tools_t.h old mode 100755 new mode 100644 similarity index 100% rename from src/tools_t/tools_t.h rename to include_ytest/include/tools_t/tools_t.h diff --git a/kreate_library_ytest.sh b/kreate_library_ytest.sh new file mode 100644 index 0000000..bbe50e9 --- /dev/null +++ b/kreate_library_ytest.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +for yfile in y* +do + cp -r "$yfile/include" include_ytest/ +done + + +gcc -c -Wall -Werror -fpic yftest/src/ftest/ftest.c yfmock/src/fmock/fmock.c \ + ytools_t/src/tools_t/tools_t.c ybar_progress/src/bar_progress/bar_progress.c \ + -I./include_ytest/include $1 -lpthread + +gcc -shared -o libytest.so *.o + +rm *.o diff --git a/libytest.so b/libytest.so new file mode 100644 index 0000000000000000000000000000000000000000..6248557cb2ac7c875caa8fc435b31b1a3da7f44a GIT binary patch literal 173280 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 literal 0 HcmV?d00001 diff --git a/src/fmock/cp0fmock.h b/src/fmock/cp0fmock.h deleted file mode 100644 index 191db7f..0000000 --- a/src/fmock/cp0fmock.h +++ /dev/null @@ -1,93 +0,0 @@ -#ifndef __MOCK_C_H__ -#define __MOCK_C_H__ - -#include "ftest/ftest.h" -#include "tools_t/tools_t.h" - -#define INFINITY -8 -#define INITSTATE -1 -#define DONOTHING 0 - -int parse_count_args_(char *input); - -struct func_mock_info_struct{ - long id; - void *struct_mock;/* contain returntype, namefunction, args... */ - int expect_call;/* 1 if EXPECT_MOCK_CALL and 0 if WILL_MOCK_CALL */ - long init_times_left;/* DONOTHING do nothing (pass to -> next), INFINITY every time; INITSTATE init; > 0 execute and decrement */ - long times_left; - struct func_mock_struct *next; -}; - -#define MOCK_FUNC(returntype, namefunction, args_prototype_with_parenthesis, args_call_with_parenthesis)\ - /*typedef returntype FUNC_type_ ## namefunction args_prototype_with_parenthesis ;*/\ - /*typedef args_prototype_with_parenthesis args_ ## namefunction;*/\ - struct list_mock_return_ ## namefunction{\ - returntype (*run) args_prototype_with_parenthesis;\ - int expect_call;/* 1 if EXPECT_MOCK_CALL and 0 if WILL_MOCK_CALL */\ - int (*call_mock_condition) args_prototype_with_parenthesis ;/* to store condition */\ - /*int arg_count;*/\ - long init_times_left;/* DONOTHING do nothing (pass to -> next), INFINITY every time; INITSTATE init; > 0 execute and decrement */\ - long times_left;/* DONOTHING do nothing (pass to -> next), INFINITY every time; INITSTATE init; > 0 execute and decrement */\ - struct list_mock_return_ ## namefunction *next;\ - } list_mo_ ## namefunction;\ - __attribute__((constructor)) void init_list_m_ ## namefunction(void){\ - list_mo_ ## namefunction.times_left = INITSTATE;\ - /*list_mo_ ## namefunction.arg_count = parse_count_args_(#args_prototype_with_parenthesis);\ - list_mo_ ## namefunction.call_mock_condition = malloc(list_mo_ ## namefunction.arg_count * sizeof( int (*)(void*))) ;*/\ - list_mo_ ## namefunction.next = NULL;\ - }\ - returntype namefunction args_prototype_with_parenthesis {\ - struct list_mock_return_ ## namefunction *tmp_mock = &list_mo_ ## namefunction;\ - while(tmp_mock->next && tmp_mock->times_left == 0) tmp_mock = tmp_mock->next ;\ - /*LOG("condition_func:%d\n", tmp_mock->call_mock_condition args_call_with_parenthesis);*/ /*LOG("%s\n","failure condition");*/\ - EXPECT_EQ_TYPE_INT(1, tmp_mock->call_mock_condition args_call_with_parenthesis); /*LOG("%s\n","failure condition");*/\ - if ((tmp_mock->times_left <= INFINITY) || (tmp_mock->times_left > 0)){\ - --(tmp_mock->times_left);\ - if(1 == tmp_mock->call_mock_condition args_call_with_parenthesis){\ - return tmp_mock->run args_call_with_parenthesis;\ - }\ - else return (returntype)0;/* default return */\ - }\ - } - - -#define ADD_RESPONSE(returntype, namefunction, args_prototype_with_parenthesis, condition_on_args_expression , repeat, f_expect_call, id)\ - /*FUNC_type_ ## namefunction CONCAT(run_ ## namefunction ## _ID_ , id);*/\ - returntype CONCAT(run_ ## namefunction ## _ID_ , id) args_prototype_with_parenthesis; \ - int CONCAT(namefunction ## _cond_ , id) args_prototype_with_parenthesis {LOG("cond:%d\n",condition_on_args_expression); return condition_on_args_expression;}\ - __attribute__((constructor)) void CONCAT(append_list_ ## namefunction , id)(void){\ - struct list_mock_return_ ## namefunction *tmp_mock = &list_mo_ ## namefunction;\ - if(tmp_mock->times_left == INITSTATE){/* init state */\ - tmp_mock->expect_call = f_expect_call;\ - tmp_mock->init_times_left = repeat;\ - tmp_mock->times_left = repeat;\ - tmp_mock->call_mock_condition = CONCAT(namefunction ## _cond_, id);\ - tmp_mock->run = CONCAT(run_ ## namefunction ## _ID_, id);\ - }\ - else{\ - while(tmp_mock->next) tmp_mock = tmp_mock->next;\ - tmp_mock->next = malloc(sizeof(list_mo_ ## namefunction));\ - (tmp_mock->next)->run = CONCAT(run_ ## namefunction ## _ID_, id);\ - (tmp_mock->next)->call_mock_condition = CONCAT(namefunction ## _cond_, id);\ - (tmp_mock->next)->expect_call = f_expect_call;\ - (tmp_mock->next)->init_times_left = repeat;\ - (tmp_mock->next)->times_left = repeat;\ - (tmp_mock->next)->next = NULL;\ - }\ - }\ - returntype CONCAT(run_ ## namefunction ## _ID_, id) args_prototype_with_parenthesis - - - - -#define EXPECT_MOCK_CALL(returntype, namefunction, args_prototype_with_parenthesis, condition_on_args_expression ,repeat) \ - ADD_RESPONSE(returntype,namefunction, args_prototype_with_parenthesis, condition_on_args_expression, repeat, 1, __LINE__) - - -#define WILL_MOCK_CALL(returntype, namefunction, args_prototype_with_parenthesis, condition_on_args_expression ,repeat) \ - ADD_RESPONSE(returntype,namefunction, args_prototype_with_parenthesis, condition_on_args_expression, repeat, 0, __LINE__) - - - -#endif /* __MOCK_C_H__ */ diff --git a/src/launch_is_good b/src/launch_is_good deleted file mode 100755 index 4255fe2f488a7c095e717398ac417169af846b8b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 182856 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�{zv{ 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 diff --git a/test/Makefile b/test/Makefile new file mode 100644 index 0000000..c8f9214 --- /dev/null +++ b/test/Makefile @@ -0,0 +1,61 @@ + + + + +NAME_TEST=is_good +CC=gcc +ROOT_DIR=$(PWD) +INCLUDE_DIR=$(ROOT_DIR)/src +CFLAGS=-I$(INCLUDE_DIR) -I../include_ytest/include +LDFLAGS=-L$(PWD)/.. -lytest + +#SRC_DIR=$(ROOT_DIR)/src +#SRC=$(wildcard */*/*.c) +SRC=$(wildcard **/**/*.c) +OBJ=$(SRC:.c=.o) +#HEADS=$(OBJS:.o=.h) +TEST_DIR=$(PWD) +EXECSRC=$(NAME_TEST).c +EXEC=launch_$(NAME_TEST)_m +PERMSRC=src/permutation_t/permutation_t.c +PERMSRC_O=$(PERMSRC:.c=.o) +SETTSRC=src/set_theoric_t/set_theoric_t.c +SETTSRC_O=$(SETTSRC:.c=.o) +TOOLSRC=../ytools_t/src/tools_t/tools_t.c +TOOLSRC_O=$(TOOLSRC:.c=.o) + +FTESTSRC=src/ftest/ftest.c +FTESTSRC_O=$(FTESTSRC:.c=.o) +FMOCKSRC=src/fmock/fmock.c +FMOCKSRC_O=$(FMOCKSRC:.c=.o) +BPROGRESSRC=src/bar_progress/bar_progress.c +BPROGRESSRC_0=$(BPROGRESSRC:.c=.o) + +LIB_YTEST=../libytest.so + +all: $(EXEC) $(LIB_YTEST) + +$(EXEC): $(EXECSRC) $(OBJ) + $(CC) -o $@ $^ $(CFLAGS) $(LDFLAGS) + +$(PERMSRC_O): $(PERMSRC) $(SETTSRC_O) + $(CC) -o $@ -c $< $(CFLAGS) + +$(SETTSRC_O) : $(SETTSRC) $(TOOLSRC_O) + $(CC) -o $@ -c $< $(CFLAGS) + +$(TOOLSRC_O): $(TOOLSRC) + $(CC) -o $@ -c $< $(CFLAGS) + +.PHONY: clean mrproper + +clean: + #echo "all src : $(SRC)" + #echo "all obj : $(OBJ)" + rm -f $(OBJ) + +mrproper: clean + rm -f $(EXEC) + +run: $(EXEC) + $(EXEC) -h diff --git a/test/compile.sh b/test/compile.sh new file mode 100644 index 0000000..1949482 --- /dev/null +++ b/test/compile.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +if [ "$#" -le 0 ] ; then + echo "Usage: $0 is_good.c" >&2 + echo "for example to compile: is_good.c" >&2 + exit 1 +fi +if [ "$#" -le 1 ] ; then + echo "Usage: $0 $1" >&2 + echo " we can add more option for example '-D DEBUG=1' to have debug print, '-D HK' to have gtest like prompt, od '-g' to gbd" >&2 + echo "for example: $0 $1 \"-D DEBUG=1 -D HK -g\"" +fi + + +export LD_LIBRARY_PATH=$PWD/../:LD_LIBRARY_PATH + +gcc -o launch_is_good_c $1 -L$PWD/../ $2 -lytest -I../include_ytest/include src/permutation_t/permutation_t.o src/set_theoric_t/set_theoric_t.o -I./src +#gcc -o launch_is_good_c $1 $2 -lytest -I../include_ytest src/permutation_t/permutation_t.o src/set_theoric_t/set_theoric_t.o -I./src + + + +#gcc $1 src/ftest/ftest.c src/fmock/fmock.c src/tools_t/tools_t.c src/bar_progress/bar_progress.c src/permutation_t/permutation_t.c src/set_theoric_t/set_theoric_t.c -I./include $2 -o launch_is_good_c -lpthread diff --git a/test/is_good.c b/test/is_good.c index 082dabf..1c37377 100644 --- a/test/is_good.c +++ b/test/is_good.c @@ -12,9 +12,10 @@ #include "ftest/ftest.h" #include "fmock/fmock.h" +#if 1 + #include "permutation_t/permutation_t.h" -#if 1 TEST(size_permutation2){ PRINTF("another size_permutation2 again\n"); @@ -30,6 +31,8 @@ TEST(size_permutation) PRINTF("test size_permutation2\n"); } +#endif + TEST(size_permutation2){ PRINTF("another size_permutation2 again false\n"); bool val_bool = false; @@ -78,6 +81,7 @@ TEST(){ ASSERT_TRUE(true); } + TEST(){ sleep(3); int a = 5; @@ -176,7 +180,6 @@ TEST(sleep){sleep(1);} TEST(sleep){sleep(1);} TEST(sleep){sleep(1);} -#endif TEST(sleep){sleep(1);} TEST(sleep){sleep(1);} TEST(sleep){sleep(1);} diff --git a/src/Makefile b/test/src/Makefile similarity index 97% rename from src/Makefile rename to test/src/Makefile index 640288a..897eb11 100644 --- a/src/Makefile +++ b/test/src/Makefile @@ -6,7 +6,7 @@ ROOT_DIR=$(shell pwd) INCLUDE_DIR=$(ROOT_DIR) CFLAGS=-I$(INCLUDE_DIR) SRC_DIR=$(ROOT_DIR) -SRC=$(wildcard */*.c) +SRC=$(wildcard src/*/*.c) OBJ=$(SRC:.c=.o) #HEADS=$(OBJS:.o=.h) TEST_DIR=$(ROOT_DIR) diff --git a/src/coordinate/coordinate.h b/test/src/coordinate/coordinate.h similarity index 100% rename from src/coordinate/coordinate.h rename to test/src/coordinate/coordinate.h diff --git a/src/dimension/dimension.cpp b/test/src/dimension/dimension.cpp similarity index 100% rename from src/dimension/dimension.cpp rename to test/src/dimension/dimension.cpp diff --git a/src/dimension/dimension.h b/test/src/dimension/dimension.h old mode 100755 new mode 100644 similarity index 100% rename from src/dimension/dimension.h rename to test/src/dimension/dimension.h diff --git a/src/dimension/dimension.hpp b/test/src/dimension/dimension.hpp old mode 100755 new mode 100644 similarity index 100% rename from src/dimension/dimension.hpp rename to test/src/dimension/dimension.hpp diff --git a/src/is_good.c b/test/src/is_good.c similarity index 100% rename from src/is_good.c rename to test/src/is_good.c diff --git a/src/permutation_t/permutation_t.c b/test/src/permutation_t/permutation_t.c similarity index 100% rename from src/permutation_t/permutation_t.c rename to test/src/permutation_t/permutation_t.c diff --git a/src/permutation_t/permutation_t.h b/test/src/permutation_t/permutation_t.h similarity index 100% rename from src/permutation_t/permutation_t.h rename to test/src/permutation_t/permutation_t.h diff --git a/src/set_theoric_t/set_theoric_t.c b/test/src/set_theoric_t/set_theoric_t.c similarity index 100% rename from src/set_theoric_t/set_theoric_t.c rename to test/src/set_theoric_t/set_theoric_t.c diff --git a/src/set_theoric_t/set_theoric_t.h b/test/src/set_theoric_t/set_theoric_t.h similarity index 100% rename from src/set_theoric_t/set_theoric_t.h rename to test/src/set_theoric_t/set_theoric_t.h diff --git a/src/tensor/tens0neD/tens0neD.cpp b/test/src/tensor/tens0neD/tens0neD.cpp similarity index 100% rename from src/tensor/tens0neD/tens0neD.cpp rename to test/src/tensor/tens0neD/tens0neD.cpp diff --git a/src/tensor/tens0neD/tens0neD.h b/test/src/tensor/tens0neD/tens0neD.h similarity index 100% rename from src/tensor/tens0neD/tens0neD.h rename to test/src/tensor/tens0neD/tens0neD.h diff --git a/src/tensor/tensCuda/d_tensCuda.cu b/test/src/tensor/tensCuda/d_tensCuda.cu old mode 100755 new mode 100644 similarity index 100% rename from src/tensor/tensCuda/d_tensCuda.cu rename to test/src/tensor/tensCuda/d_tensCuda.cu diff --git a/src/tensor/tensCuda/d_tensCuda.h b/test/src/tensor/tensCuda/d_tensCuda.h similarity index 100% rename from src/tensor/tensCuda/d_tensCuda.h rename to test/src/tensor/tensCuda/d_tensCuda.h diff --git a/src/tensor/tensCuda/tensCuda.cu b/test/src/tensor/tensCuda/tensCuda.cu similarity index 100% rename from src/tensor/tensCuda/tensCuda.cu rename to test/src/tensor/tensCuda/tensCuda.cu diff --git a/src/tensor/tensCuda/tensCuda.h b/test/src/tensor/tensCuda/tensCuda.h similarity index 100% rename from src/tensor/tensCuda/tensCuda.h rename to test/src/tensor/tensCuda/tensCuda.h diff --git a/ybar_progress/Makefile b/ybar_progress/Makefile new file mode 100644 index 0000000..c06b690 --- /dev/null +++ b/ybar_progress/Makefile @@ -0,0 +1,17 @@ + + + +BARPROGES_SRC=src/bar_progress/bar_progress.c +BARPROGES_O=$(BARPROGES_SRC:.c=.o) + +all: $(BARPROGES_O) + +$(BARPROGES_O): $(BARPROGES_SRC) + $(CC) -o $@ -c $< $(CFLAGS) + + +.PHONY: clean + +clean: + rm -f $(BARPROGES_O) + diff --git a/ybar_progress/include/bar_progress/bar_progress.h b/ybar_progress/include/bar_progress/bar_progress.h new file mode 100644 index 0000000..48a8928 --- /dev/null +++ b/ybar_progress/include/bar_progress/bar_progress.h @@ -0,0 +1,30 @@ +#ifndef __BAR_PROGRESS_H__ +#define __BAR_PROGRESS_H__ + +#include +#include +#include +//#include +#include +#include + + + +/* + * Prepares screen for progress bar. + */ +void bar_progress_start(void); + +void bar_progress_step_msg(int step_progress, int all_progress, char *msg, char fill_bar, char fill_dot, int colored); + +/* + * progress value 0 to 100 + */ +void bar_progress_step(float step_percent); + +/* + * Removes progress bar and restores original screen size. + */ +void bar_progress_stop(void); + +#endif /* __BAR_PROGRESS_H */ diff --git a/src/bar_progress/bar_progress.c b/ybar_progress/src/bar_progress/bar_progress.c similarity index 99% rename from src/bar_progress/bar_progress.c rename to ybar_progress/src/bar_progress/bar_progress.c index 9731d2d..1b3c248 100644 --- a/src/bar_progress/bar_progress.c +++ b/ybar_progress/src/bar_progress/bar_progress.c @@ -72,7 +72,7 @@ void bar_progress_step_msg(int step_progress, int all_progress, char *msg, char } int size_char_log= strlen(msg) + strlen("(-) Progress: [100a] [aaaa/bbbb] a"); int width = (w.ws_col - size_char_log); - int j; + //int j; /* for(int j=0; j< width ; ++j) if (j<(int)(width * (step_progress / 100))) bar[j]='='; diff --git a/ybar_progress/src/bar_progress/bar_progress.h b/ybar_progress/src/bar_progress/bar_progress.h new file mode 100644 index 0000000..48a8928 --- /dev/null +++ b/ybar_progress/src/bar_progress/bar_progress.h @@ -0,0 +1,30 @@ +#ifndef __BAR_PROGRESS_H__ +#define __BAR_PROGRESS_H__ + +#include +#include +#include +//#include +#include +#include + + + +/* + * Prepares screen for progress bar. + */ +void bar_progress_start(void); + +void bar_progress_step_msg(int step_progress, int all_progress, char *msg, char fill_bar, char fill_dot, int colored); + +/* + * progress value 0 to 100 + */ +void bar_progress_step(float step_percent); + +/* + * Removes progress bar and restores original screen size. + */ +void bar_progress_stop(void); + +#endif /* __BAR_PROGRESS_H */ diff --git a/yfmock/Makefile b/yfmock/Makefile new file mode 100644 index 0000000..f213508 --- /dev/null +++ b/yfmock/Makefile @@ -0,0 +1,20 @@ + + +FMOCK_SRC=src/fmock/fmock.c +FMOCK_O=$(FMOCK_SRC:.c=.o) + +FTEST_SRC=../yftest/src/ftest/ftest.c +FTEST_O=$(FTEST_SRC:.c=.o) + + +all: $(FMOCK_O) + +$(FMOCK_O): $(FMOCK_SRC) $(FTEST_O) + $(CC) -o $@ -c $< $(CFLAGS) + + +.PHONY: clean + +clean: + rm -f $(FMOCK_O) + diff --git a/yfmock/include/fmock/fmock.h b/yfmock/include/fmock/fmock.h new file mode 100644 index 0000000..7ef12c0 --- /dev/null +++ b/yfmock/include/fmock/fmock.h @@ -0,0 +1,286 @@ +#ifndef __MOCK_C_H__ +#define __MOCK_C_H__ + +#include "ftest/ftest.h" +#include "tools_t/tools_t.h" + +#define INFINITY -8 +#define INITSTATE -1 +#define DONOTHING 0 + +#define PRE_ID ___line_ +/* + * list of each variable called + * use str_print_current_variables attibute function pointer to record variable + * so if STR_PRINT_CUR_VAR is not defined, this list is empty! + */ +struct list_current_variable{ + char *str_current_variables; + struct list_current_variable *next; +}; + +/* + * list to store info abou mock function + */ +struct func_mock_info_struct{ + long id; + char *str_namefunc; + char *str_conditions; + char *str_caller; + //char *str_current_variables; + struct list_current_variable *l_current_var; + int expect_call;/* 1 if EXPECT_MOCK_CALL and 0 if WILL_MOCK_CALL */ + long call;/* increment when call (try to executed) and 0 if not : init value */ + long failed_call;/* increment when condition not fill and 0 if not : init value */ + long init_times_left;/* DONOTHING do nothing (pass to -> next), INFINITY every time; INITSTATE init; > 0 execute and decrement */ + long times_left;/* DONOTHING do nothing (pass to -> next), INFINITY every time; INITSTATE init; > 0 execute and decrement */ + struct func_mock_info_struct *next; +}; + +/* + * to list all mock responses of all mock functions in one list + */ +struct list_base_fmock{ + struct func_mock_info_struct *info_mock; + struct list_base_fmock *next; +}; + + + +int parse_count_args_(char *input); +void append_fmock_to_listmock(struct func_mock_info_struct **f_mock_list, struct func_mock_info_struct *f_mock); +void append_list_base_fmock(struct list_base_fmock **l_fmock, struct func_mock_info_struct *f_mock); +void append_variable_current(struct list_current_variable **lcurrent_var, char *current_var); + +// if input == functioname___line_NBLINE return functioname, else it return the input +//char* extract_name_func_mock(char *input); + +extern struct func_mock_info_struct *f_mock_glist; +extern struct list_base_fmock *g_list_base_fmock; + +#if 0 + int expect_call; /* 1 if EXPECT_MOCK_CALL and 0 if WILL_MOCK_CALL */\ + long init_times_left; /* DONOTHING do nothing (pass to -> next), INFINITY every time; INITSTATE init; > 0 execute and decrement */\ + long times_left; /* DONOTHING do nothing (pass to -> next), INFINITY every time; INITSTATE init; > 0 execute and decrement */\ + +#endif + +#define INIT_MOCK_INFO_IF_NO__(tmp__mock, namefunction, pre_id, id) \ + (tmp__mock)->run = NULL;\ + (tmp__mock)->call_mock_condition = NULL;\ + /*(tmp__mock)->str_print_current_variables = list_mo_ ## namefunction .str_print_current_variables;*/\ + ((tmp__mock)->info_mock)->expect_call = -1;\ + ((tmp__mock)->info_mock)->call = 0;\ + ((tmp__mock)->info_mock)->failed_call = 0;\ + ((tmp__mock)->info_mock)->str_namefunc = malloc(strlen(#namefunction) + 32 + strlen(#pre_id));\ + sprintf(((tmp__mock)->info_mock)->str_namefunc,"%s%s%d",#namefunction,#pre_id,id);\ + ((tmp__mock)->info_mock)->str_conditions = NULL;\ + ((tmp__mock)->info_mock)->str_caller = NULL;\ + ((tmp__mock)->info_mock)->l_current_var= NULL;\ + ((tmp__mock)->info_mock)->next = NULL;\ + /*(tmp__mock)->next = NULL;*/\ + append_fmock_to_listmock(&f_mock_glist, (tmp__mock)->info_mock);\ + append_list_base_fmock( &g_list_base_fmock ,(tmp__mock)->info_mock); + +#define INIT_MOCK_INFO_IF_NO_(tmp_new_mock, namefunction, pre_id) \ + INIT_MOCK_INFO_IF_NO__(tmp_new_mock, namefunction, pre_id, __LINE__) \ + +#define MOCK_FUNC(returntype, namefunction, args_prototype_with_parenthesis, args_call_with_parenthesis)\ + /*typedef returntype FUNC_type_ ## namefunction args_prototype_with_parenthesis ;*/\ + /*typedef args_prototype_with_parenthesis args_ ## namefunction;*/\ + struct list_mock_return_ ## namefunction{\ + returntype (*run) args_prototype_with_parenthesis;\ + int (*call_mock_condition) args_prototype_with_parenthesis ;/* to store condition */\ + char* (*str_print_current_variables) args_prototype_with_parenthesis ;/* to store current variables CREATE by macro STR_PRINT_CUR_VAR same arguments as MOCK_FUNC without returntype whoch is always char * */\ + struct func_mock_info_struct *info_mock;\ + struct list_mock_return_ ## namefunction *next;\ + } list_mo_ ## namefunction;\ + __attribute__((constructor)) void init_list_m_ ## namefunction(void){\ + list_mo_ ## namefunction.info_mock = malloc(sizeof(struct func_mock_info_struct));\ + (list_mo_ ## namefunction.info_mock)->times_left = INITSTATE;\ + (list_mo_ ## namefunction.info_mock)->init_times_left = INITSTATE;\ + list_mo_ ## namefunction.str_print_current_variables = NULL;\ + list_mo_ ## namefunction.next = NULL;\ + }\ + returntype namefunction args_prototype_with_parenthesis {\ + static size_t count_call_f=0;\ + ++count_call_f;\ + PRINT_DEBUG(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>count call of %s: %ld\n",#namefunction,count_call_f);\ + struct list_mock_return_ ## namefunction *tmp_mock = &list_mo_ ## namefunction;\ + if( (tmp_mock->info_mock)->times_left == INITSTATE ){\ + PRINT_HK_C(colors_f[k_YELLOW],HK_TR," WARNING, %s, no EXPECT_MOCK_CALL or WILL_MOCK_CALL, but called %ld times.\n",#namefunction, count_call_f);\ + if(count_call_f==1){\ + PRINT_HK_C(colors_f[k_YELLOW],HK_TR," For instance:\n"\ + "%s EXPECT_MOCK_CALL(%s,%s,%s,true,1){\n"\ + "%s\t %s ret;\n%s \t ...do something with %s;\n"\ + "%s\t return ret;\n"\ + "%s }\n"\ + "%s if call once and accept all args, the same args with WILL_MOCK_CALL \n\n",\ + HK_TR, #returntype, #namefunction,#args_prototype_with_parenthesis, HK_TR,#returntype, \ + HK_TR, #args_call_with_parenthesis, HK_TR, HK_TR, HK_TR ); \ + /*return (returntype)0;*/ \ + INIT_MOCK_INFO_IF_NO_(tmp_mock,namefunction, PRE_ID);\ + }/* to have log */\ + /*if(list_mo_ ## namefunction.next ) PRINT_ERROR(" %s .next SHOULD BE NULL\n",STRFY(list_mo_ ## namefunction));*/\ + }\ + while(tmp_mock->next && (tmp_mock->info_mock)->times_left == 0) {tmp_mock = tmp_mock->next ;}\ + ++((tmp_mock->info_mock)->call);\ + if(tmp_mock->str_print_current_variables){\ + append_variable_current(&((tmp_mock->info_mock)->l_current_var), tmp_mock->str_print_current_variables args_call_with_parenthesis);\ + }\ + else if(count_call_f == 1){\ + PRINT_HK_C(colors_f[k_YELLOW],HK_TR," no printer variable function defined, to define it:\n"\ + "%s STR_PRINT_CUR_VAR(%s,%s,%s){\n"\ + "%s\t char* ret=malloc(256);/*for instance*/;\n"\ + "%s\t ... sprintf(ret,...., %s);/*for instance*/ \n"\ + "%s\t return ret;\n"\ + "%s }\n"\ + "%s same prototype as MOCK_FUNC whithout returntype which always char* i\n\n",\ + HK_TR, #namefunction,#args_prototype_with_parenthesis, #args_call_with_parenthesis, \ + HK_TR, HK_TR, #args_call_with_parenthesis, HK_TR, HK_TR, HK_TR ); \ + }\ + /*LOG("condition_func:%d\n", tmp_mock->call_mock_condition args_call_with_parenthesis);*/ /*LOG("%s\n","failure condition");*/\ + /*EXPECT_EQ_TYPE_INT(1, tmp_mock->call_mock_condition args_call_with_parenthesis);*/ /*LOG("%s\n","failure condition");*/\ + /*if ((tmp_mock->info_mock)->times_left == 0)*/ /*no longer response, default return */ \ + /*return (returntype)0;*//* default return */\ + if( (tmp_mock->info_mock)->str_caller == NULL){ \ + if(count_call_f == 1){\ + PRINT_HK_C(colors_f[k_YELLOW],HK_TR," WARNING, no INIT_CALLER_MOCK; you can put it like this: \n"\ + "%s TEST(nametest){\n"\ + "%s\t INIT_CALLER_MOCK(%s); \n"\ + "%s\t %s%s; \n"\ + "%s }\n"\ + "%s i.e before calling %s in this TEST, to have explicit logs\n",\ + HK_TR, HK_TR, #namefunction, HK_TR,#namefunction,#args_call_with_parenthesis, HK_TR, HK_TR, #namefunction);} \ + /*return (returntype)0;*/ \ + }\ + else if (((tmp_mock->info_mock)->times_left != 0) && ((tmp_mock->info_mock)->times_left != INITSTATE )) {\ + size_t len0 = strlen((tmp_mock->info_mock)->str_conditions);\ + size_t len1 = strlen("when checking condition call: aa");\ + char *msg_call=malloc(len0 + len1 + strlen(__func__));\ + sprintf(msg_call,"when checking %s condition call: %s",__func__,(tmp_mock->info_mock)->str_conditions);\ + HANDLE_OP_EXPECT_NAME(EQ,TYPE_INT,1, tmp_mock->call_mock_condition args_call_with_parenthesis, (tmp_mock->info_mock)->str_caller, msg_call); /*LOG("%s\n","failure condition");*/\ + free(msg_call);\ + }\ + /*if(0 == tmp_mock->call_mock_condition args_call_with_parenthesis){\ + PRINT_LOC("Failure, arguments not expected\ncondition ( %s ) not verified\n\n", (tmp_mock->info_mock)->str_conditions);\ + PRINT_HK_C(RED_K,HK_TR," 1 argument check failed from %s \n",__func__); \ + }*/\ + PRINT_DEBUG(" %*c VALUES: mock function:%s, conditions:%s t_left:%ld, init_left:%ld| args:%s\n",8,'^',(tmp_mock->info_mock)->str_namefunc, (tmp_mock->info_mock)->str_conditions, (tmp_mock->info_mock)->times_left,(tmp_mock->info_mock)->init_times_left, #args_call_with_parenthesis);\ + if (((tmp_mock->info_mock)->times_left <= INFINITY) || ((tmp_mock->info_mock)->times_left > 0)){\ + --((tmp_mock->info_mock)->times_left);\ + PRINT_DEBUG(" %*c VALUES: mock function:%s, conditions:%s t_left:%ld, init_left:%ld| args:%s\n",8,'v',(tmp_mock->info_mock)->str_namefunc, (tmp_mock->info_mock)->str_conditions, (tmp_mock->info_mock)->times_left,(tmp_mock->info_mock)->init_times_left, #args_call_with_parenthesis);\ + if(1 == tmp_mock->call_mock_condition args_call_with_parenthesis){\ + return tmp_mock->run args_call_with_parenthesis;\ + }\ + else ++((tmp_mock->info_mock)->failed_call);\ + }\ + return (returntype)0;/* default return */\ + } + + +char* extract_name_func_mock(char *input); + +/* + * used in mock functions to check the conditions + */ +#define EXPECT_EQ_IN_MOCKF(var1,var2, name_f_mocked)\ + do{ \ + if((list_mo_ ## name_f_mocked.info_mock)->str_caller) {\ + HANDLE_OP_EXPECT_NAME(EQ,TYPE_INT,var1,var2,(list_mo_ ## name_f_mocked.info_mock)->str_caller,"mock test");\ + }\ + else\ + HANDLE_OP_EXPECT_NAME(EQ,TYPE_INT,var1,var2,__func__,"mock test");\ +}while(0) + + +/* + * to inject the name TEST caller in the mock attribute info, usefull in logs and stats + */ +#define INIT_CALLER_MOCK(namefunction)/* */\ + do{\ + struct list_mock_return_ ## namefunction *tmp_mock = &list_mo_ ## namefunction;\ + while(tmp_mock){\ + (tmp_mock->info_mock)->str_caller=malloc(strlen(__func__));\ + strcpy((tmp_mock->info_mock)->str_caller,__func__);\ + tmp_mock = tmp_mock->next;\ + }\ + }while(0); + +/* + * to create/ define str_print_current_variables functions + * prototype: char* str_print_current_variables (prototype of mock function) + * the args of the macro are the same of MOCK_FUNC without the returntype which is always (char*). + * It need to be defined after MOCK_FUNC but need to be before EXPECT_MOCK_CALL or WILL_MOCK_CALL + */ + +#define STR_PRINT_CUR_VAR(namefunction, args_prototype_with_parenthesis, args_call_with_parenthesis)\ + char* str_print_variables ## namefunction args_prototype_with_parenthesis;\ +__attribute__((constructor)) void create_str_print_variables ## namefunction(){\ + list_mo_ ## namefunction .str_print_current_variables = str_print_variables ## namefunction;\ + }\ + char* str_print_variables ## namefunction args_prototype_with_parenthesis + + + + +#define FILL_MOCK_INFO(tmp_new_mock, namefunction, condition_on_args_expression , repeat, f_expect_call, pre_id, id, is_init) \ + (tmp_new_mock)->run = CONCAT(run_ ## namefunction ## pre_id, id);\ + (tmp_new_mock)->call_mock_condition = CONCAT(namefunction ## _cond_, id);\ + if(!is_init)\ + (tmp_new_mock)->str_print_current_variables = list_mo_ ## namefunction .str_print_current_variables;\ + /*(tmp_new_mock)->info_mock = malloc(sizeof(struct func_mock_info_struct));*/\ + ((tmp_new_mock)->info_mock)->expect_call = f_expect_call;\ + ((tmp_new_mock)->info_mock)->call = 0;\ + ((tmp_new_mock)->info_mock)->failed_call = 0;\ + ((tmp_new_mock)->info_mock)->init_times_left = repeat;\ + ((tmp_new_mock)->info_mock)->times_left = repeat;\ + ((tmp_new_mock)->info_mock)->str_namefunc = malloc(strlen(#namefunction) + 32 + strlen(#pre_id));\ + sprintf(((tmp_new_mock)->info_mock)->str_namefunc,"%s%s%d",#namefunction,#pre_id,id);\ + ((tmp_new_mock)->info_mock)->str_conditions = malloc(strlen(#condition_on_args_expression));\ + strcpy(((tmp_new_mock)->info_mock)->str_conditions, #condition_on_args_expression);\ + ((tmp_new_mock)->info_mock)->str_caller = NULL;\ + ((tmp_new_mock)->info_mock)->l_current_var= NULL;\ + ((tmp_new_mock)->info_mock)->next = NULL;\ + (tmp_new_mock)->next = NULL;\ + append_fmock_to_listmock(&f_mock_glist, (tmp_new_mock)->info_mock); + + +#define ADD_RESPONSE_(returntype, namefunction, args_prototype_with_parenthesis, condition_on_args_expression , repeat, f_expect_call, pre_id, id)\ + /*FUNC_type_ ## namefunction CONCAT(run_ ## namefunction ## pre_id , id);*/\ + returntype CONCAT(run_ ## namefunction ## pre_id , id) args_prototype_with_parenthesis; \ + int CONCAT(namefunction ## _cond_ , id) args_prototype_with_parenthesis {/*LOG("cond:%d\n",condition_on_args_expression);*/ return condition_on_args_expression;}\ + __attribute__((constructor)) void CONCAT(append_list_ ## namefunction , id)(void){\ + struct list_mock_return_ ## namefunction *tmp_mock = &list_mo_ ## namefunction;\ + if((tmp_mock->info_mock)->times_left == INITSTATE){/* init state */\ + FILL_MOCK_INFO(tmp_mock, namefunction, condition_on_args_expression , repeat, f_expect_call, pre_id, id, true);\ + append_list_base_fmock( &g_list_base_fmock ,(tmp_mock->info_mock));\ + }\ + else{\ + while(tmp_mock->next) tmp_mock = tmp_mock->next;\ + tmp_mock->next = malloc(sizeof(list_mo_ ## namefunction));\ + (tmp_mock->next)->info_mock = malloc(sizeof(struct func_mock_info_struct));\ + FILL_MOCK_INFO(tmp_mock->next, namefunction, condition_on_args_expression , repeat, f_expect_call, pre_id, id, false);\ + /*(tmp_mock->info_mock)->next = (tmp_mock->next)->info_mock ;*/\ + }\ + }\ + returntype CONCAT(run_ ## namefunction ## pre_id, id) args_prototype_with_parenthesis + +/* + * have to define this below macro to rewrite the right macro identifier (PRE_ID) + */ + +#define ADD_RESPONSE(returntype, namefunction, args_prototype_with_parenthesis, condition_on_args_expression , repeat, f_expect_call, pre_id, id)\ + ADD_RESPONSE_(returntype, namefunction, args_prototype_with_parenthesis, condition_on_args_expression , repeat, f_expect_call, pre_id, id)\ + + +#define EXPECT_MOCK_CALL(returntype, namefunction, args_prototype_with_parenthesis, condition_on_args_expression ,repeat) \ + ADD_RESPONSE(returntype,namefunction, args_prototype_with_parenthesis, condition_on_args_expression, repeat, 1, PRE_ID, __LINE__) + + +#define WILL_MOCK_CALL(returntype, namefunction, args_prototype_with_parenthesis, condition_on_args_expression ,repeat) \ + ADD_RESPONSE(returntype,namefunction, args_prototype_with_parenthesis, condition_on_args_expression, repeat, 0, PRE_ID, __LINE__) + + + +#endif /* __MOCK_C_H__ */ diff --git a/src/fmock/fmock.c b/yfmock/src/fmock/fmock.c similarity index 98% rename from src/fmock/fmock.c rename to yfmock/src/fmock/fmock.c index a4bfb96..5a0edf4 100644 --- a/src/fmock/fmock.c +++ b/yfmock/src/fmock/fmock.c @@ -198,14 +198,14 @@ __attribute__((destructor)) is_parallel_nb = 0; /* no longer parallel here */ - struct func_mock_info_struct *tmock = f_mock_glist, *tfree; + struct func_mock_info_struct *tmock = f_mock_glist; //, *tfree; /* global order of fmock , order of expect and will */ while(tmock){ PRINT_DEBUG("check mock function: %s\n",tmock->str_namefunc); - tfree=tmock; + //tfree=tmock; PRINT_DEBUG("**** STAT mock function:%s, conditions:%s t_left:%ld, init_left:%ld, failed_call:%ld\n",tmock->str_namefunc, tmock->str_conditions, tmock->times_left,tmock->init_times_left, tmock->failed_call); - if((tmock->expect_call) && (tmock->init_times_left == tmock->times_left) || (tmock->failed_call)){ + if(((tmock->expect_call) && (tmock->init_times_left == tmock->times_left)) || (tmock->failed_call)){ if(tmock->l_current_var){ PRINTF("%s%s %s%s %s: expect %s, it was called %ld times and failed %ld times, with condition %s\n",colors_f[k_RED],HK_FL,colors_f[k_YELLOW],tmock->str_namefunc,DEFAULT_K, number_call_translate(tmock->init_times_left), diff --git a/yftest/Makefile b/yftest/Makefile new file mode 100644 index 0000000..b6b9a94 --- /dev/null +++ b/yftest/Makefile @@ -0,0 +1,24 @@ + + +FTEST_SRC=src/ftest/ftest.c +FTEST_O=$(FTEST_SRC:.c=.o) + +TOOLS_SRC=../ytools_t/src/tools_t/tools_t.c +TOOLS_O=$(TOOLS_SRC:.c=.o) + +BARPROGES_SRC=../ybar_progress/src/bar_progress/bar_progress.c +BARPROGES_O=$(BARPROGES_SRC:.c=.o) + + +all: $(FTEST_O) + + +$(FTEST_O): $(FTEST_SRC) $(TOOLS_O) $(BARPROGES_O) + $(CC) -o $@ -c $< $(CFLAGS) + + +.PHONY: clean + +clean: + rm -f $(FTEST_O) + diff --git a/yftest/include/ftest/ftest.h b/yftest/include/ftest/ftest.h new file mode 100644 index 0000000..9797e9c --- /dev/null +++ b/yftest/include/ftest/ftest.h @@ -0,0 +1,800 @@ +#ifndef __TEST_C_H__ +#define __TEST_C_H__ + +#include +#include +#include +#include +//#include +#include +//#include +#include /* to have size of screen, for progress bar */ + +#include "tools_t/tools_t.h" +#include "bar_progress/bar_progress.h" + +#define DEFAULT_K "\033[0m" /*Resets the text to default color*/ +#define GREEN_K "\033[0;32m" +#define RED_K "\033[0;31m" +#define YELLOW_K "\033[0;33m" +#define BLUE_K "\033[0;34m" +#define NOTHING_K "" + +#define COLOR_SZ 6 + +#define Dknothing COLOR_SZ - 1 + +#define SZ_TAB_HK 8 + + +#ifdef HK + #define HK_EQ "[==========]" + #define HK_TR "[----------]" + #define HK_RN "[RUN ]" + #define HK_DN "[ DONE]" + #define HK_OK "[ OK ]" + #define HK_FL "[ FAILED ]" + #define HK_PS "[ PASSED ]" + #define HK_SK "[ SKIP ]" +#else + #define HK_EQ "==========" + #define HK_TR "----------" + #define HK_RN "====== RUN" + #define HK_DN "===== DONE" + #define HK_OK "======= OK" + #define HK_FL "===== FAIL" + #define HK_PS "===== PASS" + #define HK_SK "===== SKIP" +#endif /* HK */ + +/* + * compare symbol + */ +#define EQ == +#define LT < +#define GT > +#define LE <= +#define GE >= +#define NE != + + +extern FILE **f_ou_th; +extern bool unicolour; +extern bool ordered; +extern bool log_parallel; +extern char *savelog; + +extern char *colors_f[]; +extern char *tab_hk_f[]; + +extern int k_DEFAULT, k_GREEN, k_RED, k_YELLOW, k_BLUE, k_NOTHING; +extern int hk_EQ, hk_TR, hk_RN, hk_DN, hk_OK, hk_FL, hk_PS, hk_SK; +extern char *varHK_EQ, *varHK_TR, *varHK_RN, *varHK_DN, *varHK_OK, *varHK_FL, *varHK_PS, *varHK_SK; + +/* + * */ + +/* + * to execute once in print functions in the case of log_parallel (printing on screen and recording in file), we have to copy to stream -> string before copy it, + * so I have tried using fopen a file in memory location '/dev/shm' and remove it after use! + * /dev/shm/tmp_PTHREAD_SELF() but it prints twice sometimes, + * here a solution with open_memstream which is better + */ + +#define PRINTF( ...) \ + do{ \ + FILE *stream ;\ + size_t len;\ + char *buf ;\ + stream = open_memstream (&buf, &len);\ + if (stream == NULL) { fprintf(stderr," error open_memstream %s:%d:%s \n",__FILE__,__LINE__,__func__); exit(0); }\ + fprintf(stream, __VA_ARGS__); \ + fflush(stream);\ + if(is_parallel_nb){\ + long int id_thread=id_of_thread_executed();\ + if(log_parallel){\ + fprintf(F_OUT, "%s",buf);\ + if(id_thread >= 0){\ + fprintf(f_ou_th[id_thread], "%s",buf);\ + fflush(f_ou_th[id_thread]);\ + }\ + }\ + else{\ + if(id_thread >= 0){\ + fprintf(f_ou_th[id_thread], "%s",buf);\ + fflush(f_ou_th[id_thread]);\ + }\ + else {\ + fprintf(F_OUT, "%s",buf);\ + }\ + }\ + } \ + else{\ + if(savelog){\ + FILE *f_savelog = fopen(savelog,"a");\ + fprintf(f_savelog, "%s",buf);\ + fclose(f_savelog);\ + }\ + fprintf(F_OUT, "%s",buf);\ + }\ + fclose(stream);\ + free(buf);\ + }while(0) + + +#define LOG(...) PRINTF(__VA_ARGS__) + +#define PRINT_LOC(fmt, ...) \ + PRINTF( "%s:%d:%s(): " fmt, __FILE__, __LINE__, __func__, __VA_ARGS__) + + +#define PRINT_HK_C(color,hk,fmt,...)\ + PRINTF("%s%s%s" fmt, color,hk,colors_f[k_DEFAULT],__VA_ARGS__) + + + + +/* + * to skip the bloc test function + */ +#define SKIP(fmt,...)\ + PRINT_HK_C(colors_f[k_GREEN], HK_SK, fmt, ## __VA_ARGS__);\ + PRINT_LOC("%s\n\n" DEFAULT_K," Skiped "); return; + + + +struct func { + char *name; + void (*run)(void); + struct func *next; +}; + + +extern bool is_parallel_nb; + +long int id_of_thread_executed(void); + +void parse_options(int argc, char **argv); + +void run_all_tests(); +void execute_all(struct func *fun); +void append_func(void (*run)(void), char *name); + +char* extract_func_edited_TEST_from_exec_func_name(char* func_name); /* TEST_funcname___NUM -> TEST(funcname) */ + +/* +void run_some_tests(size_t cnt, ... ); +void run_all_tests_exept(size_t cnt, ... ); +void run_some_tests_ordered(size_t cnt, ... ); +*/ + +void run_all_tests_parallel(size_t parallel /*, int max_col*/); + +/* + * to launch test with different parameters without re-compile it + * it can print help if need! + * */ +void run_all_tests_args(int argc, char **argv); + +bool expected_true_f(bool val); +bool expected_false_f(bool val); + +bool expected_true_f_name(bool val, const char *name); +bool expected_false_f_name(bool val, const char *name); + +#define GEN_EXPECTED_OP_TYPE_FUNC(OP,type)\ + bool expected_##OP##_##type(type var1, type var2);\ + bool expected_##OP##_name_##type(type var1, type var2, const char *name); + + +/* + * ***** generate signature of expected functions EQ *********** + */ +GEN_EXPECTED_OP_TYPE_FUNC(EQ, TYPE_CHAR) +GEN_EXPECTED_OP_TYPE_FUNC(EQ, TYPE_U_CHAR) +GEN_EXPECTED_OP_TYPE_FUNC(EQ, TYPE_INT) +GEN_EXPECTED_OP_TYPE_FUNC(EQ, TYPE_U_INT) +GEN_EXPECTED_OP_TYPE_FUNC(EQ, TYPE_L_INT) +GEN_EXPECTED_OP_TYPE_FUNC(EQ, TYPE_U_L_INT) +GEN_EXPECTED_OP_TYPE_FUNC(EQ, TYPE_SIZE_T) +GEN_EXPECTED_OP_TYPE_FUNC(EQ, TYPE_FLOAT) +GEN_EXPECTED_OP_TYPE_FUNC(EQ, TYPE_DOUBLE) +GEN_EXPECTED_OP_TYPE_FUNC(EQ, TYPE_L_DOUBLE) +GEN_EXPECTED_OP_TYPE_FUNC(EQ, TYPE_STRING) +/* + * ******************** end EQ generation ************************ + */ + + +/* + * ***** generate signature of expected functions LT *********** + */ +GEN_EXPECTED_OP_TYPE_FUNC(LT, TYPE_CHAR) +GEN_EXPECTED_OP_TYPE_FUNC(LT, TYPE_U_CHAR) +GEN_EXPECTED_OP_TYPE_FUNC(LT, TYPE_INT) +GEN_EXPECTED_OP_TYPE_FUNC(LT, TYPE_U_INT) +GEN_EXPECTED_OP_TYPE_FUNC(LT, TYPE_L_INT) +GEN_EXPECTED_OP_TYPE_FUNC(LT, TYPE_U_L_INT) +GEN_EXPECTED_OP_TYPE_FUNC(LT, TYPE_SIZE_T) +GEN_EXPECTED_OP_TYPE_FUNC(LT, TYPE_FLOAT) +GEN_EXPECTED_OP_TYPE_FUNC(LT, TYPE_DOUBLE) +GEN_EXPECTED_OP_TYPE_FUNC(LT, TYPE_L_DOUBLE) +GEN_EXPECTED_OP_TYPE_FUNC(LT, TYPE_STRING) +/* + * ******************** end LT generation ************************ + */ + + +/* + * ***** generate signature of expected functions GT *********** + */ +GEN_EXPECTED_OP_TYPE_FUNC(GT, TYPE_CHAR) +GEN_EXPECTED_OP_TYPE_FUNC(GT, TYPE_U_CHAR) +GEN_EXPECTED_OP_TYPE_FUNC(GT, TYPE_INT) +GEN_EXPECTED_OP_TYPE_FUNC(GT, TYPE_U_INT) +GEN_EXPECTED_OP_TYPE_FUNC(GT, TYPE_L_INT) +GEN_EXPECTED_OP_TYPE_FUNC(GT, TYPE_U_L_INT) +GEN_EXPECTED_OP_TYPE_FUNC(GT, TYPE_SIZE_T) +GEN_EXPECTED_OP_TYPE_FUNC(GT, TYPE_FLOAT) +GEN_EXPECTED_OP_TYPE_FUNC(GT, TYPE_DOUBLE) +GEN_EXPECTED_OP_TYPE_FUNC(GT, TYPE_L_DOUBLE) +GEN_EXPECTED_OP_TYPE_FUNC(GT, TYPE_STRING) +/* + * ******************** end GT generation ************************ + */ + + +/* + * ***** generate signature of expected functions LE *********** + */ +GEN_EXPECTED_OP_TYPE_FUNC(LE, TYPE_CHAR) +GEN_EXPECTED_OP_TYPE_FUNC(LE, TYPE_U_CHAR) +GEN_EXPECTED_OP_TYPE_FUNC(LE, TYPE_INT) +GEN_EXPECTED_OP_TYPE_FUNC(LE, TYPE_U_INT) +GEN_EXPECTED_OP_TYPE_FUNC(LE, TYPE_L_INT) +GEN_EXPECTED_OP_TYPE_FUNC(LE, TYPE_U_L_INT) +GEN_EXPECTED_OP_TYPE_FUNC(LE, TYPE_SIZE_T) +GEN_EXPECTED_OP_TYPE_FUNC(LE, TYPE_FLOAT) +GEN_EXPECTED_OP_TYPE_FUNC(LE, TYPE_DOUBLE) +GEN_EXPECTED_OP_TYPE_FUNC(LE, TYPE_L_DOUBLE) +GEN_EXPECTED_OP_TYPE_FUNC(LE, TYPE_STRING) +/* + * ******************** end LE generation ************************ + */ + + +/* + * ***** generate signature of expected functions GE *********** + */ +GEN_EXPECTED_OP_TYPE_FUNC(GE, TYPE_CHAR) +GEN_EXPECTED_OP_TYPE_FUNC(GE, TYPE_U_CHAR) +GEN_EXPECTED_OP_TYPE_FUNC(GE, TYPE_INT) +GEN_EXPECTED_OP_TYPE_FUNC(GE, TYPE_U_INT) +GEN_EXPECTED_OP_TYPE_FUNC(GE, TYPE_L_INT) +GEN_EXPECTED_OP_TYPE_FUNC(GE, TYPE_U_L_INT) +GEN_EXPECTED_OP_TYPE_FUNC(GE, TYPE_SIZE_T) +GEN_EXPECTED_OP_TYPE_FUNC(GE, TYPE_FLOAT) +GEN_EXPECTED_OP_TYPE_FUNC(GE, TYPE_DOUBLE) +GEN_EXPECTED_OP_TYPE_FUNC(GE, TYPE_L_DOUBLE) +GEN_EXPECTED_OP_TYPE_FUNC(GE, TYPE_STRING) +/* + * ******************** end GE generation ************************ + */ + + +/* + * ***** generate signature of expected functions NE *********** + */ +GEN_EXPECTED_OP_TYPE_FUNC(NE, TYPE_CHAR) +GEN_EXPECTED_OP_TYPE_FUNC(NE, TYPE_U_CHAR) +GEN_EXPECTED_OP_TYPE_FUNC(NE, TYPE_INT) +GEN_EXPECTED_OP_TYPE_FUNC(NE, TYPE_U_INT) +GEN_EXPECTED_OP_TYPE_FUNC(NE, TYPE_L_INT) +GEN_EXPECTED_OP_TYPE_FUNC(NE, TYPE_U_L_INT) +GEN_EXPECTED_OP_TYPE_FUNC(NE, TYPE_SIZE_T) +GEN_EXPECTED_OP_TYPE_FUNC(NE, TYPE_FLOAT) +GEN_EXPECTED_OP_TYPE_FUNC(NE, TYPE_DOUBLE) +GEN_EXPECTED_OP_TYPE_FUNC(NE, TYPE_L_DOUBLE) +GEN_EXPECTED_OP_TYPE_FUNC(NE, TYPE_STRING) +/* + * ******************** end NE generation ************************ + */ + +/* + * only expect + */ +#define HANDLE_OP_EXPECT_NAME(OP,type,var1,var2,name_f,msg_call) \ +do{ \ + if(is_parallel_nb == 0){\ + if(expected_##OP##_##type(var1, var2)){ \ + PRINT_HK_C(colors_f[k_GREEN],HK_TR," 1 %s passed %s \n\n",name_f,msg_call); \ + } \ + else{ \ + /*PRINT_LOC("Failure\nExpected %s of these values:\n %s\n\tWhich is: %s\n %s\n\tWhich is: %s\n\n"\ + ,DESCRIPTION_##OP,#var1, type##_TO_STR(var1), #var2, type##_TO_STR(var2)); */ \ + PRINT_LOC("Failure\nExpected: (%s) %s (%s) :\n Value of %s: %s \n Value of %s: %s\n\n"\ + ,#var1,STRFY(OP),#var2,#var1, type##_TO_STR(var1), #var2, type##_TO_STR(var2)); \ + PRINT_HK_C(colors_f[k_RED],HK_TR," 1 %s failed %s \n",name_f,msg_call); \ + } \ + }else { \ + if(expected_##OP##_name_##type(var1, var2, name_f)){ \ + PRINT_HK_C(colors_f[k_GREEN],HK_TR," 1 %s passed %s \n\n",name_f,msg_call); \ + /*PRINT_HK_C(colors_f[k_GREEN],HK_TR," 1 test passed %s \n\n",name_f);*/ \ + } \ + else{ \ + /*PRINT_LOC("Failure\nExpected %s of these values:\n %s\n\tWhich is: %s\n %s\n\tWhich is: %s\n\n"\ + ,DESCRIPTION_##OP ,#var1, type##_TO_STR(var1), #var2, type##_TO_STR(var2));*/ \ + PRINT_LOC("Failure\nExpected: (%s) %s (%s) :\n Value of %s: %s \n Value of %s: %s\n\n"\ + ,#var1,STRFY(OP),#var2,#var1, type##_TO_STR(var1), #var2, type##_TO_STR(var2)); \ + PRINT_HK_C(colors_f[k_RED],HK_TR," 1 %s failed %s \n",name_f,msg_call); \ + } \ + }\ +}while(0); + +//#define EXPECT_OP_(OP,type,var1,var2) HANDLE_OP_EXPECT_(OP,type,var1,var2) + + /** + * old combined macros HANDLE_OP_EXPECT_ASSERT for ASSERT and EXPECT + * is_assert : 0 for EXPECT and 1 for ASSERT + */ +#define HANDLE_OP_EXPECT_ASSERT(OP,type,var1,var2,is_assert) \ +do{ \ + if(is_parallel_nb == 0){\ + if(expected_##OP##_##type(var1, var2)){ \ + PRINT_HK_C(colors_f[k_GREEN],HK_TR," 1 test passed from %s \n\n",__func__); \ + } \ + else{ \ + /*PRINT_LOC("Failure\nExpected %s of these values:\n %s\n\tWhich is: %s\n %s\n\tWhich is: %s\n\n"\ + ,DESCRIPTION_##OP,#var1, type##_TO_STR(var1), #var2, type##_TO_STR(var2)); */ \ + PRINT_LOC("Failure\nExpected: (%s) %s (%s) :\n Value of %s: %s \n Value of %s: %s\n\n"\ + ,#var1,STRFY(OP),#var2,#var1, type##_TO_STR(var1), #var2, type##_TO_STR(var2)); \ + PRINT_HK_C(colors_f[k_RED],HK_TR," 1 test failed from %s \n",__func__); \ + if(is_assert) return; \ + } \ + }else { \ + if(expected_##OP##_name_##type(var1, var2, __func__)){ \ + PRINT_HK_C(colors_f[k_GREEN],HK_TR," 1 test passed from %s \n\n",__func__); \ + } \ + else{ \ + /*PRINT_LOC("Failure\nExpected %s of these values:\n %s\n\tWhich is: %s\n %s\n\tWhich is: %s\n\n"\ + ,DESCRIPTION_##OP ,#var1, type##_TO_STR(var1), #var2, type##_TO_STR(var2));*/ \ + PRINT_LOC("Failure\nExpected: (%s) %s (%s) :\n Value of %s: %s \n Value of %s: %s\n\n"\ + ,#var1,STRFY(OP),#var2,#var1, type##_TO_STR(var1), #var2, type##_TO_STR(var2)); \ + PRINT_HK_C(colors_f[k_RED],HK_TR," 1 test failed from %s \n",__func__); \ + if(is_assert) return; \ + } \ + }\ +}while(0); + +// ******************************************************************************************************************* + + /** + * new HANDLE_OP_ EXPECT and ASSERT separated + */ +#define HANDLE_OP_EXPECT_(OP,type,var1,var2) \ +do{ \ + if(is_parallel_nb == 0){\ + if(expected_##OP##_##type(var1, var2)){ \ + PRINT_HK_C(colors_f[k_GREEN],HK_TR," 1 test passed from %s \n\n",__func__); \ + } \ + else{ \ + /*PRINT_LOC("Failure\nExpected %s of these values:\n %s\n\tWhich is: %s\n %s\n\tWhich is: %s\n\n"\ + ,DESCRIPTION_##OP,#var1, type##_TO_STR(var1), #var2, type##_TO_STR(var2)); */ \ + PRINT_LOC("Failure\nExpected: (%s) %s (%s) :\n Value of %s: %s \n Value of %s: %s\n\n"\ + ,#var1,STRFY(OP),#var2,#var1, type##_TO_STR(var1), #var2, type##_TO_STR(var2)); \ + PRINT_HK_C(colors_f[k_RED],HK_TR," 1 test failed from %s \n",__func__); \ + } \ + }else { \ + if(expected_##OP##_name_##type(var1, var2, __func__)){ \ + PRINT_HK_C(colors_f[k_GREEN],HK_TR," 1 test passed from %s \n\n",__func__); \ + } \ + else{ \ + /*PRINT_LOC("Failure\nExpected %s of these values:\n %s\n\tWhich is: %s\n %s\n\tWhich is: %s\n\n"\ + ,DESCRIPTION_##OP ,#var1, type##_TO_STR(var1), #var2, type##_TO_STR(var2));*/ \ + PRINT_LOC("Failure\nExpected: (%s) %s (%s) :\n Value of %s: %s \n Value of %s: %s\n\n"\ + ,#var1,STRFY(OP),#var2,#var1, type##_TO_STR(var1), #var2, type##_TO_STR(var2)); \ + PRINT_HK_C(colors_f[k_RED],HK_TR," 1 test failed from %s \n",__func__); \ + } \ + }\ +}while(0); + +#define HANDLE_OP_ASSERT_(OP,type,var1,var2) \ +do{ \ + if(is_parallel_nb == 0){\ + if(expected_##OP##_##type(var1, var2)){ \ + PRINT_HK_C(colors_f[k_GREEN],HK_TR," 1 test passed from %s \n\n",__func__); \ + } \ + else{ \ + /*PRINT_LOC("Failure\nExpected %s of these values:\n %s\n\tWhich is: %s\n %s\n\tWhich is: %s\n\n"\ + ,DESCRIPTION_##OP,#var1, type##_TO_STR(var1), #var2, type##_TO_STR(var2)); */ \ + PRINT_LOC("Failure\nExpected: (%s) %s (%s) :\n Value of %s: %s \n Value of %s: %s\n\n"\ + ,#var1,STRFY(OP),#var2,#var1, type##_TO_STR(var1), #var2, type##_TO_STR(var2)); \ + PRINT_HK_C(colors_f[k_RED],HK_TR," 1 test failed from %s \n",__func__); \ + return; \ + } \ + }else { \ + if(expected_##OP##_name_##type(var1, var2, __func__)){ \ + PRINT_HK_C(colors_f[k_GREEN],HK_TR," 1 test passed from %s \n\n",__func__); \ + } \ + else{ \ + /*PRINT_LOC("Failure\nExpected %s of these values:\n %s\n\tWhich is: %s\n %s\n\tWhich is: %s\n\n"\ + ,DESCRIPTION_##OP ,#var1, type##_TO_STR(var1), #var2, type##_TO_STR(var2));*/ \ + PRINT_LOC("Failure\nExpected: (%s) %s (%s) :\n Value of %s: %s \n Value of %s: %s\n\n"\ + ,#var1,STRFY(OP),#var2,#var1, type##_TO_STR(var1), #var2, type##_TO_STR(var2)); \ + PRINT_HK_C(colors_f[k_RED],HK_TR," 1 test failed from %s \n",__func__); \ + return; \ + } \ + }\ +}while(0); + + + +// ******************************************************************************************************************** + + +// *********************** begin EQ ************************ +// ============== EXPECT ============================== + +#define EXPECT_EQ_TYPE_CHAR(var1, var2) HANDLE_OP_EXPECT_(EQ, TYPE_CHAR,var1, var2) +#define EXPECT_EQ_TYPE_U_CHAR(var1, var2) HANDLE_OP_EXPECT_(EQ, TYPE_U_CHAR,var1, var2) +#define EXPECT_EQ_TYPE_INT(var1, var2) HANDLE_OP_EXPECT_(EQ, TYPE_INT,var1, var2) +#define EXPECT_EQ_TYPE_U_INT(var1, var2) HANDLE_OP_EXPECT_(EQ, TYPE_U_INT,var1, var2) +#define EXPECT_EQ_TYPE_L_INT(var1, var2) HANDLE_OP_EXPECT_(EQ, TYPE_L_INT,var1, var2) +#define EXPECT_EQ_TYPE_U_L_INT(var1, var2) HANDLE_OP_EXPECT_(EQ, TYPE_U_L_INT,var1, var2) +#define EXPECT_EQ_TYPE_SIZE_T(var1, var2) HANDLE_OP_EXPECT_(EQ, TYPE_SIZE_T,var1, var2) +#define EXPECT_EQ_TYPE_FLOAT(var1, var2) HANDLE_OP_EXPECT_(EQ, TYPE_FLOAT,var1, var2) +#define EXPECT_EQ_TYPE_DOUBLE(var1, var2) HANDLE_OP_EXPECT_(EQ, TYPE_DOUBLE,var1, var2) +#define EXPECT_EQ_TYPE_L_DOUBLE(var1, var2) HANDLE_OP_EXPECT_(EQ, TYPE_L_DOUBLE,var1, var2) +#define EXPECT_EQ_TYPE_STRING(var1, var2) HANDLE_OP_EXPECT_(EQ, TYPE_STRING,var1, var2) + +#define EXPECT_EQ(var1, var2) HANDLE_OP_EXPECT_(EQ, TYPE_L_INT,var1, var2) + + + +// ============== ASERT ===================== + +#define ASSERT_EQ_TYPE_CHAR(var1, var2) HANDLE_OP_ASSERT_(EQ, TYPE_CHAR,var1, var2) +#define ASSERT_EQ_TYPE_U_CHAR(var1, var2) HANDLE_OP_ASSERT_(EQ, TYPE_U_CHAR,var1, var2) +#define ASSERT_EQ_TYPE_INT(var1, var2) HANDLE_OP_ASSERT_(EQ, TYPE_INT,var1, var2) +#define ASSERT_EQ_TYPE_U_INT(var1, var2) HANDLE_OP_ASSERT_(EQ, TYPE_U_INT,var1, var2) +#define ASSERT_EQ_TYPE_L_INT(var1, var2) HANDLE_OP_ASSERT_(EQ, TYPE_L_INT,var1, var2) +#define ASSERT_EQ_TYPE_U_L_INT(var1, var2) HANDLE_OP_ASSERT_(EQ, TYPE_U_L_INT,var1, var2) +#define ASSERT_EQ_TYPE_SIZE_T(var1, var2) HANDLE_OP_ASSERT_(EQ, TYPE_SIZE_T,var1, var2) +#define ASSERT_EQ_TYPE_FLOAT(var1, var2) HANDLE_OP_ASSERT_(EQ, TYPE_FLOAT,var1, var2) +#define ASSERT_EQ_TYPE_DOUBLE(var1, var2) HANDLE_OP_ASSERT_(EQ, TYPE_DOUBLE,var1, var2) +#define ASSERT_EQ_TYPE_L_DOUBLE(var1, var2) HANDLE_OP_ASSERT_(EQ, TYPE_L_DOUBLE,var1, var2) +#define ASSERT_EQ_TYPE_STRING(var1, var2) HANDLE_OP_ASSERT_(EQ, TYPE_STRING,var1, var2) + +#define ASSERT_EQ(var1, var2) HANDLE_OP_ASSERT_(EQ, TYPE_L_INT,var1, var2) + +// ************************ end EQ ********************** + + +// *********************** begin LT ************************ +// ============== EXPECT ============================== + +#define EXPECT_LT_TYPE_CHAR(var1, var2) HANDLE_OP_EXPECT_(LT, TYPE_CHAR,var1, var2) +#define EXPECT_LT_TYPE_U_CHAR(var1, var2) HANDLE_OP_EXPECT_(LT, TYPE_U_CHAR,var1, var2) +#define EXPECT_LT_TYPE_INT(var1, var2) HANDLE_OP_EXPECT_(LT, TYPE_INT,var1, var2) +#define EXPECT_LT_TYPE_U_INT(var1, var2) HANDLE_OP_EXPECT_(LT, TYPE_U_INT,var1, var2) +#define EXPECT_LT_TYPE_L_INT(var1, var2) HANDLE_OP_EXPECT_(LT, TYPE_L_INT,var1, var2) +#define EXPECT_LT_TYPE_U_L_INT(var1, var2) HANDLE_OP_EXPECT_(LT, TYPE_U_L_INT,var1, var2) +#define EXPECT_LT_TYPE_SIZE_T(var1, var2) HANDLE_OP_EXPECT_(LT, TYPE_SIZE_T,var1, var2) +#define EXPECT_LT_TYPE_FLOAT(var1, var2) HANDLE_OP_EXPECT_(LT, TYPE_FLOAT,var1, var2) +#define EXPECT_LT_TYPE_DOUBLE(var1, var2) HANDLE_OP_EXPECT_(LT, TYPE_DOUBLE,var1, var2) +#define EXPECT_LT_TYPE_L_DOUBLE(var1, var2) HANDLE_OP_EXPECT_(LT, TYPE_L_DOUBLE,var1, var2) +#define EXPECT_LT_TYPE_STRING(var1, var2) HANDLE_OP_EXPECT_(LT, TYPE_STRING,var1, var2) + +#define EXPECT_LT(var1, var2) HANDLE_OP_EXPECT_(LT, TYPE_L_INT,var1, var2) + + +// ============== ASERT ===================== + +#define ASSERT_LT_TYPE_CHAR(var1, var2) HANDLE_OP_ASSERT_(LT, TYPE_CHAR,var1, var2) +#define ASSERT_LT_TYPE_U_CHAR(var1, var2) HANDLE_OP_ASSERT_(LT, TYPE_U_CHAR,var1, var2) +#define ASSERT_LT_TYPE_INT(var1, var2) HANDLE_OP_ASSERT_(LT, TYPE_INT,var1, var2) +#define ASSERT_LT_TYPE_U_INT(var1, var2) HANDLE_OP_ASSERT_(LT, TYPE_U_INT,var1, var2) +#define ASSERT_LT_TYPE_L_INT(var1, var2) HANDLE_OP_ASSERT_(LT, TYPE_L_INT,var1, var2) +#define ASSERT_LT_TYPE_U_L_INT(var1, var2) HANDLE_OP_ASSERT_(LT, TYPE_U_L_INT,var1, var2) +#define ASSERT_LT_TYPE_SIZE_T(var1, var2) HANDLE_OP_ASSERT_(LT, TYPE_SIZE_T,var1, var2) +#define ASSERT_LT_TYPE_FLOAT(var1, var2) HANDLE_OP_ASSERT_(LT, TYPE_FLOAT,var1, var2) +#define ASSERT_LT_TYPE_DOUBLE(var1, var2) HANDLE_OP_ASSERT_(LT, TYPE_DOUBLE,var1, var2) +#define ASSERT_LT_TYPE_L_DOUBLE(var1, var2) HANDLE_OP_ASSERT_(LT, TYPE_L_DOUBLE,var1, var2) +#define ASSERT_LT_TYPE_STRING(var1, var2) HANDLE_OP_ASSERT_(LT, TYPE_STRING,var1, var2) + +#define ASSERT_LT(var1, var2) HANDLE_OP_ASSERT_(LT, TYPE_L_INT,var1, var2) + +// ************************ end LT ********************** + + +// *********************** begin GT ************************ +// ============== EXPECT ============================== + +#define EXPECT_GT_TYPE_CHAR(var1, var2) HANDLE_OP_EXPECT_(GT, TYPE_CHAR,var1, var2) +#define EXPECT_GT_TYPE_U_CHAR(var1, var2) HANDLE_OP_EXPECT_(GT, TYPE_U_CHAR,var1, var2) +#define EXPECT_GT_TYPE_INT(var1, var2) HANDLE_OP_EXPECT_(GT, TYPE_INT,var1, var2) +#define EXPECT_GT_TYPE_U_INT(var1, var2) HANDLE_OP_EXPECT_(GT, TYPE_U_INT,var1, var2) +#define EXPECT_GT_TYPE_L_INT(var1, var2) HANDLE_OP_EXPECT_(GT, TYPE_L_INT,var1, var2) +#define EXPECT_GT_TYPE_U_L_INT(var1, var2) HANDLE_OP_EXPECT_(GT, TYPE_U_L_INT,var1, var2) +#define EXPECT_GT_TYPE_SIZE_T(var1, var2) HANDLE_OP_EXPECT_(GT, TYPE_SIZE_T,var1, var2) +#define EXPECT_GT_TYPE_FLOAT(var1, var2) HANDLE_OP_EXPECT_(GT, TYPE_FLOAT,var1, var2) +#define EXPECT_GT_TYPE_DOUBLE(var1, var2) HANDLE_OP_EXPECT_(GT, TYPE_DOUBLE,var1, var2) +#define EXPECT_GT_TYPE_L_DOUBLE(var1, var2) HANDLE_OP_EXPECT_(GT, TYPE_L_DOUBLE,var1, var2) +#define EXPECT_GT_TYPE_STRING(var1, var2) HANDLE_OP_EXPECT_(GT, TYPE_STRING,var1, var2) + +#define EXPECT_GT(var1, var2) HANDLE_OP_EXPECT_(GT, TYPE_L_INT,var1, var2) + + + +// ============== ASERT ===================== + +#define ASSERT_GT_TYPE_CHAR(var1, var2) HANDLE_OP_ASSERT_(GT, TYPE_CHAR,var1, var2) +#define ASSERT_GT_TYPE_U_CHAR(var1, var2) HANDLE_OP_ASSERT_(GT, TYPE_U_CHAR,var1, var2) +#define ASSERT_GT_TYPE_INT(var1, var2) HANDLE_OP_ASSERT_(GT, TYPE_INT,var1, var2) +#define ASSERT_GT_TYPE_U_INT(var1, var2) HANDLE_OP_ASSERT_(GT, TYPE_U_INT,var1, var2) +#define ASSERT_GT_TYPE_L_INT(var1, var2) HANDLE_OP_ASSERT_(GT, TYPE_L_INT,var1, var2) +#define ASSERT_GT_TYPE_U_L_INT(var1, var2) HANDLE_OP_ASSERT_(GT, TYPE_U_L_INT,var1, var2) +#define ASSERT_GT_TYPE_SIZE_T(var1, var2) HANDLE_OP_ASSERT_(GT, TYPE_SIZE_T,var1, var2) +#define ASSERT_GT_TYPE_FLOAT(var1, var2) HANDLE_OP_ASSERT_(GT, TYPE_FLOAT,var1, var2) +#define ASSERT_GT_TYPE_DOUBLE(var1, var2) HANDLE_OP_ASSERT_(GT, TYPE_DOUBLE,var1, var2) +#define ASSERT_GT_TYPE_L_DOUBLE(var1, var2) HANDLE_OP_ASSERT_(GT, TYPE_L_DOUBLE,var1, var2) +#define ASSERT_GT_TYPE_STRING(var1, var2) HANDLE_OP_ASSERT_(GT, TYPE_STRING,var1, var2) + +#define ASSERT_GT(var1, var2) HANDLE_OP_ASSERT_(GT, TYPE_L_INT,var1, var2) + +// ************************ end GT ********************** + + +// *********************** begin LE ************************ +// ============== EXPECT ============================== + +#define EXPECT_LE_TYPE_CHAR(var1, var2) HANDLE_OP_EXPECT_(LE, TYPE_CHAR,var1, var2) +#define EXPECT_LE_TYPE_U_CHAR(var1, var2) HANDLE_OP_EXPECT_(LE, TYPE_U_CHAR,var1, var2) +#define EXPECT_LE_TYPE_INT(var1, var2) HANDLE_OP_EXPECT_(LE, TYPE_INT,var1, var2) +#define EXPECT_LE_TYPE_U_INT(var1, var2) HANDLE_OP_EXPECT_(LE, TYPE_U_INT,var1, var2) +#define EXPECT_LE_TYPE_L_INT(var1, var2) HANDLE_OP_EXPECT_(LE, TYPE_L_INT,var1, var2) +#define EXPECT_LE_TYPE_U_L_INT(var1, var2) HANDLE_OP_EXPECT_(LE, TYPE_U_L_INT,var1, var2) +#define EXPECT_LE_TYPE_SIZE_T(var1, var2) HANDLE_OP_EXPECT_(LE, TYPE_SIZE_T,var1, var2) +#define EXPECT_LE_TYPE_FLOAT(var1, var2) HANDLE_OP_EXPECT_(LE, TYPE_FLOAT,var1, var2) +#define EXPECT_LE_TYPE_DOUBLE(var1, var2) HANDLE_OP_EXPECT_(LE, TYPE_DOUBLE,var1, var2) +#define EXPECT_LE_TYPE_L_DOUBLE(var1, var2) HANDLE_OP_EXPECT_(LE, TYPE_L_DOUBLE,var1, var2) +#define EXPECT_LE_TYPE_STRING(var1, var2) HANDLE_OP_EXPECT_(LE, TYPE_STRING,var1, var2) + +#define EXPECT_LE(var1, var2) HANDLE_OP_EXPECT_(LE, TYPE_L_INT,var1, var2) + + + +// ============== ASERT ===================== + +#define ASSERT_LE_TYPE_CHAR(var1, var2) HANDLE_OP_ASSERT_(LE, TYPE_CHAR,var1, var2) +#define ASSERT_LE_TYPE_U_CHAR(var1, var2) HANDLE_OP_ASSERT_(LE, TYPE_U_CHAR,var1, var2) +#define ASSERT_LE_TYPE_INT(var1, var2) HANDLE_OP_ASSERT_(LE, TYPE_INT,var1, var2) +#define ASSERT_LE_TYPE_U_INT(var1, var2) HANDLE_OP_ASSERT_(LE, TYPE_U_INT,var1, var2) +#define ASSERT_LE_TYPE_L_INT(var1, var2) HANDLE_OP_ASSERT_(LE, TYPE_L_INT,var1, var2) +#define ASSERT_LE_TYPE_U_L_INT(var1, var2) HANDLE_OP_ASSERT_(LE, TYPE_U_L_INT,var1, var2) +#define ASSERT_LE_TYPE_SIZE_T(var1, var2) HANDLE_OP_ASSERT_(LE, TYPE_SIZE_T,var1, var2) +#define ASSERT_LE_TYPE_FLOAT(var1, var2) HANDLE_OP_ASSERT_(LE, TYPE_FLOAT,var1, var2) +#define ASSERT_LE_TYPE_DOUBLE(var1, var2) HANDLE_OP_ASSERT_(LE, TYPE_DOUBLE,var1, var2) +#define ASSERT_LE_TYPE_L_DOUBLE(var1, var2) HANDLE_OP_ASSERT_(LE, TYPE_L_DOUBLE,var1, var2) +#define ASSERT_LE_TYPE_STRING(var1, var2) HANDLE_OP_ASSERT_(LE, TYPE_STRING,var1, var2) + +#define ASSERT_LE(var1, var2) HANDLE_OP_ASSERT_(LE, TYPE_L_INT,var1, var2) + +// ************************ end LE ********************** + + +// *********************** begin GE ************************ +// ============== EXPECT ============================== + +#define EXPECT_GE_TYPE_CHAR(var1, var2) HANDLE_OP_EXPECT_(GE, TYPE_CHAR,var1, var2) +#define EXPECT_GE_TYPE_U_CHAR(var1, var2) HANDLE_OP_EXPECT_(GE, TYPE_U_CHAR,var1, var2) +#define EXPECT_GE_TYPE_INT(var1, var2) HANDLE_OP_EXPECT_(GE, TYPE_INT,var1, var2) +#define EXPECT_GE_TYPE_U_INT(var1, var2) HANDLE_OP_EXPECT_(GE, TYPE_U_INT,var1, var2) +#define EXPECT_GE_TYPE_L_INT(var1, var2) HANDLE_OP_EXPECT_(GE, TYPE_L_INT,var1, var2) +#define EXPECT_GE_TYPE_U_L_INT(var1, var2) HANDLE_OP_EXPECT_(GE, TYPE_U_L_INT,var1, var2) +#define EXPECT_GE_TYPE_SIZE_T(var1, var2) HANDLE_OP_EXPECT_(GE, TYPE_SIZE_T,var1, var2) +#define EXPECT_GE_TYPE_FLOAT(var1, var2) HANDLE_OP_EXPECT_(GE, TYPE_FLOAT,var1, var2) +#define EXPECT_GE_TYPE_DOUBLE(var1, var2) HANDLE_OP_EXPECT_(GE, TYPE_DOUBLE,var1, var2) +#define EXPECT_GE_TYPE_L_DOUBLE(var1, var2) HANDLE_OP_EXPECT_(GE, TYPE_L_DOUBLE,var1, var2) +#define EXPECT_GE_TYPE_STRING(var1, var2) HANDLE_OP_EXPECT_(GE, TYPE_STRING,var1, var2) + +#define EXPECT_GE(var1, var2) HANDLE_OP_EXPECT_(GE, TYPE_L_INT,var1, var2) + + + +// ============== ASERT ===================== + +#define ASSERT_GE_TYPE_CHAR(var1, var2) HANDLE_OP_ASSERT_(GE, TYPE_CHAR,var1, var2) +#define ASSERT_GE_TYPE_U_CHAR(var1, var2) HANDLE_OP_ASSERT_(GE, TYPE_U_CHAR,var1, var2) +#define ASSERT_GE_TYPE_INT(var1, var2) HANDLE_OP_ASSERT_(GE, TYPE_INT,var1, var2) +#define ASSERT_GE_TYPE_U_INT(var1, var2) HANDLE_OP_ASSERT_(GE, TYPE_U_INT,var1, var2) +#define ASSERT_GE_TYPE_L_INT(var1, var2) HANDLE_OP_ASSERT_(GE, TYPE_L_INT,var1, var2) +#define ASSERT_GE_TYPE_U_L_INT(var1, var2) HANDLE_OP_ASSERT_(GE, TYPE_U_L_INT,var1, var2) +#define ASSERT_GE_TYPE_SIZE_T(var1, var2) HANDLE_OP_ASSERT_(GE, TYPE_SIZE_T,var1, var2) +#define ASSERT_GE_TYPE_FLOAT(var1, var2) HANDLE_OP_ASSERT_(GE, TYPE_FLOAT,var1, var2) +#define ASSERT_GE_TYPE_DOUBLE(var1, var2) HANDLE_OP_ASSERT_(GE, TYPE_DOUBLE,var1, var2) +#define ASSERT_GE_TYPE_L_DOUBLE(var1, var2) HANDLE_OP_ASSERT_(GE, TYPE_L_DOUBLE,var1, var2) +#define ASSERT_GE_TYPE_STRING(var1, var2) HANDLE_OP_ASSERT_(GE, TYPE_STRING,var1, var2) + +#define ASSERT_GE(var1, var2) HANDLE_OP_ASSERT_(GE, TYPE_L_INT,var1, var2) + +// ************************ end GE ********************** + + +// *********************** begin NE ************************ +// ============== EXPECT ============================== + +#define EXPECT_NE_TYPE_CHAR(var1, var2) HANDLE_OP_EXPECT_(NE, TYPE_CHAR,var1, var2) +#define EXPECT_NE_TYPE_U_CHAR(var1, var2) HANDLE_OP_EXPECT_(NE, TYPE_U_CHAR,var1, var2) +#define EXPECT_NE_TYPE_INT(var1, var2) HANDLE_OP_EXPECT_(NE, TYPE_INT,var1, var2) +#define EXPECT_NE_TYPE_U_INT(var1, var2) HANDLE_OP_EXPECT_(NE, TYPE_U_INT,var1, var2) +#define EXPECT_NE_TYPE_L_INT(var1, var2) HANDLE_OP_EXPECT_(NE, TYPE_L_INT,var1, var2) +#define EXPECT_NE_TYPE_U_L_INT(var1, var2) HANDLE_OP_EXPECT_(NE, TYPE_U_L_INT,var1, var2) +#define EXPECT_NE_TYPE_SIZE_T(var1, var2) HANDLE_OP_EXPECT_(NE, TYPE_SIZE_T,var1, var2) +#define EXPECT_NE_TYPE_FLOAT(var1, var2) HANDLE_OP_EXPECT_(NE, TYPE_FLOAT,var1, var2) +#define EXPECT_NE_TYPE_DOUBLE(var1, var2) HANDLE_OP_EXPECT_(NE, TYPE_DOUBLE,var1, var2) +#define EXPECT_NE_TYPE_L_DOUBLE(var1, var2) HANDLE_OP_EXPECT_(NE, TYPE_L_DOUBLE,var1, var2) +#define EXPECT_NE_TYPE_STRING(var1, var2) HANDLE_OP_EXPECT_(NE, TYPE_STRING,var1, var2) + +#define EXPECT_NE(var1, var2) HANDLE_OP_EXPECT_(NE, TYPE_L_INT,var1, var2) + + + +// ============== ASERT ===================== + +#define ASSERT_NE_TYPE_CHAR(var1, var2) HANDLE_OP_ASSERT_(NE, TYPE_CHAR,var1, var2) +#define ASSERT_NE_TYPE_U_CHAR(var1, var2) HANDLE_OP_ASSERT_(NE, TYPE_U_CHAR,var1, var2) +#define ASSERT_NE_TYPE_INT(var1, var2) HANDLE_OP_ASSERT_(NE, TYPE_INT,var1, var2) +#define ASSERT_NE_TYPE_U_INT(var1, var2) HANDLE_OP_ASSERT_(NE, TYPE_U_INT,var1, var2) +#define ASSERT_NE_TYPE_L_INT(var1, var2) HANDLE_OP_ASSERT_(NE, TYPE_L_INT,var1, var2) +#define ASSERT_NE_TYPE_U_L_INT(var1, var2) HANDLE_OP_ASSERT_(NE, TYPE_U_L_INT,var1, var2) +#define ASSERT_NE_TYPE_SIZE_T(var1, var2) HANDLE_OP_ASSERT_(NE, TYPE_SIZE_T,var1, var2) +#define ASSERT_NE_TYPE_FLOAT(var1, var2) HANDLE_OP_ASSERT_(NE, TYPE_FLOAT,var1, var2) +#define ASSERT_NE_TYPE_DOUBLE(var1, var2) HANDLE_OP_ASSERT_(NE, TYPE_DOUBLE,var1, var2) +#define ASSERT_NE_TYPE_L_DOUBLE(var1, var2) HANDLE_OP_ASSERT_(NE, TYPE_L_DOUBLE,var1, var2) +#define ASSERT_NE_TYPE_STRING(var1, var2) HANDLE_OP_ASSERT_(NE, TYPE_STRING,var1, var2) + +#define ASSERT_NE(var1, var2) HANDLE_OP_ASSERT_(NE, TYPE_L_INT,var1, var2) + +// ************************ end NE ********************** + +/* + * ============== bool =================== + * bellow old combined EXPECT and ASSERT macros + */ + +#define HANDLE_EXPECT_NOT_EXPECT_ASSERT(expect,not_expect,var1,is_assert) \ +do{ \ + if(is_parallel_nb==0){\ + if(expected_##expect##_f(var1)){ \ + PRINT_HK_C(colors_f[k_GREEN],HK_TR," 1 test passed from %s \n\n",__func__); \ + } \ + else{ \ + PRINT_LOC("Failure\nValue of: %s\nActual: %s\nExpected: %s\n\n", #var1, #not_expect, #expect);\ + PRINT_HK_C(colors_f[k_RED],HK_TR," 1 test failed from %s \n",__func__); \ + if(is_assert) return; \ + } \ + }\ + else{\ + if(expected_##expect##_f_name(var1, __func__)){ \ + PRINT_HK_C(colors_f[k_GREEN],HK_TR," 1 test passed from %s \n\n",__func__); \ + } \ + else{ \ + PRINT_LOC("Failure\nValue of: %s\nActual: %s\nExpected: %s\n\n", #var1, #not_expect, #expect);\ + PRINT_HK_C(colors_f[k_RED],HK_TR," 1 test failed from %s \n",__func__); \ + if(is_assert) return; \ + } \ + }\ +}while(0); + +// ******************************************************************************************************* +/* + * new macro HANDEL ASSERT and EXPECT separated + */ +#define HANDLE_EXPECT_NOT_EXPECT_(expect,not_expect,var1) \ +do{ \ + if(is_parallel_nb==0){ \ + if(expected_##expect##_f(var1)){ \ + PRINT_HK_C(colors_f[k_GREEN],HK_TR," 1 test passed from %s \n\n",__func__); \ + } \ + else{ \ + PRINT_LOC("Failure\nValue of: %s\nActual: %s\nExpected: %s\n", #var1, #not_expect, #expect); \ + PRINT_HK_C(colors_f[k_RED],HK_TR," 1 test failed from %s \n\n",__func__); \ + } \ + } \ + else{ \ + size_t id_thread=id_of_thread_executed(); \ + if(expected_##expect##_f_name(var1, __func__)){ \ + PRINT_HK_C(colors_f[k_GREEN],HK_TR," 1 test passed from %s, on thread[%ld]\n\n",__func__,id_thread); \ + } \ + else{ \ + PRINT_LOC("Failure\nValue of: %s\nActual: %s\nExpected: %s\n", #var1, #not_expect, #expect); \ + PRINT_HK_C(colors_f[k_RED],HK_TR," 1 test failed from %s, on thread[%ld]\n\n",__func__,id_thread); \ + } \ + } \ +}while(0); + + +#define HANDLE_ASSERT_EXPECT_NOT_EXPECT_(expect,not_expect,var1) \ +do{ \ + if(is_parallel_nb==0){ \ + if(expected_##expect##_f(var1)){ \ + PRINT_HK_C(colors_f[k_GREEN],HK_TR," 1 test passed from %s \n\n",__func__); \ + } \ + else{ \ + PRINT_LOC("Failure\nValue of: %s\nActual: %s\nExpected: %s\n", #var1, #not_expect, #expect); \ + PRINT_HK_C(colors_f[k_RED],HK_TR," 1 test failed from %s \n\n",__func__); \ + return; \ + } \ + }\ + else{\ + size_t id_thread=id_of_thread_executed(); \ + if(expected_##expect##_f_name(var1, __func__)){ \ + PRINT_HK_C(colors_f[k_GREEN],HK_TR," 1 test passed from %s, on thread[%ld]\n\n",__func__,id_thread); \ + } \ + else{ \ + PRINT_LOC("Failure\nValue of: %s\nActual: %s\nExpected: %s\n\n", #var1, #not_expect, #expect);\ + PRINT_HK_C(colors_f[k_RED],HK_TR," 1 test failed from %s, on thread[%ld]\n\n",__func__, id_thread); \ + return; \ + } \ + }\ +}while(0); + + +// ******************************************************************************************************* +#define EXPECT_TRUE(var1) HANDLE_EXPECT_NOT_EXPECT_(true, false, var1) +#define EXPECT_FALSE(var1) HANDLE_EXPECT_NOT_EXPECT_(false, true, var1) + +#define ASSERT_TRUE(var1) HANDLE_ASSERT_EXPECT_NOT_EXPECT_(true, false, var1) +#define ASSERT_FALSE(var1) HANDLE_ASSERT_EXPECT_NOT_EXPECT_(false, true, var1) + + +//******************************************************************************** + +/* +#define EXPECT_TRUE(var1) HANDLE_EXPECT_NOT_EXPECT_ASSERT(true, false, var1, 0) +#define EXPECT_FALSE(var1) HANDLE_EXPECT_NOT_EXPECT_ASSERT(false, true, var1, 0) + +#define ASSERT_TRUE(var1) HANDLE_EXPECT_NOT_EXPECT_ASSERT(true, false, var1, 1) +#define ASSERT_FALSE(var1) HANDLE_EXPECT_NOT_EXPECT_ASSERT(false, true, var1, 1) +*/ + + +#define CONCAT(x,y) x ## y +#define STRFY(x) # x + +//#define test_label test + +#define FTEST_(count, name_f) \ + void CONCAT(test_##name_f##____,count)(void); \ + __attribute__((constructor)) \ + void CONCAT(append_test_##name_f,count)(void){ \ + append_func(CONCAT(test_##name_f##____,count),STRFY(name_f test count)); \ + } \ + void CONCAT(test_##name_f##____,count)(void) + +#define FTEST__(count, name_f) \ + void CONCAT(TEST_##name_f##____,count)(void); \ + __attribute__((constructor)) \ + void CONCAT(append_test_##name_f,count)(void){ \ + append_func(CONCAT(TEST_##name_f##____,count),STRFY (TEST(name_f): test N° count| ) ); \ + } \ + void CONCAT(TEST_##name_f##____,count)(void) + + +/*#define TEST(name_f)\ + FTEST_(__COUNTER__,name_f) +*/ + +#define TEST(name_f) \ + FTEST__(__COUNTER__,name_f) + +/* +#define ASSERT_TRUE(val)\ + if(expected_true_f(val,#val,__func__) == false) {error_print("%s\n\n","Failure"); return;} + +#define ASSERT_FALSE(val)\ + if(expected_false_f(val,#val,__func__) == false) {error_print("%s\n\n","Failure"); return;} +*/ + +#endif /* __TEST_C_H__ */ diff --git a/src/ftest/ftest.c b/yftest/src/ftest/ftest.c similarity index 99% rename from src/ftest/ftest.c rename to yftest/src/ftest/ftest.c index b645017..2ada557 100644 --- a/src/ftest/ftest.c +++ b/yftest/src/ftest/ftest.c @@ -783,9 +783,10 @@ void bar_progress_test_(){ void* run_progress_tests(void *max_d) { - int max_col = 80; //*(int*)max_d; + /*int max_col = 80;*/ //*(int*)max_d; //progress_test_(max_col); bar_progress_test_(); + return (void*)0; } @@ -1123,6 +1124,7 @@ run_parallel_tests(void *id) head_parallel_run(&start_t, id_th); execute_test_parallel(id_th); stat_end_parallel_run(count_fail_thread[id_th]+count_pass_thread[id_th], start_t, id_th); + return (void*)0; } /* diff --git a/ytools_t/Makefile b/ytools_t/Makefile new file mode 100644 index 0000000..9259c90 --- /dev/null +++ b/ytools_t/Makefile @@ -0,0 +1,17 @@ + + +TOOLS_SRC=src/tools_t/tools_t.c +TOOLS_O=$(TOOLS_SRC:.c=.o) + + +all: $(TOOLS_O) + +$(TOOLS_O): $(TOOLS_SRC) + $(CC) -o $@ -c $< $(CFLAGS) + + +.PHONY: clean + +clean: + rm -f $(TOOLS_O) + diff --git a/ytools_t/include/tools_t/tools_t.h b/ytools_t/include/tools_t/tools_t.h new file mode 100644 index 0000000..10607a4 --- /dev/null +++ b/ytools_t/include/tools_t/tools_t.h @@ -0,0 +1,119 @@ +#ifndef __TOOLS_T_C_H__ +#define __TOOLS_T_C_H__ + +#include +#include +#include +#include +#include + +// to define DEBUG in gcc cli do: gcc -D DEBUG=1 or 0 if need! +#ifndef DEBUG + #define DEBUG 0 +#endif + + +// F_OUT file (stream) to log +#ifndef F_OUT + #define F_OUT stdout +#endif +// F_ERR file (stream) to log +#ifndef F_ERR + #define F_ERR stderr +#endif + + + +/* +#ifndef SECOND + #define SECOND 0 +#endif +#ifndef NANOSECOND + #define NANOSECOND 0 +#endif + +double diff_timespec_seconds(struct timespec time_stop, struct timespec time_start); +double diff_timespec_milliseconds(struct timespec time_stop, struct timespec time_start); +long diff_timespec_nanoseconds(struct timespec time_stop, struct timespec time_start); +*/ + +void gotoxy(int x, int y); +//void get_cursor_position(int *col, int *rows); + + +#define debug_print(fmt, ...) \ + do { if (DEBUG) fprintf(stderr, "%s:%d:%s(): " fmt, __FILE__, \ + __LINE__, __func__, __VA_ARGS__); } while (0) + +#define PRINT_DEBUG(fmt, ...) \ + do { if (DEBUG) fprintf(F_ERR, "%s:%d:%s(): " fmt, __FILE__, \ + __LINE__, __func__, __VA_ARGS__); } while (0) + + +#define error_print(fmt, ...) \ + fprintf(stderr, "%s:%d:%s(): " fmt, __FILE__, \ + __LINE__, __func__, __VA_ARGS__); + +#define PRINT_ERROR(fmt, ...) \ + fprintf(F_ERR, "%s:%d:%s(): " fmt, __FILE__, \ + __LINE__, __func__, __VA_ARGS__); + +#define PRINT_LOC_T(fmt, ...) \ + fprintf(F_OUT, "%s:%d:%s(): " fmt, __FILE__, \ + __LINE__, __func__, __VA_ARGS__); + + + +#define TYPE_CHAR char +#define TYPE_U_CHAR unsigned char +#define TYPE_INT int +#define TYPE_U_INT unsigned int +#define TYPE_L_INT long int +#define TYPE_U_L_INT unsigned long int +#define TYPE_SIZE_T size_t +#define TYPE_FLOAT float +#define TYPE_DOUBLE double +#define TYPE_L_DOUBLE long double +#define TYPE_STRING char* + +#define FREE(x) { free((x)); (x) = NULL;} + +#define FOREACH(array, size, function)\ + for(size_t _ind = 0; _ind < size; ++_ind) function(array[_ind]); + + +#define GENERATE_ALL(type)\ + int COMPARE_N_##type(const void *,const void*);\ + void COPY_ARRAY_##type(type* dst, const type* src, size_t size);\ + type MAX_ARRAY_##type(const type *array, size_t size);\ + size_t ARG_MAX_ARRAY_##type(const type *array, size_t size);\ + type MIN_ARRAY_##type(const type *array, size_t size);\ + size_t ARG_MIN_ARRAY_##type(const type *array, size_t size);\ + TYPE_STRING type##_TO_STR(type var);\ + + +GENERATE_ALL(TYPE_CHAR) +GENERATE_ALL(TYPE_U_CHAR) +GENERATE_ALL(TYPE_INT) +GENERATE_ALL(TYPE_U_INT) +GENERATE_ALL(TYPE_L_INT) +GENERATE_ALL(TYPE_U_L_INT) +GENERATE_ALL(TYPE_SIZE_T) +GENERATE_ALL(TYPE_FLOAT) +GENERATE_ALL(TYPE_DOUBLE) +GENERATE_ALL(TYPE_L_DOUBLE) +GENERATE_ALL(TYPE_STRING) + + +/* + * time calucl + */ +double diff_timespec_seconds(struct timespec time_stop, struct timespec time_start); + +double diff_timespec_milliseconds(struct timespec time_stop, struct timespec time_start); + +long diff_timespec_nanoseconds(struct timespec time_stop, struct timespec time_start); + + +#endif /*__TOOLS_T_C_H__*/ + diff --git a/src/tools_t/tools_t.c b/ytools_t/src/tools_t/tools_t.c similarity index 100% rename from src/tools_t/tools_t.c rename to ytools_t/src/tools_t/tools_t.c diff --git a/ytools_t/src/tools_t/tools_t.h b/ytools_t/src/tools_t/tools_t.h new file mode 100644 index 0000000..10607a4 --- /dev/null +++ b/ytools_t/src/tools_t/tools_t.h @@ -0,0 +1,119 @@ +#ifndef __TOOLS_T_C_H__ +#define __TOOLS_T_C_H__ + +#include +#include +#include +#include +#include + +// to define DEBUG in gcc cli do: gcc -D DEBUG=1 or 0 if need! +#ifndef DEBUG + #define DEBUG 0 +#endif + + +// F_OUT file (stream) to log +#ifndef F_OUT + #define F_OUT stdout +#endif +// F_ERR file (stream) to log +#ifndef F_ERR + #define F_ERR stderr +#endif + + + +/* +#ifndef SECOND + #define SECOND 0 +#endif +#ifndef NANOSECOND + #define NANOSECOND 0 +#endif + +double diff_timespec_seconds(struct timespec time_stop, struct timespec time_start); +double diff_timespec_milliseconds(struct timespec time_stop, struct timespec time_start); +long diff_timespec_nanoseconds(struct timespec time_stop, struct timespec time_start); +*/ + +void gotoxy(int x, int y); +//void get_cursor_position(int *col, int *rows); + + +#define debug_print(fmt, ...) \ + do { if (DEBUG) fprintf(stderr, "%s:%d:%s(): " fmt, __FILE__, \ + __LINE__, __func__, __VA_ARGS__); } while (0) + +#define PRINT_DEBUG(fmt, ...) \ + do { if (DEBUG) fprintf(F_ERR, "%s:%d:%s(): " fmt, __FILE__, \ + __LINE__, __func__, __VA_ARGS__); } while (0) + + +#define error_print(fmt, ...) \ + fprintf(stderr, "%s:%d:%s(): " fmt, __FILE__, \ + __LINE__, __func__, __VA_ARGS__); + +#define PRINT_ERROR(fmt, ...) \ + fprintf(F_ERR, "%s:%d:%s(): " fmt, __FILE__, \ + __LINE__, __func__, __VA_ARGS__); + +#define PRINT_LOC_T(fmt, ...) \ + fprintf(F_OUT, "%s:%d:%s(): " fmt, __FILE__, \ + __LINE__, __func__, __VA_ARGS__); + + + +#define TYPE_CHAR char +#define TYPE_U_CHAR unsigned char +#define TYPE_INT int +#define TYPE_U_INT unsigned int +#define TYPE_L_INT long int +#define TYPE_U_L_INT unsigned long int +#define TYPE_SIZE_T size_t +#define TYPE_FLOAT float +#define TYPE_DOUBLE double +#define TYPE_L_DOUBLE long double +#define TYPE_STRING char* + +#define FREE(x) { free((x)); (x) = NULL;} + +#define FOREACH(array, size, function)\ + for(size_t _ind = 0; _ind < size; ++_ind) function(array[_ind]); + + +#define GENERATE_ALL(type)\ + int COMPARE_N_##type(const void *,const void*);\ + void COPY_ARRAY_##type(type* dst, const type* src, size_t size);\ + type MAX_ARRAY_##type(const type *array, size_t size);\ + size_t ARG_MAX_ARRAY_##type(const type *array, size_t size);\ + type MIN_ARRAY_##type(const type *array, size_t size);\ + size_t ARG_MIN_ARRAY_##type(const type *array, size_t size);\ + TYPE_STRING type##_TO_STR(type var);\ + + +GENERATE_ALL(TYPE_CHAR) +GENERATE_ALL(TYPE_U_CHAR) +GENERATE_ALL(TYPE_INT) +GENERATE_ALL(TYPE_U_INT) +GENERATE_ALL(TYPE_L_INT) +GENERATE_ALL(TYPE_U_L_INT) +GENERATE_ALL(TYPE_SIZE_T) +GENERATE_ALL(TYPE_FLOAT) +GENERATE_ALL(TYPE_DOUBLE) +GENERATE_ALL(TYPE_L_DOUBLE) +GENERATE_ALL(TYPE_STRING) + + +/* + * time calucl + */ +double diff_timespec_seconds(struct timespec time_stop, struct timespec time_start); + +double diff_timespec_milliseconds(struct timespec time_stop, struct timespec time_start); + +long diff_timespec_nanoseconds(struct timespec time_stop, struct timespec time_start); + + +#endif /*__TOOLS_T_C_H__*/ +