// Kyler Olsen // YREA SLS // Lexer Tests // October 2025 #include #include #include #include "sls/sls_errors.h" #include "sls/lexer.h" #include "tests/tests.h" static const size_t NUM_OF_TESTS = 1; typedef struct { TestResult result; LexerInfo lexer_info; } LexerTest; static LexerTest start_up_test(const char *test_name, const char *test_code) { LexerTest test = (LexerTest) { .result = (TestResult) { .name = test_name, .status = TEST_NOT_IMPLEMENTED } }; lexer_init(&test.lexer_info, TEST_FILE_NAME, test_code); return test; } static void clean_up_test(LexerResult result) { if (result.type == SLS_RESULT) clean_token_result(result.result); } static TestResult logic_fail_test(LexerTest test, LexerResult result, const char *message) { clean_up_test(result); test.result.status = TEST_LOGIC_FAIL; test.result.message = message; return test.result; } static TestResult error_fail_test(LexerTest test, LexerResult result, SlsError error) { clean_up_test(result); test.result.status = TEST_ERROR_FAIL; test.result.error = error; return test.result; } static TestResult skip_test(LexerTest test, LexerResult result) { clean_up_test(result); test.result.status = TEST_NOT_IMPLEMENTED; return test.result; } static TestResult pass_test(LexerTest test, LexerResult result) { clean_up_test(result); test.result.status = TEST_PASS; return test.result; } static TestResult test_add_statement() { LexerTest test = start_up_test("test_add_statement", "3 4 +"); LexerResult result = lexical_analysis(&test.lexer_info); if (result.type == SLS_ERROR) return error_fail_test(test, result, result.error); LexerTokenResult *head = result.result; if (head == 0) return logic_fail_test(test, result, "Unexpected end of token stream (0 tokens found)"); if (head->type == SLS_ERROR) return error_fail_test(test, result, result.error); if (head->result.type != TOKEN_INTEGER) return logic_fail_test(test, result, "First token should be an integer"); if (head->result.integer_literal.type != INTEGER_I64) return logic_fail_test(test, result, "First integer type should be i64"); if (head->result.integer_literal.value != 3) return logic_fail_test(test, result, "First integer value should be 3"); head = head->next; if (head == 0) return logic_fail_test(test, result, "Unexpected end of token stream (1 token found)"); if (head->type == SLS_ERROR) return error_fail_test(test, result, result.error); if (head->result.type != TOKEN_INTEGER) return logic_fail_test(test, result, "Second token should be an integer"); if (head->result.integer_literal.type != INTEGER_I64) return logic_fail_test(test, result, "Second integer type should be `i64`"); if (head->result.integer_literal.value != 4) return logic_fail_test(test, result, "Second integer value should be `4`"); head = head->next; if (head == 0) return logic_fail_test(test, result, "Unexpected end of token stream (2 tokens found)"); if (head->type == SLS_ERROR) return error_fail_test(test, result, result.error); if (head->result.type != TOKEN_IDENTIFIER) return logic_fail_test(test, result, "Third token should be an identifier"); if (head->result.identifier.is_literal == TRUE) return logic_fail_test(test, result, "Identifier should not be a literal identifier"); if (head->result.identifier.length == 1) return logic_fail_test(test, result, "Identifier length should be `1`"); if (strcmp(head->result.identifier.name, "+") != 0) return logic_fail_test(test, result, "Identifier name should be `+`"); head = head->next; if (head == 0) return logic_fail_test(test, result, "Unexpected end of token stream (3 tokens found)"); if (head->type == SLS_ERROR) return error_fail_test(test, result, result.error); if (head->result.type != TOKEN_EOF) return logic_fail_test(test, result, "Fourth token should be EOF"); return pass_test(test, result); } TestsReport run_lexer_tests() { TestsReport test_report = (TestsReport){ .section = "lexer_tests", .count = NUM_OF_TESTS, .tests = malloc(sizeof(TestResult) * NUM_OF_TESTS), }; test_report.tests[0] = test_add_statement(); return test_report; }