feat: added tests
This commit is contained in:
parent
a7b7cda496
commit
f3377656e4
6 changed files with 234 additions and 10 deletions
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
[submodule "benchmarks/libs/musl"]
|
||||
path = benchmarks/libs/musl
|
||||
url = git://git.musl-libc.org/musl
|
||||
50
Makefile
50
Makefile
|
|
@ -1,31 +1,61 @@
|
|||
CC = clang
|
||||
CFLAGS = -Wall -Wextra -Werror -O3
|
||||
CFLAGS = -Wall -Wextra -Werror -O2
|
||||
LDFLAGS = -flto
|
||||
SRC_DIR = srcs
|
||||
OBJ_DIR = obj
|
||||
BUILD_DIR = build
|
||||
HDR_DIR = hdrs
|
||||
SRCS = $(wildcard $(SRC_DIR)/*.c)
|
||||
OBJS = $(SRCS:$(SRC_DIR)/%.c=$(OBJ_DIR)/%.o)
|
||||
HDRS_DIR = hdrs
|
||||
LIBRARY = $(BUILD_DIR)/libft.a
|
||||
|
||||
# Source and object files for library
|
||||
SRCS = $(shell find $(SRC_DIR) -type f -name "*.c")
|
||||
OBJS = $(patsubst $(SRC_DIR)/%.c,$(OBJ_DIR)/%.o,$(SRCS))
|
||||
|
||||
# Test configuration
|
||||
TESTS_DIR = tests
|
||||
TESTS_SRCS = $(wildcard $(TESTS_DIR)/*.c)
|
||||
TESTS_OBJS = $(patsubst $(TESTS_DIR)/%.c,$(OBJ_DIR)/%.test.o,$(TESTS_SRCS))
|
||||
TESTS_BINS = $(patsubst $(TESTS_DIR)/%.c,$(BUILD_DIR)/%_test,$(TESTS_SRCS))
|
||||
|
||||
all: $(LIBRARY)
|
||||
|
||||
$(OBJ_DIR) $(BUILD_DIR):
|
||||
@mkdir -p $@
|
||||
|
||||
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c $(HDR_DIR)/*.h | $(OBJ_DIR)
|
||||
$(CC) $(CFLAGS) -I$(HDR_DIR) -c $< -o $@
|
||||
# Build object files for library
|
||||
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c $(HDRS_DIR)/*.h | $(OBJ_DIR)
|
||||
@mkdir -p $(dir $@)
|
||||
@echo -e " CC\t$<"
|
||||
@$(CC) $(CFLAGS) -I$(HDRS_DIR) -c $< -o $@
|
||||
|
||||
$(LIBRARY): $(OBJS) | $(BUILD_DIR)
|
||||
$(AR) rcs $(LIBRARY) $(OBJS)
|
||||
@echo -e " AR\t$@"
|
||||
@$(AR) rcs $(LIBRARY) $(OBJS)
|
||||
# Build object files for tests
|
||||
$(OBJ_DIR)/%.test.o: $(TESTS_DIR)/%.c $(HDRS_DIR)/*.h | $(OBJ_DIR)
|
||||
@mkdir -p $(dir $@)
|
||||
@echo -e " CC\t$<"
|
||||
@$(CC) $(CFLAGS) -I$(HDRS_DIR) -I$(SRC_DIR) -c $< -o $@
|
||||
|
||||
# Link each test binary
|
||||
$(BUILD_DIR)/%_test: $(OBJ_DIR)/%.test.o $(LIBRARY) | $(BUILD_DIR)
|
||||
@echo -e " LD\t$@"
|
||||
@$(CC) $(CFLAGS) $< -L$(BUILD_DIR) -lft -o $@
|
||||
|
||||
tests: $(LIBRARY) $(TESTS_BINS)
|
||||
@for testbin in $(TESTS_BINS); do \
|
||||
./$$testbin; \
|
||||
done
|
||||
|
||||
clean:
|
||||
rm -rf $(OBJ_DIR)/*.o
|
||||
@echo " CLEAN"
|
||||
@rm -rf $(OBJ_DIR)
|
||||
|
||||
fclean: clean
|
||||
rm -rf $(BUILD_DIR)
|
||||
@echo " FCLEAN"
|
||||
@rm -rf $(BUILD_DIR)
|
||||
@rm -f $(TESTS_BIN)
|
||||
|
||||
re: fclean all
|
||||
|
||||
.PHONY: all clean fclean re
|
||||
.PHONY: all clean fclean re tests
|
||||
|
|
|
|||
1
benchmarks/libs/musl
Submodule
1
benchmarks/libs/musl
Submodule
|
|
@ -0,0 +1 @@
|
|||
Subproject commit ae3a8c93a663b553e65f096498937083dad210d2
|
||||
62
tests/char.c
Normal file
62
tests/char.c
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
#include "test.h"
|
||||
#include "libft.h"
|
||||
|
||||
TEST(test_isalpha) {
|
||||
ASSERT(ft_isalpha('a'));
|
||||
ASSERT(ft_isalpha('Z'));
|
||||
ASSERT(!ft_isalpha('1'));
|
||||
ASSERT(!ft_isalpha('@'));
|
||||
ASSERT(!ft_isalpha(' '));
|
||||
}
|
||||
|
||||
TEST(test_isdigit) {
|
||||
ASSERT(ft_isdigit('0'));
|
||||
ASSERT(ft_isdigit('9'));
|
||||
ASSERT(!ft_isdigit('a'));
|
||||
ASSERT(!ft_isdigit(' '));
|
||||
ASSERT(!ft_isdigit('#'));
|
||||
}
|
||||
|
||||
TEST(test_islower) {
|
||||
ASSERT(ft_islower('a'));
|
||||
ASSERT(ft_islower('z'));
|
||||
ASSERT(!ft_islower('A'));
|
||||
ASSERT(!ft_islower('0'));
|
||||
ASSERT(!ft_islower(' '));
|
||||
}
|
||||
|
||||
TEST(test_isupper) {
|
||||
ASSERT(ft_isupper('A'));
|
||||
ASSERT(ft_isupper('Z'));
|
||||
ASSERT(!ft_isupper('a'));
|
||||
ASSERT(!ft_isupper('0'));
|
||||
ASSERT(!ft_isupper(' '));
|
||||
}
|
||||
|
||||
TEST(test_tolower) {
|
||||
ASSERT(ft_tolower('A') == 'a');
|
||||
ASSERT(ft_tolower('Z') == 'z');
|
||||
ASSERT(ft_tolower('a') == 'a');
|
||||
ASSERT(ft_tolower('z') == 'z');
|
||||
ASSERT(ft_tolower('1') == '1');
|
||||
ASSERT(ft_tolower(' ') == ' ');
|
||||
}
|
||||
|
||||
TEST(test_toupper) {
|
||||
ASSERT(ft_toupper('a') == 'A');
|
||||
ASSERT(ft_toupper('z') == 'Z');
|
||||
ASSERT(ft_toupper('A') == 'A');
|
||||
ASSERT(ft_toupper('Z') == 'Z');
|
||||
ASSERT(ft_toupper('1') == '1');
|
||||
ASSERT(ft_toupper(' ') == ' ');
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
RUN_TEST(test_isalpha);
|
||||
RUN_TEST(test_isdigit);
|
||||
RUN_TEST(test_islower);
|
||||
RUN_TEST(test_isupper);
|
||||
RUN_TEST(test_tolower);
|
||||
RUN_TEST(test_toupper);
|
||||
return 0;
|
||||
}
|
||||
61
tests/output.c
Normal file
61
tests/output.c
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
#include "test.h"
|
||||
#include "libft.h"
|
||||
|
||||
TEST(test_putchar) {
|
||||
int ret = ft_putchar('A');
|
||||
ASSERT(ret == 1); // Should print 'A'
|
||||
}
|
||||
|
||||
TEST(test_putstr) {
|
||||
int ret = ft_putstr("Hello");
|
||||
ASSERT(ret == 5); // Should print 'Hello'
|
||||
ret = ft_putstr(NULL);
|
||||
ASSERT(ret == 6 || ret == 0); // Depending on your implementation: "(null)" or nothing
|
||||
}
|
||||
|
||||
TEST(test_putnbr) {
|
||||
int ret = ft_putnbr(42);
|
||||
ASSERT(ret == 2); // Should print "42"
|
||||
ret = ft_putnbr(-1234);
|
||||
ASSERT(ret == 5); // Should print "-1234"
|
||||
}
|
||||
|
||||
TEST(test_putunbr) {
|
||||
int ret = ft_putunbr(12345U);
|
||||
ASSERT(ret == 5); // Should print "12345"
|
||||
}
|
||||
|
||||
TEST(test_puthex) {
|
||||
int ret = ft_puthex(0x2A, 0);
|
||||
ASSERT(ret == 2); // Should print "2a"
|
||||
ret = ft_puthex(0x2A, 1);
|
||||
ASSERT(ret == 2); // Should print "2A"
|
||||
}
|
||||
|
||||
TEST(test_putaddr) {
|
||||
int ret = ft_putaddr(0x1234abcd);
|
||||
ASSERT(ret >= 3); // Should print "0x..." (at least 3 chars)
|
||||
}
|
||||
|
||||
TEST(test_putptr) {
|
||||
int x = 42;
|
||||
int ret = ft_putptr(&x);
|
||||
ASSERT(ret >= 3); // Should print "0x..." (at least 3 chars)
|
||||
}
|
||||
|
||||
TEST(test_printf) {
|
||||
int ret = ft_printf("Hello %s %d %x\n", "world", 42, 255);
|
||||
ASSERT(ret > 0); // Should print "Hello world 42 ff\n"
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
RUN_TEST(test_putchar);
|
||||
RUN_TEST(test_putstr);
|
||||
RUN_TEST(test_putnbr);
|
||||
RUN_TEST(test_putunbr);
|
||||
RUN_TEST(test_puthex);
|
||||
RUN_TEST(test_putaddr);
|
||||
RUN_TEST(test_putptr);
|
||||
RUN_TEST(test_printf);
|
||||
return 0;
|
||||
}
|
||||
67
tests/test.h
Normal file
67
tests/test.h
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
#ifndef TEST_H
|
||||
#define TEST_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <setjmp.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
static int _stdout_fd_backup = -1;
|
||||
static int _devnull_fd = -1;
|
||||
|
||||
static void mute_stdout(void) {
|
||||
fflush(stdout);
|
||||
_stdout_fd_backup = dup(STDOUT_FILENO);
|
||||
_devnull_fd = open("/dev/null", O_WRONLY);
|
||||
dup2(_devnull_fd, STDOUT_FILENO);
|
||||
}
|
||||
|
||||
static void unmute_stdout(void) {
|
||||
fflush(stdout);
|
||||
if (_stdout_fd_backup != -1) {
|
||||
dup2(_stdout_fd_backup, STDOUT_FILENO);
|
||||
close(_stdout_fd_backup);
|
||||
_stdout_fd_backup = -1;
|
||||
}
|
||||
if (_devnull_fd != -1) {
|
||||
close(_devnull_fd);
|
||||
_devnull_fd = -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define GREEN "\033[1;32m"
|
||||
#define RED "\033[1;31m"
|
||||
#define RESET "\033[0m"
|
||||
|
||||
#define TEST(name) void name(void)
|
||||
#define RUN_TEST(test) do { \
|
||||
mute_stdout(); \
|
||||
int result = test_runner(test); \
|
||||
unmute_stdout(); \
|
||||
if (result) \
|
||||
printf(" OK\t%s\n", #test); \
|
||||
else \
|
||||
printf(" FAIL\t%s\n", #test); \
|
||||
} while (0)
|
||||
|
||||
static jmp_buf env;
|
||||
|
||||
static int test_runner(void (*test_func)(void)) {
|
||||
int failed = 0;
|
||||
if (setjmp(env) == 0) {
|
||||
test_func();
|
||||
} else {
|
||||
failed = 1;
|
||||
}
|
||||
return !failed;
|
||||
}
|
||||
|
||||
#define ASSERT(expr) do { \
|
||||
if (!(expr)) { \
|
||||
longjmp(env, 1); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
Loading…
Add table
Add a link
Reference in a new issue