diff options
| author | hachem <im@hachem.wtf> | 2026-08-30 04:30:33 +0200 |
|---|---|---|
| committer | hachem <im@hachem.wtf> | 2026-08-30 04:30:33 +0200 |
| commit | 2b5a8a428cbbdda8ef0efa7b2c77c100b8dbfa0c (patch) | |
| tree | ca0ed5be92ae59c9609ff4eaa3f86ce2f3cb4b03 | |
| parent | affa20ab497911353babc9ed6c580c8a12b2bf15 (diff) | |
test: add lexer testing
| -rw-r--r-- | premake5.lua | 34 | ||||
| -rw-r--r-- | tests/lexer_test.c | 63 | ||||
| -rw-r--r-- | tests/main.c | 13 | ||||
| -rw-r--r-- | tests/test.h | 21 | ||||
| -rw-r--r-- | tests/tests.h | 5 |
5 files changed, 136 insertions, 0 deletions
diff --git a/premake5.lua b/premake5.lua index 710bf1c..d8f2aec 100644 --- a/premake5.lua +++ b/premake5.lua @@ -90,3 +90,37 @@ project "hdass" filter "configurations:dist" defines "HDASS_DIST" filter {} + +project "tests" + kind "ConsoleApp" + language "C" + cdialect "C17" + + setup_c_target() + + files { + "src/**.h", + "src/**.c", + "tests/**.h", + "tests/**.c", + } + + removefiles "src/main.c" + + includedirs { + "src", + "tests", + } + + filter { "system:macosx or system:linux" } + buildoptions { + "-Wall", + "-Wextra", + "-Werror", + "-pedantic", + } + filter {} + + filter "system:windows" + systemversion "latest" + filter {} diff --git a/tests/lexer_test.c b/tests/lexer_test.c new file mode 100644 index 0000000..c5c9f14 --- /dev/null +++ b/tests/lexer_test.c @@ -0,0 +1,63 @@ +#include <string.h> +#include <stdbool.h> + +#include "lexer/lexer.h" +#include "tests.h" + +static bool token_matches(struct Token token, enum TokenType type, const char* text) +{ + size_t length = strlen(text); + return token.type == type + && token.length == length + && memcmp(token.start, text, length) == 0; +} + +static void test_identifiers_and_integers(struct TestContext* context) +{ + struct Lexer lexer = create_lexer("rax 42"); + check(context, token_matches(scan_token(&lexer), TOKEN_IDENTIFIER, "rax")); + check(context, token_matches(scan_token(&lexer), TOKEN_INTEGER, "42")); + check(context, scan_token(&lexer).type == TOKEN_EOF); +} + +static void test_operators(struct TestContext* context) +{ + struct Lexer lexer = create_lexer("= == += != /"); + check(context, scan_token(&lexer).type == TOKEN_EQUAL); + check(context, scan_token(&lexer).type == TOKEN_EQUAL_EQUAL); + check(context, scan_token(&lexer).type == TOKEN_PLUS_EQUAL); + check(context, scan_token(&lexer).type == TOKEN_BANG_EQUAL); + check(context, scan_token(&lexer).type == TOKEN_SLASH); +} + +static void test_literals(struct TestContext* context) +{ + struct Lexer lexer = create_lexer("\"hi\\n\" '0'"); + check(context, token_matches(scan_token(&lexer), TOKEN_STRING, "\"hi\\n\"")); + check(context, token_matches(scan_token(&lexer), TOKEN_CHAR, "'0'")); +} + +static void test_keywords(struct TestContext* context) +{ + struct Lexer lexer = create_lexer("const proc mainly"); + check(context, scan_token(&lexer).type == TOKEN_CONST); + check(context, scan_token(&lexer).type == TOKEN_PROC); + check(context, scan_token(&lexer).type == TOKEN_IDENTIFIER); +} + +static void test_line_counting(struct TestContext* context) +{ + struct Lexer lexer = create_lexer("a\nb\nc"); + check(context, scan_token(&lexer).line == 1); + check(context, scan_token(&lexer).line == 2); + check(context, scan_token(&lexer).line == 3); +} + +void run_lexer_tests(struct TestContext* context) +{ + test_identifiers_and_integers(context); + test_operators(context); + test_literals(context); + test_keywords(context); + test_line_counting(context); +} diff --git a/tests/main.c b/tests/main.c new file mode 100644 index 0000000..49ac448 --- /dev/null +++ b/tests/main.c @@ -0,0 +1,13 @@ +#include <stdio.h> + +#include "tests.h" + +int main(void) +{ + struct TestContext context = { 0, 0 }; + + run_lexer_tests(&context); + + printf("\n%d checks, %d failure(s)\n", context.checks, context.failures); + return context.failures == 0 ? 0 : 1; +} diff --git a/tests/test.h b/tests/test.h new file mode 100644 index 0000000..c5e2e73 --- /dev/null +++ b/tests/test.h @@ -0,0 +1,21 @@ +#pragma once + +#include <stdio.h> + +struct TestContext +{ + int checks; + int failures; +}; + +#define check(context, condition) \ + do \ + { \ + (context)->checks += 1; \ + if (!(condition)) \ + { \ + (context)->failures += 1; \ + printf(" FAIL %s:%d: %s\n", __FILE__, __LINE__, #condition); \ + } \ + } \ + while (0) diff --git a/tests/tests.h b/tests/tests.h new file mode 100644 index 0000000..4ed1348 --- /dev/null +++ b/tests/tests.h @@ -0,0 +1,5 @@ +#pragma once + +#include "test.h" + +void run_lexer_tests(struct TestContext* context); |
