#include "algo/hash.h" #include "unity.h" #include #include void test_xor_hash_consistency(void) { uint64_t in[] = {10, 20, 30}; uint64_t actual_1 = xor64_hash(in, 3); uint64_t actual_2 = xor64_hash(in, 3); TEST_ASSERT_EQUAL_INT(actual_1, actual_2); } void test_xor_hash_empty_src(void) { uint64_t in[] = {}; uint64_t actual = xor64_hash(in, 0); TEST_ASSERT_EQUAL_INT(0, actual); } void test_xor_hash_single_byte(void) { uint64_t in_1[] = {5}; uint64_t in_2[] = {10}; uint64_t in_3[] = {15}; uint64_t actual_1 = xor64_hash(in_1, 1); uint64_t actual_2 = xor64_hash(in_2, 1); uint64_t actual_3 = xor64_hash(in_3, 1); TEST_ASSERT_NOT_EQUAL(actual_1, actual_2); TEST_ASSERT_NOT_EQUAL(actual_1, actual_3); TEST_ASSERT_NOT_EQUAL(actual_2, actual_3); } void test_xor_hash_is_varied(void) { uint64_t in_1[] = {1, 2, 3}; uint64_t in_2[] = {4, 5, 6}; uint64_t in_3[] = {100, 200, 300}; uint64_t actual_1 = xor64_hash(in_1, 3); uint64_t actual_2 = xor64_hash(in_2, 3); uint64_t actual_3 = xor64_hash(in_3, 3); TEST_ASSERT_NOT_EQUAL(actual_1, actual_2); TEST_ASSERT_NOT_EQUAL(actual_1, actual_3); TEST_ASSERT_NOT_EQUAL(actual_2, actual_3); } void test_xor_hash_permutation_collisions(void) { uint64_t in_1[] = {1, 2}; uint64_t in_2[] = {2, 1}; uint64_t actual_1 = xor64_hash(in_1, 2); uint64_t actual_2 = xor64_hash(in_2, 2); TEST_ASSERT_EQUAL_INT(actual_1, actual_2); } void test_xor_hash_large_src(void) { uint64_t large_array[100]; for (int i = 0; i < 100; i++) { large_array[i] = i * 7 + 13; } uint64_t actual = xor64_hash(large_array, 100); TEST_ASSERT_NOT_EQUAL(0, actual); uint64_t actual_2 = xor64_hash(large_array, 100); TEST_ASSERT_EQUAL_INT(actual, actual_2); } void test_xor_hash_range(void) { uint64_t in[] = {10, 20, 30, 40, 50}; uint64_t hash_1 = xor64_hash(in, 1); uint64_t hash_2 = xor64_hash(in, 2); uint64_t hash_3 = xor64_hash(in, 3); uint64_t hash_5 = xor64_hash(in, 5); TEST_ASSERT_NOT_EQUAL(hash_1, hash_2); TEST_ASSERT_NOT_EQUAL(hash_2, hash_3); TEST_ASSERT_NOT_EQUAL(hash_3, hash_5); } void test_djb2_hash_consistency(void) { const char *str = "Hello World!"; uint64_t actual_1 = djb2_hash(str, strlen(str)); uint64_t actual_2 = djb2_hash(str, strlen(str)); TEST_ASSERT_EQUAL_UINT64(actual_1, actual_2); } void test_djb2_hash_empty_string(void) { const char *str = ""; uint64_t actual = djb2_hash(str, strlen(str)); TEST_ASSERT_EQUAL_UINT64(5381, actual); } void test_djb2_hash_single_char(void) { uint64_t hash_a = djb2_hash("a", 1); uint64_t hash_b = djb2_hash("b", 1); uint64_t hash_z = djb2_hash("z", 1); TEST_ASSERT_NOT_EQUAL(hash_a, hash_b); TEST_ASSERT_NOT_EQUAL(hash_b, hash_z); } void test_djb2_hash_known_values(void) { // Pre-calculated djb2 hashes: // e.g. "a": (5381 * 33) + 'a' = 177573 + 97 = 177670 TEST_ASSERT_EQUAL_UINT64(0x0002b606ULL, djb2_hash("a", 1)); TEST_ASSERT_EQUAL_UINT64(0x0b887389ULL, djb2_hash("foo", 3)); TEST_ASSERT_EQUAL_UINT64(0x310D4F2079ULL, djb2_hash("Hello", 5)); } void test_djb2_hash_different_strings(void) { const char *str1 = "apple"; const char *str2 = "banana"; const char *str3 = "orange"; uint64_t hash1 = djb2_hash(str1, strlen(str1)); uint64_t hash2 = djb2_hash(str2, strlen(str2)); uint64_t hash3 = djb2_hash(str3, strlen(str3)); TEST_ASSERT_NOT_EQUAL(hash1, hash2); TEST_ASSERT_NOT_EQUAL(hash1, hash3); TEST_ASSERT_NOT_EQUAL(hash2, hash3); } void test_djb2_hash_large_string(void) { char long_str[256]; for (int i = 0; i < 255; i++) { long_str[i] = 'A' + (i % 26); } long_str[255] = '\0'; uint64_t actual = djb2_hash(long_str, strlen(long_str)); TEST_ASSERT_NOT_EQUAL(5381, actual); TEST_ASSERT_NOT_EQUAL(0, actual); uint64_t actual_2 = djb2_hash(long_str, strlen(long_str)); TEST_ASSERT_EQUAL_UINT64(actual, actual_2); } void test_runner_algo_hash(void) { RUN_TEST(test_xor_hash_consistency); RUN_TEST(test_xor_hash_empty_src); RUN_TEST(test_xor_hash_single_byte); RUN_TEST(test_xor_hash_is_varied); RUN_TEST(test_xor_hash_permutation_collisions); RUN_TEST(test_xor_hash_large_src); RUN_TEST(test_xor_hash_range); RUN_TEST(test_djb2_hash_consistency); RUN_TEST(test_djb2_hash_empty_string); RUN_TEST(test_djb2_hash_single_char); RUN_TEST(test_djb2_hash_known_values); RUN_TEST(test_djb2_hash_different_strings); RUN_TEST(test_djb2_hash_large_string); return; }