From d7a6f3906893e8ab4b08919bb0a9740e04289201 Mon Sep 17 00:00:00 2001 From: omicron Date: Tue, 8 Apr 2025 21:57:59 +0200 Subject: [PATCH] Add more symbols tests --- tests/symbols.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) diff --git a/tests/symbols.c b/tests/symbols.c index 7392b12..28d600c 100644 --- a/tests/symbols.c +++ b/tests/symbols.c @@ -135,6 +135,101 @@ MunitResult test_symbol_add_import(const MunitParameter params[], void *data) { return MUNIT_OK; } +void test_symbol_update(const char *name, ast_node_t *first, symbol_kind_t first_kind, ast_node_t *second, + symbol_kind_t second_kind, bool should_succeed, bool should_update) { + symbol_table_t *table = nullptr; + symbol_table_alloc(&table); + + munit_assert_size(table->len, ==, 0); + error_t *err = symbol_table_update(table, first); + munit_assert_null(err); + munit_assert_size(table->len, ==, 1); + + symbol_t *symbol = symbol_table_lookup(table, name); + munit_assert_not_null(symbol); + munit_assert_int(first_kind, ==, symbol->kind); + munit_assert_ptr_equal(first, symbol->node); + munit_assert_string_equal(symbol->name, name); + + err = symbol_table_update(table, second); + if (should_succeed) + munit_assert_null(err); + else + munit_assert_ptr_equal(err, err_symbol_table_incompatible_symbols); + munit_assert_size(table->len, ==, 1); + + symbol = symbol_table_lookup(table, name); + if (should_update) { + munit_assert_not_null(symbol); + munit_assert_int(second_kind, ==, symbol->kind); + munit_assert_ptr_equal(second, symbol->node); + munit_assert_string_equal(symbol->name, name); + } else { + munit_assert_not_null(symbol); + munit_assert_int(first_kind, ==, symbol->kind); + munit_assert_ptr_equal(first, symbol->node); + munit_assert_string_equal(symbol->name, name); + } + + symbol_table_free(table); +} + +MunitResult test_symbol_upgrade_valid(const MunitParameter params[], void *data) { + ast_node_t *root; + tokenlist_t *list; + + symbols_setup_test(&root, &list, "tests/input/symbols.asm"); + + ast_node_t *reference = root->children[3]->children[1]->children[0]->children[0]; + ast_node_t *label = root->children[2]; + ast_node_t *import_directive = root->children[0]->children[1]; + ast_node_t *export_directive = root->children[1]->children[1]; + + // real upgrades + test_symbol_update("test", reference, SYMBOL_REFERENCE, label, SYMBOL_LOCAL, true, true); + test_symbol_update("test", reference, SYMBOL_REFERENCE, import_directive, SYMBOL_IMPORT, true, true); + test_symbol_update("test", reference, SYMBOL_REFERENCE, export_directive, SYMBOL_EXPORT, true, true); + test_symbol_update("test", label, SYMBOL_LOCAL, export_directive, SYMBOL_EXPORT, true, true); + + // identity upgrades + test_symbol_update("test", reference, SYMBOL_REFERENCE, reference, SYMBOL_REFERENCE, true, false); + test_symbol_update("test", label, SYMBOL_LOCAL, label, SYMBOL_LOCAL, true, false); + test_symbol_update("test", import_directive, SYMBOL_IMPORT, import_directive, SYMBOL_IMPORT, true, false); + test_symbol_update("test", export_directive, SYMBOL_EXPORT, export_directive, SYMBOL_EXPORT, true, false); + + // downgrades that are allowed and ignored + test_symbol_update("test", label, SYMBOL_LOCAL, reference, SYMBOL_REFERENCE, true, false); + test_symbol_update("test", import_directive, SYMBOL_IMPORT, reference, SYMBOL_REFERENCE, true, false); + test_symbol_update("test", export_directive, SYMBOL_EXPORT, reference, SYMBOL_REFERENCE, true, false); + test_symbol_update("test", export_directive, SYMBOL_EXPORT, label, SYMBOL_LOCAL, true, false); + test_symbol_update("test", import_directive, SYMBOL_IMPORT, label, SYMBOL_LOCAL, true, false); + + ast_node_free(root); + tokenlist_free(list); + return MUNIT_OK; +} + +MunitResult test_symbol_upgrade_invalid(const MunitParameter params[], void *data) { + ast_node_t *root; + tokenlist_t *list; + + symbols_setup_test(&root, &list, "tests/input/symbols.asm"); + + ast_node_t *reference = root->children[3]->children[1]->children[0]->children[0]; + ast_node_t *label = root->children[2]; + ast_node_t *import_directive = root->children[0]->children[1]; + ast_node_t *export_directive = root->children[1]->children[1]; + + // invalid upgrades + test_symbol_update("test", label, SYMBOL_LOCAL, import_directive, SYMBOL_IMPORT, false, false); + test_symbol_update("test", export_directive, SYMBOL_EXPORT, import_directive, SYMBOL_IMPORT, false, false); + test_symbol_update("test", import_directive, SYMBOL_IMPORT, export_directive, SYMBOL_EXPORT, false, false); + + ast_node_free(root); + tokenlist_free(list); + return MUNIT_OK; +} + MunitResult test_symbol_add_export(const MunitParameter params[], void *data) { (void)params; (void)data; @@ -171,5 +266,7 @@ MunitTest symbols_tests[] = { {"/add_label", test_symbol_add_label, nullptr, nullptr, MUNIT_TEST_OPTION_NONE, nullptr}, {"/add_import", test_symbol_add_import, nullptr, nullptr, MUNIT_TEST_OPTION_NONE, nullptr}, {"/add_export", test_symbol_add_export, nullptr, nullptr, MUNIT_TEST_OPTION_NONE, nullptr}, + {"/upgrade_valid", test_symbol_upgrade_valid, nullptr, nullptr, MUNIT_TEST_OPTION_NONE, nullptr}, + {"/upgrade_invalid", test_symbol_upgrade_invalid, nullptr, nullptr, MUNIT_TEST_OPTION_NONE, nullptr}, {nullptr, nullptr, nullptr, nullptr, MUNIT_TEST_OPTION_NONE, nullptr} };