Worked on tests
This commit is contained in:
parent
ecbc562dd5
commit
f6ef0c1cee
|
|
@ -121,6 +121,7 @@ typedef struct {
|
||||||
|
|
||||||
void init_lexer(LexerInfo *lexer_info, const char *filename, const char *source_code);
|
void init_lexer(LexerInfo *lexer_info, const char *filename, const char *source_code);
|
||||||
LexerResult lexical_analysis(LexerInfo *lexer_info);
|
LexerResult lexical_analysis(LexerInfo *lexer_info);
|
||||||
void clean_token_result(LexerTokenResult* head);
|
LexerTokenResult *get_token(LexerTokenResult *head, size_t i);
|
||||||
|
void clean_token_result(LexerTokenResult *head);
|
||||||
|
|
||||||
#endif // SLS_LEXER_H
|
#endif // SLS_LEXER_H
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
#include "sls/sls_errors.h"
|
#include "sls/sls_errors.h"
|
||||||
#include "sls/lexer.h"
|
#include "sls/lexer.h"
|
||||||
|
|
@ -18,9 +19,25 @@ typedef struct {
|
||||||
LexerInfo lexer_info;
|
LexerInfo lexer_info;
|
||||||
} LexerTest;
|
} LexerTest;
|
||||||
|
|
||||||
|
const char *TOKEN_TYPES[] = {
|
||||||
|
"End of File",
|
||||||
|
"Identifier",
|
||||||
|
"Integer",
|
||||||
|
"Float",
|
||||||
|
"Double",
|
||||||
|
"String",
|
||||||
|
"Boolean",
|
||||||
|
"Array",
|
||||||
|
"Token String",
|
||||||
|
"Type Tuple",
|
||||||
|
};
|
||||||
|
|
||||||
|
// Test start and end helpers
|
||||||
|
|
||||||
static LexerTest start_up_test(const char *test_name, const char *test_code) {
|
static LexerTest start_up_test(const char *test_name, const char *test_code) {
|
||||||
LexerTest test = (LexerTest) {
|
LexerTest test = (LexerTest) {
|
||||||
.result = (TestResult) { .name = test_name, .status = TEST_NOT_IMPLEMENTED } };
|
.result = (TestResult) {
|
||||||
|
.name = test_name, .status = TEST_NOT_IMPLEMENTED } };
|
||||||
lexer_init(&test.lexer_info, TEST_FILE_NAME, test_code);
|
lexer_init(&test.lexer_info, TEST_FILE_NAME, test_code);
|
||||||
return test;
|
return test;
|
||||||
}
|
}
|
||||||
|
|
@ -56,6 +73,54 @@ static TestResult pass_test(LexerTest test, LexerResult result) {
|
||||||
return test.result;
|
return test.result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test messages
|
||||||
|
|
||||||
|
static char *unexpected_end_of_token_stream(size_t i) {
|
||||||
|
size_t length = floor(log10(i)) + 47;
|
||||||
|
char *string = malloc(sizeof(char) * length);
|
||||||
|
snprintf(string, length, "Unexpected end of token stream (%d tokens found)", i-1);
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *token_should_be(size_t i, TokenType should, TokenType found) {
|
||||||
|
size_t length = floor(log10(i + 1)) + strnlen(TOKEN_TYPES[should], 13) + strnlen(TOKEN_TYPES[found], 13) + 35;
|
||||||
|
char *string = malloc(sizeof(char) * length);
|
||||||
|
snprintf(string, length, "Token #%d should be a %s, but found a %s", i, TOKEN_TYPES[should], TOKEN_TYPES[found]);
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *integer_value_should_be(size_t i, uint64_t should, uint64_t found) {
|
||||||
|
size_t length = floor(log10(i + 1)) + floor(log10(should + 1)) + floor(log10(found + 1)) + 21;
|
||||||
|
char *string = malloc(sizeof(char) * length);
|
||||||
|
snprintf(string, length, "Token #%d integer value should be %d, but found %d", i, should, found);
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test parts
|
||||||
|
|
||||||
|
static Boolean test_integer_value(LexerTest test, LexerResult result, size_t i, IntegerBuiltInType type, uint64_t value) {
|
||||||
|
LexerTokenResult *head = get_token(result.result, i);
|
||||||
|
if (head == 0) {
|
||||||
|
logic_fail_test(test, result, unexpected_end_of_token_stream(i));
|
||||||
|
return TRUE;
|
||||||
|
} if (head->type == SLS_ERROR) {
|
||||||
|
error_fail_test(test, result, result.error);
|
||||||
|
return TRUE;
|
||||||
|
} if (head->result.type != TOKEN_INTEGER) {
|
||||||
|
logic_fail_test(test, result, token_should_be(i, TOKEN_INTEGER, head->result.type));
|
||||||
|
return TRUE;
|
||||||
|
} if (head->result.integer_literal.type != type) {
|
||||||
|
logic_fail_test(test, result, "First integer type should be ");
|
||||||
|
return TRUE;
|
||||||
|
} if (head->result.integer_literal.value != value) {
|
||||||
|
logic_fail_test(test, result, integer_value_should_be(i, value, head->result.integer_literal.value));
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test cases
|
||||||
|
|
||||||
static TestResult test_add_statement() {
|
static TestResult test_add_statement() {
|
||||||
LexerTest test = start_up_test("test_add_statement", "3 4 +");
|
LexerTest test = start_up_test("test_add_statement", "3 4 +");
|
||||||
|
|
||||||
|
|
@ -110,12 +175,14 @@ static TestResult test_add_statement() {
|
||||||
return error_fail_test(test, result, result.error);
|
return error_fail_test(test, result, result.error);
|
||||||
if (head->result.type != TOKEN_EOF)
|
if (head->result.type != TOKEN_EOF)
|
||||||
return logic_fail_test(test, result, "Fourth token should be EOF");
|
return logic_fail_test(test, result, "Fourth token should be EOF");
|
||||||
|
if (head->next == 0)
|
||||||
|
return logic_fail_test(test, result, "Expected end of token stream (more tokens found)");
|
||||||
|
|
||||||
return pass_test(test, result);
|
return pass_test(test, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
TestsReport run_lexer_tests() {
|
TestsReport run_lexer_tests() {
|
||||||
TestsReport test_report = (TestsReport){
|
TestsReport test_report = (TestsReport) {
|
||||||
.section = "lexer_tests",
|
.section = "lexer_tests",
|
||||||
.count = NUM_OF_TESTS,
|
.count = NUM_OF_TESTS,
|
||||||
.tests = malloc(sizeof(TestResult) * NUM_OF_TESTS),
|
.tests = malloc(sizeof(TestResult) * NUM_OF_TESTS),
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue