Refactor tests
This commit is contained in:
@@ -1,10 +1,12 @@
|
||||
#include "test.h"
|
||||
|
||||
#include "util.h"
|
||||
#include "parser.h"
|
||||
|
||||
#include <setjmp.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "util.h"
|
||||
#include "parser.h"
|
||||
|
||||
static jmp_buf s_testJmp;
|
||||
static const char* s_failMsg;
|
||||
@@ -12,6 +14,9 @@ static char* s_logOutput = NULL;
|
||||
static const char* s_currentTestName = NULL;
|
||||
static char* s_testSource = NULL;
|
||||
|
||||
static Module* s_currentModule = NULL;
|
||||
static TokenStream* s_currentTokenStream = NULL;
|
||||
|
||||
void fail(const char* msg) {
|
||||
s_failMsg = msg;
|
||||
longjmp(s_testJmp, 1);
|
||||
@@ -56,9 +61,9 @@ void assert_str(const char* expected, const char* actual, const char* msg) {
|
||||
}
|
||||
}
|
||||
|
||||
TokenStream* tokenstream_get_test(void) {
|
||||
TokenStream* test_get_tokenstream(void) {
|
||||
if (s_currentTokenStream == NULL) {
|
||||
char* filepath = NULL;
|
||||
TokenStream* ts = NULL;
|
||||
|
||||
filepath = format_string("v0/tests/%s.c2", s_currentTestName);
|
||||
if (!filepath) {
|
||||
@@ -73,15 +78,17 @@ TokenStream* tokenstream_get_test(void) {
|
||||
free(filepath);
|
||||
return NULL;
|
||||
}
|
||||
ts = tokenstream_open(filepath, s_testSource);
|
||||
s_currentTokenStream = tokenstream_open(filepath, s_testSource);
|
||||
free(filepath);
|
||||
return ts;
|
||||
}
|
||||
return s_currentTokenStream;
|
||||
}
|
||||
|
||||
Module* test_get_ast(void) {
|
||||
TokenStream* ts = tokenstream_get_test();
|
||||
if (!ts) return NULL;
|
||||
return parser_parse(ts);
|
||||
if (s_currentModule == NULL) {
|
||||
s_currentModule = parser_parse(test_get_tokenstream());
|
||||
}
|
||||
return s_currentModule;
|
||||
}
|
||||
|
||||
void assert_log(const char* expected, const char* msg) {
|
||||
@@ -240,6 +247,15 @@ int main(int argc, char** argv) {
|
||||
printf(" [FAIL]: %s\n", s_failMsg ? s_failMsg : "");
|
||||
failedTests[failedCount++] = s_tests[i].name;
|
||||
}
|
||||
|
||||
if (s_currentModule) {
|
||||
parser_free(s_currentModule);
|
||||
s_currentModule = NULL;
|
||||
}
|
||||
if (s_currentTokenStream) {
|
||||
tokenstream_close(s_currentTokenStream);
|
||||
s_currentTokenStream = NULL;
|
||||
}
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
|
||||
+7
-38
@@ -4,58 +4,34 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
static void test_parser_module_name(void) {
|
||||
TokenStream* ts = tokenstream_open("test.c", "module my_module;");
|
||||
Module* m = parser_parse(ts);
|
||||
Module* m = test_get_ast();
|
||||
|
||||
assert_not_null(m, "expected module to be parsed");
|
||||
assert_str("my_module", m->name, "expected name 'my_module'");
|
||||
parser_free(m);
|
||||
tokenstream_close(ts);
|
||||
}
|
||||
|
||||
static void test_parser_bad_module_name(void) {
|
||||
TokenStream* ts = tokenstream_get_test();
|
||||
Module* m = parser_parse(ts);
|
||||
|
||||
test_get_ast();
|
||||
assert_log_file("expected error to be logged for bad module name");
|
||||
|
||||
parser_free(m);
|
||||
tokenstream_close(ts);
|
||||
}
|
||||
|
||||
static void test_parser_missing_semicolon_module(void) {
|
||||
TokenStream* ts = tokenstream_get_test();
|
||||
Module* m = parser_parse(ts);
|
||||
|
||||
test_get_ast();
|
||||
assert_log_file("expected error for missing semicolon");
|
||||
|
||||
parser_free(m);
|
||||
tokenstream_close(ts);
|
||||
}
|
||||
|
||||
static void test_parser_missing_semicolon_import(void) {
|
||||
TokenStream* ts = tokenstream_get_test();
|
||||
Module* m = parser_parse(ts);
|
||||
|
||||
test_get_ast();
|
||||
assert_log_file("expected error for missing semicolon");
|
||||
|
||||
parser_free(m);
|
||||
tokenstream_close(ts);
|
||||
}
|
||||
|
||||
static void test_parser_bad_import_name(void) {
|
||||
TokenStream* ts = tokenstream_get_test();
|
||||
Module* m = parser_parse(ts);
|
||||
|
||||
test_get_ast();
|
||||
assert_log_file("expected error for bad import name");
|
||||
|
||||
parser_free(m);
|
||||
tokenstream_close(ts);
|
||||
}
|
||||
|
||||
static void test_parser_imports(void) {
|
||||
TokenStream* ts = tokenstream_open("test.c", "module my_module; import other_module;");
|
||||
Module* m = parser_parse(ts);
|
||||
Module* m = test_get_ast();
|
||||
|
||||
assert_not_null(m, "expected module to be parsed");
|
||||
assert_str("my_module", m->name, "expected name 'my_module'");
|
||||
@@ -64,13 +40,10 @@ static void test_parser_imports(void) {
|
||||
assert_int(1, (int)m->import_count, "expected one import");
|
||||
assert_str("other_module", m->imports[0].module_name, "expected import name 'other_module'");
|
||||
assert_false(m->imports[0].is_public, "expected import to not be public");
|
||||
parser_free(m);
|
||||
tokenstream_close(ts);
|
||||
}
|
||||
|
||||
static void test_parser_public_imports(void) {
|
||||
TokenStream* ts = tokenstream_open("test.c", "module my_module; import public other_module;");
|
||||
Module* m = parser_parse(ts);
|
||||
Module* m = test_get_ast();
|
||||
|
||||
assert_not_null(m, "expected module to be parsed");
|
||||
assert_str("my_module", m->name, "expected name 'my_module'");
|
||||
@@ -79,8 +52,6 @@ static void test_parser_public_imports(void) {
|
||||
assert_int(1, (int)m->import_count, "expected one import");
|
||||
assert_str("other_module", m->imports[0].module_name, "expected import name 'other_module'");
|
||||
assert_true(m->imports[0].is_public, "expected import to be public");
|
||||
parser_free(m);
|
||||
tokenstream_close(ts);
|
||||
}
|
||||
|
||||
static void test_parser_alias_simple(void) {
|
||||
@@ -110,7 +81,6 @@ static void test_parser_alias_array(void) {
|
||||
assert_true(valueType->builtin.isSigned, "expected signed");
|
||||
}
|
||||
|
||||
|
||||
static void test_parser_alias_and_import_mix(void) {
|
||||
Module* m = test_get_ast();
|
||||
|
||||
@@ -122,5 +92,4 @@ static void test_parser_alias_and_import_mix(void) {
|
||||
assert_str("bar", m->imports[1].module_name, "expected import 2 name 'bar'");
|
||||
assert_str("myalias", m->aliases[0].name, "expected alias 1 name 'myalias'");
|
||||
assert_str("otheralias", m->aliases[1].name, "expected alias 2 name 'otheralias'");
|
||||
parser_free(m);
|
||||
}
|
||||
|
||||
+10
-44
@@ -9,23 +9,19 @@ static void test_tokenstream_open_fail(void) {
|
||||
}
|
||||
|
||||
static void test_tokenstream_simple_keyword(void) {
|
||||
TokenStream* ts;
|
||||
TokenStream* ts = test_get_tokenstream();
|
||||
Token t;
|
||||
Token eof;
|
||||
|
||||
ts = tokenstream_open("test.c", "module");
|
||||
|
||||
t = tokenstream_next(ts);
|
||||
if (t.token != TOKEN_MODULE) fail("expected TOKEN_MODULE");
|
||||
|
||||
eof = tokenstream_next(ts);
|
||||
if (eof.token != TOKEN_EOF) fail("expected EOF");
|
||||
|
||||
tokenstream_close(ts);
|
||||
}
|
||||
|
||||
static void test_tokenstream_keywords_and_symbols(void) {
|
||||
TokenStream* ts = tokenstream_open("test.c", "module main; import stdio;");
|
||||
TokenStream* ts = test_get_tokenstream();
|
||||
|
||||
if (tokenstream_next(ts).token != TOKEN_MODULE) fail("expected TOKEN_MODULE");
|
||||
if (tokenstream_next(ts).token != TOKEN_IDENTIFIER) fail("expected TOKEN_IDENTIFIER (main)");
|
||||
@@ -34,24 +30,20 @@ static void test_tokenstream_keywords_and_symbols(void) {
|
||||
if (tokenstream_next(ts).token != TOKEN_IDENTIFIER) fail("expected TOKEN_IDENTIFIER (stdio)");
|
||||
if (tokenstream_next(ts).token != TOKEN_SEMICOLON) fail("expected TOKEN_SEMICOLON");
|
||||
if (tokenstream_next(ts).token != TOKEN_EOF) fail("expected EOF");
|
||||
|
||||
tokenstream_close(ts);
|
||||
}
|
||||
|
||||
static void test_tokenstream_parentheses_and_brackets(void) {
|
||||
TokenStream* ts = tokenstream_open("test.c", "()[]");
|
||||
TokenStream* ts = test_get_tokenstream();
|
||||
|
||||
if (tokenstream_next(ts).token != TOKEN_PARENT_OPEN) fail("expected TOKEN_PARENT_OPEN");
|
||||
if (tokenstream_next(ts).token != TOKEN_PARENT_CLOSE) fail("expected TOKEN_PARENT_CLOSE");
|
||||
if (tokenstream_next(ts).token != TOKEN_BRACKET_OPEN) fail("expected TOKEN_BRACKET_OPEN");
|
||||
if (tokenstream_next(ts).token != TOKEN_BRACKET_CLOSE) fail("expected TOKEN_BRACKET_CLOSE");
|
||||
if (tokenstream_next(ts).token != TOKEN_EOF) fail("expected EOF");
|
||||
|
||||
tokenstream_close(ts);
|
||||
}
|
||||
|
||||
static void test_tokenstream_comma(void) {
|
||||
TokenStream* ts = tokenstream_open("test.c", "a,b,c");
|
||||
TokenStream* ts = test_get_tokenstream();
|
||||
|
||||
if (tokenstream_next(ts).token != TOKEN_IDENTIFIER) fail("expected a");
|
||||
if (tokenstream_next(ts).token != TOKEN_COMMA) fail("expected comma");
|
||||
@@ -59,75 +51,49 @@ static void test_tokenstream_comma(void) {
|
||||
if (tokenstream_next(ts).token != TOKEN_COMMA) fail("expected comma");
|
||||
if (tokenstream_next(ts).token != TOKEN_IDENTIFIER) fail("expected c");
|
||||
if (tokenstream_next(ts).token != TOKEN_EOF) fail("expected EOF");
|
||||
|
||||
tokenstream_close(ts);
|
||||
}
|
||||
|
||||
static void test_tokenstream_whitespace_ignored(void) {
|
||||
TokenStream* ts = tokenstream_open("test.c", " module \n\t import ; ");
|
||||
TokenStream* ts = test_get_tokenstream();
|
||||
|
||||
if (tokenstream_next(ts).token != TOKEN_MODULE) fail("expected TOKEN_MODULE");
|
||||
if (tokenstream_next(ts).token != TOKEN_IMPORT) fail("expected TOKEN_IMPORT");
|
||||
if (tokenstream_next(ts).token != TOKEN_SEMICOLON) fail("expected TOKEN_SEMICOLON");
|
||||
if (tokenstream_next(ts).token != TOKEN_EOF) fail("expected EOF");
|
||||
|
||||
tokenstream_close(ts);
|
||||
}
|
||||
|
||||
static void test_tokenstream_void_function_signature(void) {
|
||||
TokenStream* ts = tokenstream_open("test.c", "void main()");
|
||||
TokenStream* ts = test_get_tokenstream();
|
||||
|
||||
if (tokenstream_next(ts).token != TOKEN_VOID) fail("expected TOKEN_VOID");
|
||||
if (tokenstream_next(ts).token != TOKEN_IDENTIFIER) fail("expected TOKEN_IDENTIFIER");
|
||||
if (tokenstream_next(ts).token != TOKEN_PARENT_OPEN) fail("expected TOKEN_PARENT_OPEN");
|
||||
if (tokenstream_next(ts).token != TOKEN_PARENT_CLOSE) fail("expected TOKEN_PARENT_CLOSE");
|
||||
if (tokenstream_next(ts).token != TOKEN_EOF) fail("expected EOF");
|
||||
|
||||
tokenstream_close(ts);
|
||||
}
|
||||
|
||||
static void test_tokenstream_unknown_token(void) {
|
||||
TokenStream* ts = tokenstream_get_test();
|
||||
TokenStream* ts = test_get_tokenstream();
|
||||
|
||||
if (tokenstream_next(ts).token != TOKEN_UNKNOWN) fail("expected TOKEN_UNKNOWN");
|
||||
|
||||
assert_log_file("expected error message for unknown token");
|
||||
|
||||
tokenstream_close(ts);
|
||||
}
|
||||
|
||||
static void test_tokenstream_info(void) {
|
||||
TokenStream* ts;
|
||||
TokenStream* ts = test_get_tokenstream();
|
||||
Token t1;
|
||||
Token t2;
|
||||
char* buf1;
|
||||
char* buf2;
|
||||
|
||||
ts = tokenstream_open("test.c", "module main;");
|
||||
|
||||
t1 = tokenstream_next(ts);
|
||||
if (t1.token != TOKEN_MODULE) fail("expected TOKEN_MODULE");
|
||||
|
||||
buf1 = malloc((size_t)t1.text.length + 1);
|
||||
if (!buf1) fail("out of memory");
|
||||
memcpy(buf1, t1.text.data, t1.text.length);
|
||||
buf1[t1.text.length] = '\0';
|
||||
assert_str("module", buf1, "info: expected 'module'");
|
||||
assert_string("module", t1.text, "info: expected 'module'");
|
||||
if (t1.location.line != 1) fail("expected line 1");
|
||||
if (t1.location.column_start != 1) fail("expected column 1");
|
||||
|
||||
t2 = tokenstream_next(ts);
|
||||
if (t2.token != TOKEN_IDENTIFIER) fail("expected TOKEN_IDENTIFIER");
|
||||
|
||||
buf2 = malloc((size_t)t2.text.length + 1);
|
||||
if (!buf2) { free(buf1); fail("out of memory"); }
|
||||
memcpy(buf2, t2.text.data, t2.text.length);
|
||||
buf2[t2.text.length] = '\0';
|
||||
assert_str("main", buf2, "info: expected 'main'");
|
||||
assert_string("main", t2.text, "info: expected 'main'");
|
||||
if (t2.location.line != 1) fail("expected line 1");
|
||||
if (t2.location.column_start != 8) fail("expected column 8");
|
||||
|
||||
free(buf1);
|
||||
free(buf2);
|
||||
tokenstream_close(ts);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
module my_module;
|
||||
import other_module;
|
||||
@@ -0,0 +1 @@
|
||||
module my_module;
|
||||
@@ -0,0 +1,2 @@
|
||||
module my_module;
|
||||
import public other_module;
|
||||
@@ -0,0 +1 @@
|
||||
a,b,c
|
||||
@@ -0,0 +1 @@
|
||||
module main;
|
||||
@@ -0,0 +1 @@
|
||||
module main; import stdio;
|
||||
@@ -0,0 +1 @@
|
||||
()[]
|
||||
@@ -0,0 +1 @@
|
||||
module
|
||||
@@ -0,0 +1 @@
|
||||
void main()
|
||||
@@ -0,0 +1,2 @@
|
||||
module
|
||||
import ;
|
||||
Reference in New Issue
Block a user