diff options
| author | Douglas B. Rumbaugh <doug@douglasrumbaugh.com> | 2025-11-01 13:31:38 -0400 |
|---|---|---|
| committer | Douglas B. Rumbaugh <doug@douglasrumbaugh.com> | 2025-11-01 13:31:38 -0400 |
| commit | 6338ac827b15787a0d83136eac9d681588f07f9a (patch) | |
| tree | f808100cd52e54c632b31b8a42f3bdb703f3d31a /tests/strmap_tests.c | |
| download | libmap-6338ac827b15787a0d83136eac9d681588f07f9a.tar.gz | |
Initial commit
Diffstat (limited to 'tests/strmap_tests.c')
| -rwxr-xr-x | tests/strmap_tests.c | 228 |
1 files changed, 228 insertions, 0 deletions
diff --git a/tests/strmap_tests.c b/tests/strmap_tests.c new file mode 100755 index 0000000..7f3c34f --- /dev/null +++ b/tests/strmap_tests.c @@ -0,0 +1,228 @@ +/* + * strmap_test.c + * + * Unit tests for strmap implementation + */ + +#include "hashfuncs.h" +#include "strmap.h" + +#include <check.h> +#include <stdlib.h> +#include <string.h> + +START_TEST(test_create_destroy) { + strmap *map = strmap_create(hash_key); + ck_assert_ptr_nonnull(map); + ck_assert_uint_eq(strmap_size(map), 0); + strmap_destroy(map); +} +END_TEST + +START_TEST(test_put_get_basic) { + strmap *map = strmap_create(hash_key); + const char *value; + + ck_assert_int_eq(strmap_put(map, "key1", "value1"), STRMAP_OK); + ck_assert_uint_eq(strmap_size(map), 1); + + ck_assert_int_eq(strmap_get(map, "key1", &value), STRMAP_OK); + ck_assert_str_eq(value, "value1"); + + strmap_destroy(map); +} +END_TEST + +START_TEST(test_put_update) { + strmap *map = strmap_create(hash_key); + const char *value; + + ck_assert_int_eq(strmap_put(map, "key1", "value1"), STRMAP_OK); + ck_assert_int_eq(strmap_put(map, "key1", "value2"), STRMAP_OK); + ck_assert_uint_eq(strmap_size(map), 1); + + ck_assert_int_eq(strmap_get(map, "key1", &value), STRMAP_OK); + ck_assert_str_eq(value, "value2"); + + strmap_destroy(map); +} +END_TEST + +START_TEST(test_get_nonexistent) { + strmap *map = strmap_create(hash_key); + const char *value; + + ck_assert_int_eq(strmap_get(map, "nonexistent", &value), STRMAP_NOTFOUND); + + strmap_destroy(map); +} +END_TEST + +START_TEST(test_delete_basic) { + strmap *map = strmap_create(hash_key); + const char *value; + + ck_assert_int_eq(strmap_put(map, "key1", "value1"), STRMAP_OK); + ck_assert_int_eq(strmap_delete(map, "key1"), STRMAP_OK); + ck_assert_uint_eq(strmap_size(map), 0); + + ck_assert_int_eq(strmap_get(map, "key1", &value), STRMAP_NOTFOUND); + + strmap_destroy(map); +} +END_TEST + +START_TEST(test_delete_nonexistent) { + strmap *map = strmap_create(hash_key); + + ck_assert_int_eq(strmap_delete(map, "nonexistent"), STRMAP_NOTFOUND); + + strmap_destroy(map); +} +END_TEST + +START_TEST(test_delete_multiple) { + strmap *map = strmap_create(hash_key); + const char *value; + + // Add multiple items + ck_assert_int_eq(strmap_put(map, "key1", "value1"), STRMAP_OK); + ck_assert_int_eq(strmap_put(map, "key2", "value2"), STRMAP_OK); + ck_assert_int_eq(strmap_put(map, "key3", "value3"), STRMAP_OK); + ck_assert_uint_eq(strmap_size(map), 3); + + // Delete middle item + ck_assert_int_eq(strmap_delete(map, "key2"), STRMAP_OK); + ck_assert_uint_eq(strmap_size(map), 2); + ck_assert_int_eq(strmap_get(map, "key2", &value), STRMAP_NOTFOUND); + + // Verify remaining items + ck_assert_int_eq(strmap_get(map, "key1", &value), STRMAP_OK); + ck_assert_str_eq(value, "value1"); + ck_assert_int_eq(strmap_get(map, "key3", &value), STRMAP_OK); + ck_assert_str_eq(value, "value3"); + + strmap_destroy(map); +} +END_TEST + +START_TEST(test_delete_head) { + strmap *map = strmap_create(hash_key); + const char *value; + + // Add items that will likely hash to same bucket + ck_assert_int_eq(strmap_put(map, "a", "first"), STRMAP_OK); + ck_assert_int_eq(strmap_put(map, "b", "second"), STRMAP_OK); + ck_assert_int_eq(strmap_put(map, "c", "third"), STRMAP_OK); + + // Delete head item + ck_assert_int_eq(strmap_delete(map, "c"), STRMAP_OK); + ck_assert_uint_eq(strmap_size(map), 2); + ck_assert_int_eq(strmap_get(map, "c", &value), STRMAP_NOTFOUND); + + // Verify remaining items + ck_assert_int_eq(strmap_get(map, "a", &value), STRMAP_OK); + ck_assert_str_eq(value, "first"); + ck_assert_int_eq(strmap_get(map, "b", &value), STRMAP_OK); + ck_assert_str_eq(value, "second"); + + strmap_destroy(map); +} +END_TEST + +START_TEST(test_collision_handling) { + strmap *map = strmap_create(test_hash); + const char *value; + + /* all keys with the same initial letter should map to the same bucket */ + ck_assert_int_eq(strmap_put(map, "key1", "value1"), STRMAP_OK); + ck_assert_int_eq(strmap_put(map, "key2", "value2"), STRMAP_OK); + ck_assert_int_eq(strmap_put(map, "key3", "value3"), STRMAP_OK); + ck_assert_uint_eq(strmap_size(map), 3); + + // Retrieve all values + ck_assert_int_eq(strmap_get(map, "key1", &value), STRMAP_OK); + ck_assert_str_eq(value, "value1"); + ck_assert_int_eq(strmap_get(map, "key2", &value), STRMAP_OK); + ck_assert_str_eq(value, "value2"); + ck_assert_int_eq(strmap_get(map, "key3", &value), STRMAP_OK); + ck_assert_str_eq(value, "value3"); + + strmap_destroy(map); +} +END_TEST + +START_TEST(test_empty_key_value) { + strmap *map = strmap_create(hash_key); + const char *value; + + // Test empty string key + ck_assert_int_eq(strmap_put(map, "", "empty_key_value"), STRMAP_OK); + ck_assert_int_eq(strmap_get(map, "", &value), STRMAP_OK); + ck_assert_str_eq(value, "empty_key_value"); + + // Test empty string value + ck_assert_int_eq(strmap_put(map, "empty_value_key", ""), STRMAP_OK); + ck_assert_int_eq(strmap_get(map, "empty_value_key", &value), STRMAP_OK); + ck_assert_str_eq(value, ""); + + strmap_destroy(map); +} +END_TEST + +START_TEST(test_put_null_key) { + strmap *map = strmap_create(hash_key); + + // This should ideally be handled gracefully + // Behavior depends on your strdup implementation with NULL + // For now, we'll assume it fails gracefully + ck_assert_int_eq(strmap_put(map, NULL, "value"), STRMAP_ERR); + + strmap_destroy(map); +} +END_TEST + +Suite *strmap_suite(void) { + Suite *s; + TCase *tc_core; + TCase *tc_edge; + + s = suite_create("Strmap"); + + /* Core test case */ + tc_core = tcase_create("Core"); + tcase_add_test(tc_core, test_create_destroy); + tcase_add_test(tc_core, test_put_get_basic); + tcase_add_test(tc_core, test_put_update); + tcase_add_test(tc_core, test_get_nonexistent); + tcase_add_test(tc_core, test_delete_basic); + tcase_add_test(tc_core, test_delete_nonexistent); + tcase_add_test(tc_core, test_delete_multiple); + tcase_add_test(tc_core, test_delete_head); + tcase_add_test(tc_core, test_collision_handling); + + /* Edge cases */ + tc_edge = tcase_create("Edge"); + tcase_add_test(tc_edge, test_empty_key_value); + tcase_add_test(tc_edge, test_put_null_key); + + suite_add_tcase(s, tc_core); + suite_add_tcase(s, tc_edge); + + return s; +} + +int main(void) { + int number_failed; + Suite *s; + SRunner *sr; + + s = strmap_suite(); + sr = srunner_create(s); + + srunner_run_all(sr, CK_NORMAL); + number_failed = srunner_ntests_failed(sr); + srunner_free(sr); + + return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; +} |