aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2019-03-31 13:44:27 +0200
committerdec05eba <dec05eba@protonmail.com>2020-07-25 14:36:46 +0200
commit6a9466da5377d0bc73c7e5aa48deca3740d3de6f (patch)
tree87f4630f72fe77d037fe19d17bdc00618929f678 /tests
parent6927b6338b9655974db79c429e6ffc73037ab5e0 (diff)
Test errors, stop working on error
Diffstat (limited to 'tests')
-rw-r--r--tests/errors/closure_no_lhs.amal1
-rw-r--r--tests/errors/duplicate_declaration.amal2
-rw-r--r--tests/errors/pub_in_closure.amal3
-rw-r--r--tests/main.amal3
-rw-r--r--tests/main.c127
5 files changed, 128 insertions, 8 deletions
diff --git a/tests/errors/closure_no_lhs.amal b/tests/errors/closure_no_lhs.amal
new file mode 100644
index 0000000..d903c3c
--- /dev/null
+++ b/tests/errors/closure_no_lhs.amal
@@ -0,0 +1 @@
+fn {} \ No newline at end of file
diff --git a/tests/errors/duplicate_declaration.amal b/tests/errors/duplicate_declaration.amal
new file mode 100644
index 0000000..a97b507
--- /dev/null
+++ b/tests/errors/duplicate_declaration.amal
@@ -0,0 +1,2 @@
+const main = fn {}
+const main = fn {} \ No newline at end of file
diff --git a/tests/errors/pub_in_closure.amal b/tests/errors/pub_in_closure.amal
new file mode 100644
index 0000000..881bbd4
--- /dev/null
+++ b/tests/errors/pub_in_closure.amal
@@ -0,0 +1,3 @@
+const main = fn {
+ pub const num = 45;
+} \ No newline at end of file
diff --git a/tests/main.amal b/tests/main.amal
index f778a14..ae37816 100644
--- a/tests/main.amal
+++ b/tests/main.amal
@@ -10,15 +10,12 @@ const main = fn {
}
const value = "hello";
- // fn {} // error, function declaration can't be by itself. Needs left-hand side
print(value, "world", 356, 13.37);
var num1: i64;
const num2 = 23232;
const num3 = num1 + num2 * 30;
//const num4 = (num1 + num2) * num3 * ((34 + 32) / 234.345);
const num4 = (num1 + num2) * num3 * ((34 + 32) / 2);
- // pub cost num34 = 45; // error, only declarations in global scope can be public
- //const num4 = 23; // error, variable redeclaration
/*
episfjpseifipesf
*/
diff --git a/tests/main.c b/tests/main.c
index 0dfd878..bc2fbb1 100644
--- a/tests/main.c
+++ b/tests/main.c
@@ -5,6 +5,7 @@
#include "../include/std/hash.h"
#include <stdio.h>
#include <stdlib.h>
+#include <unistd.h>
#define REQUIRE_EQ_INT(expected, actual) do{\
if((expected) != (actual)) {\
@@ -41,25 +42,141 @@ static CHECK_RESULT int test_hash_map() {
return 0;
}
-/* TODO: Restrict variables in global scope to const */
-int main() {
+#define FAIL_TEST(name) do { fprintf(stderr, "Test failed: %s\n", (name)); exit(1); } while(0)
+
+typedef struct {
+ char *filepath;
+ char *expected_error;
+ bool got_expected_error;
+} ErrorExpectedData;
+
+static void error_callback_assert(const char *err_msg, int err_msg_len, void *userdata) {
+ ErrorExpectedData *expected_data;
+ expected_data = userdata;
+ int expected_err_msg_len;
+ expected_err_msg_len = strlen(expected_data->expected_error);
+
+ if(expected_data->got_expected_error) {
+ fprintf(stderr, "We got the error we expected but also got additional error:\n%.*s\n", err_msg_len, err_msg);
+ FAIL_TEST(expected_data->filepath);
+ }
+
+ if(err_msg_len != expected_err_msg_len || strncmp(err_msg, expected_data->expected_error, expected_err_msg_len) != 0) {
+ fprintf(stderr, "Expected error message:\n%.*s\n", expected_err_msg_len, expected_data->expected_error);
+ fprintf(stderr, "Actual error message:\n%.*s\n", err_msg_len, err_msg);
+ fprintf(stderr, "a: %d, b: %d\n", expected_err_msg_len, err_msg_len);
+ FAIL_TEST(expected_data->filepath);
+ }
+
+ expected_data->got_expected_error = bool_true;
+}
+
+static char* get_full_path(const char *filepath) {
+ #define PATH_LEN 4096
+ char *buf;
+ int len;
+ int filepath_len;
+
+ buf = malloc(PATH_LEN);
+ buf[PATH_LEN - 1] = '\0';
+ getcwd(buf, PATH_LEN);
+
+ len = strlen(buf);
+ filepath_len = strlen(filepath);
+
+ buf[len++] = '/';
+ memcpy(buf + len, filepath, filepath_len);
+ buf[len + filepath_len] = '\0';
+ return buf;
+}
+
+static char* join_str(const char *str1, const char *str2, char delimiter) {
+ char *buf;
+ int len1;
+ int len2;
+
+ len1 = strlen(str1);
+ len2 = strlen(str2);
+ buf = malloc(len1 + 1 + len2 + 1);
+
+ memcpy(buf, str1, len1);
+ buf[len1] = delimiter;
+ memcpy(buf + len1 + 1, str2, len2);
+ buf[len1 + 1 + len2] = '\0';
+ return buf;
+}
+
+static void test_load_error(const char *filepath, const char *expected_error) {
amal_compiler compiler;
- FileScopeReference *file_scope;
+ amal_compiler_options options;
int result;
+ amal_compiler_options_init(&options);
+ options.error_callback = error_callback_assert;
+ ErrorExpectedData expected_data;
+ expected_data.filepath = get_full_path(filepath);
+ expected_data.expected_error = join_str(expected_data.filepath, expected_error, ':');
+ expected_data.got_expected_error = bool_false;
+ options.error_callback_userdata = &expected_data;
+
+ result = amal_compiler_init(&compiler, &options);
+ if(result != AMAL_COMPILER_OK) {
+ fprintf(stderr, "Failed to initialize compiler, error code: %d\n", result);
+ FAIL_TEST(expected_data.filepath);
+ }
+
+ result = amal_compiler_load_file(&compiler, filepath);
+ if(result == AMAL_COMPILER_OK) {
+ fprintf(stderr, "Expected to fail loading file\n");
+ FAIL_TEST(expected_data.filepath);
+ }
+
+ if(amal_compiler_deinit(&compiler) != 0) {
+ fprintf(stderr, "Failed to deinitialize compiler.\n");
+ FAIL_TEST(expected_data.filepath);
+ }
+
+ if(!expected_data.got_expected_error) {
+ fprintf(stderr, "Didn't get expected error message:\n%s\n", expected_error);
+ FAIL_TEST(expected_data.filepath);
+ }
+ free(expected_data.filepath);
+ free(expected_data.expected_error);
+}
+
+/* TODO: Restrict variables in global scope to const */
+int main() {
+ /*amal_compiler compiler;
+ int result;*/
+
return_if_error(test_hash_map());
- result = amal_compiler_init(&compiler);
+ /*
+ result = amal_compiler_init(&compiler, NULL);
if(result != AMAL_COMPILER_OK) {
fprintf(stderr, "Failed to initialize compiler, error code: %d\n", result);
return 1;
}
- result = amal_compiler_load_file(&compiler, "tests/main.amal", &file_scope);
+ result = amal_compiler_load_file(&compiler, "tests/main.amal");
if(result != AMAL_COMPILER_OK) {
fprintf(stderr, "Failed to load file, error code: %d\n", result);
return 1;
}
return amal_compiler_deinit(&compiler);
+ */
+ test_load_error("tests/errors/duplicate_declaration.amal",
+ "2:7: error: Variable with the name main was declared twice in the same scope\n"
+ "const main = fn {}\n"
+ " ^\n");
+ test_load_error("tests/errors/pub_in_closure.amal",
+ "2:5: error: Only declarations in structs can be public\n"
+ " pub const num = 45;\n"
+ " ^\n");
+ test_load_error("tests/errors/closure_no_lhs.amal",
+ "1:1: error: Expected variable declaration, string, variable or function call\n"
+ "fn {}\n"
+ "^\n");
+ return 0;
}