128 lines
4.4 KiB
C
128 lines
4.4 KiB
C
// Kyler Olsen
|
|
// YREA SLS
|
|
// Lexer Tests
|
|
// October 2025
|
|
|
|
#include <stdlib.h>
|
|
#include <stdint.h>
|
|
#include <string.h>
|
|
|
|
#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;
|
|
}
|