LCOV - code coverage report
Current view: top level - src/tests - hashmap.c (source / functions) Hit Total Coverage
Test: passgen-test.info Lines: 134 134 100.0 %
Date: 2024-05-03 06:05:14 Functions: 11 11 100.0 %

          Line data    Source code
       1             : #include "passgen/container/hashmap.h"
       2             : #include "tests.h"
       3             : #include <stdlib.h>
       4             : #include <string.h>
       5             : 
       6           1 : test_result test_hashmap_init(void) {
       7             :     passgen_hashmap map;
       8           1 :     passgen_hashmap_init(&map, NULL);
       9           1 :     passgen_hashmap_free(&map);
      10           1 :     return test_ok;
      11             : }
      12             : 
      13           1 : test_result test_hashmap_context_utf8(void) {
      14             :     passgen_hashmap map;
      15           1 :     passgen_hashmap_init(&map, &passgen_hashmap_context_utf8);
      16             : 
      17           1 :     const char *key1 = "hello";
      18           1 :     const char *key2 = "hola";
      19             : 
      20           1 :     assert(passgen_hashmap_context_utf8.equal(&map, key1, key1));
      21           1 :     assert(passgen_hashmap_context_utf8.equal(&map, key2, key2));
      22           1 :     assert(!passgen_hashmap_context_utf8.equal(&map, key1, key2));
      23             : 
      24           1 :     assert_eq(
      25             :         passgen_hashmap_context_utf8.hash(&map, key1, true),
      26             :         0xf6f0cd43722c7cfe);
      27           1 :     assert_eq(
      28             :         passgen_hashmap_context_utf8.hash(&map, key1, false),
      29             :         0x438bcb516e4d4abf);
      30             : 
      31           1 :     assert_eq(
      32             :         passgen_hashmap_context_utf8.hash(&map, key2, true),
      33             :         0xcb99aa476d12f348);
      34           1 :     assert_eq(
      35             :         passgen_hashmap_context_utf8.hash(&map, key2, false),
      36             :         0xef7ec81d7aa533ea);
      37             : 
      38           1 :     passgen_hashmap_free(&map);
      39             : 
      40           1 :     return test_ok;
      41             : }
      42             : 
      43           1 : test_result test_hashmap_context_utf32(void) {
      44             :     passgen_hashmap map;
      45           1 :     passgen_hashmap_init(&map, &passgen_hashmap_context_utf32);
      46             : 
      47           1 :     uint32_t key1[] = {'h', 'e', 'l', 'l', 'o', 0};
      48           1 :     uint32_t key2[] = {'h', 'o', 'l', 'a', 0};
      49             : 
      50           1 :     assert(passgen_hashmap_context_utf32.equal(&map, &key1[0], &key1[0]));
      51           1 :     assert(passgen_hashmap_context_utf32.equal(&map, &key2[0], &key2[0]));
      52           1 :     assert(!passgen_hashmap_context_utf32.equal(&map, &key1[0], &key2[0]));
      53             : 
      54           1 :     assert_eq(
      55             :         passgen_hashmap_context_utf32.hash(&map, &key1[0], true),
      56             :         0x4b9a41e6925a46ad);
      57           1 :     assert_eq(
      58             :         passgen_hashmap_context_utf32.hash(&map, &key1[0], false),
      59             :         0x6ce43ac01a6144b8);
      60             : 
      61           1 :     assert_eq(
      62             :         passgen_hashmap_context_utf32.hash(&map, &key2[0], true),
      63             :         0xdefab330a5dcde19);
      64           1 :     assert_eq(
      65             :         passgen_hashmap_context_utf32.hash(&map, &key2[0], false),
      66             :         0x45168f9b31b7e7bd);
      67             : 
      68           1 :     passgen_hashmap_free(&map);
      69             : 
      70           1 :     return test_ok;
      71             : }
      72             : 
      73           1 : test_result test_hashmap_insert_utf32(void) {
      74             :     passgen_hashmap map;
      75             :     passgen_hashmap_entry entry;
      76             : 
      77           1 :     passgen_hashmap_init(&map, &passgen_hashmap_context_utf32);
      78             : 
      79           1 :     uint32_t key1[] = {'h', 'e', 'l', 'l', 'o', 0};
      80             :     int value1;
      81           1 :     entry = passgen_hashmap_insert(&map, &key1, &value1);
      82           1 :     assert_eq(entry.key, NULL);
      83           1 :     assert_eq(entry.value, NULL);
      84           1 :     assert_eq(map.len, 1);
      85           1 :     assert_eq(passgen_hashmap_lookup(&map, &key1)->value, &value1);
      86             : 
      87           1 :     uint32_t key2[] = {'h', 'o', 'l', 'a', 0};
      88             :     int value2;
      89           1 :     entry = passgen_hashmap_insert(&map, &key2, &value2);
      90           1 :     assert_eq(map.len, 2);
      91           1 :     assert_eq(entry.key, NULL);
      92           1 :     assert_eq(entry.value, NULL);
      93           1 :     assert_eq(passgen_hashmap_lookup(&map, &key1)->value, &value1);
      94           1 :     assert_eq(passgen_hashmap_lookup(&map, &key2)->value, &value2);
      95             : 
      96           1 :     passgen_hashmap_free(&map);
      97             : 
      98           1 :     return test_ok;
      99             : }
     100             : 
     101           1 : test_result test_hashmap_insert_utf8(void) {
     102             :     passgen_hashmap map;
     103           1 :     passgen_hashmap_init(&map, NULL);
     104             : 
     105           1 :     int value_a = 4, value_b = 7;
     106             : 
     107           1 :     passgen_hashmap_insert(&map, "hello", &value_a);
     108           1 :     assert_eq(map.len, 1);
     109           1 :     passgen_hashmap_insert(&map, "world", &value_b);
     110           1 :     assert_eq(map.len, 2);
     111             : 
     112             :     passgen_hashmap_entry *entry;
     113           1 :     entry = passgen_hashmap_lookup(&map, "hello");
     114           1 :     assert(entry);
     115           1 :     assert_eq(entry->value, &value_a);
     116             : 
     117           1 :     entry = passgen_hashmap_lookup(&map, "world");
     118           1 :     assert(entry);
     119           1 :     assert_eq(entry->value, &value_b);
     120             : 
     121           1 :     entry = passgen_hashmap_lookup(&map, "other");
     122           1 :     assert(!entry);
     123             : 
     124           1 :     passgen_hashmap_free(&map);
     125           1 :     return test_ok;
     126             : }
     127             : 
     128           1 : test_result test_hashmap_insert_many(void) {
     129             :     passgen_hashmap map;
     130           1 :     passgen_hashmap_init(&map, NULL);
     131           1 :     size_t insert_max = 10000;
     132             : 
     133             :     // insert large amount of items
     134       10001 :     for(size_t i = 0; i < insert_max; i++) {
     135       10000 :         assert_eq(map.len, i);
     136       10000 :         char *key = malloc(32);
     137       10000 :         size_t *value = malloc(sizeof(size_t));
     138       10000 :         *value = i;
     139       10000 :         snprintf(key, 32, "%zu", i);
     140       10000 :         passgen_hashmap_insert(&map, key, value);
     141             : 
     142             :         // fill factor is how many percent of slots are used. we want this
     143             :         // to be high.
     144       10000 :         float fill = map.len * 100.0 / (double) map.capacity;
     145       10000 :         assert(fill > 3.0);
     146             :     }
     147             : 
     148             :     // retrieve all items
     149       10001 :     for(size_t i = 0; i < insert_max; i++) {
     150             :         char key[32];
     151       10000 :         snprintf(key, 32, "%zu", i);
     152       10000 :         passgen_hashmap_entry *entry = passgen_hashmap_lookup(&map, key);
     153       10000 :         assert(entry);
     154       10000 :         size_t *value = entry->value;
     155       10000 :         assert_eq(*value, i);
     156             :     }
     157             : 
     158             :     // release memory
     159           1 :     passgen_hashmap_foreach(&map, NULL, passgen_hashmap_entry_free);
     160             : 
     161           1 :     passgen_hashmap_free(&map);
     162           1 :     return test_ok;
     163             : }
     164             : 
     165           1 : test_result test_hashmap_remove(void) {
     166             :     passgen_hashmap map;
     167           1 :     passgen_hashmap_init(&map, NULL);
     168             : 
     169           1 :     int value_a = 4, value_b = 7;
     170             : 
     171           1 :     passgen_hashmap_insert(&map, "hello", &value_a);
     172           1 :     passgen_hashmap_insert(&map, "world", &value_b);
     173           1 :     assert_eq(map.len, 2);
     174             : 
     175           1 :     assert(passgen_hashmap_lookup(&map, "hello"));
     176           1 :     assert(passgen_hashmap_lookup(&map, "world"));
     177           1 :     assert(!passgen_hashmap_lookup(&map, "other"));
     178             : 
     179             :     passgen_hashmap_entry entry;
     180           1 :     entry = passgen_hashmap_remove(&map, "hello");
     181           1 :     assert_eq(map.len, 1);
     182           1 :     assert(entry.key);
     183           1 :     assert_eq(entry.value, &value_a);
     184           1 :     assert_streq(entry.key, "hello");
     185             : 
     186           1 :     assert(!passgen_hashmap_lookup(&map, "hello"));
     187           1 :     assert(passgen_hashmap_lookup(&map, "world"));
     188           1 :     assert(!passgen_hashmap_lookup(&map, "other"));
     189             : 
     190           1 :     entry = passgen_hashmap_remove(&map, "world");
     191           1 :     assert_eq(map.len, 0);
     192           1 :     assert(entry.key);
     193           1 :     assert_eq(entry.value, &value_b);
     194           1 :     assert_streq(entry.key, "world");
     195             : 
     196           1 :     assert(!passgen_hashmap_lookup(&map, "hello"));
     197           1 :     assert(!passgen_hashmap_lookup(&map, "world"));
     198           1 :     assert(!passgen_hashmap_lookup(&map, "other"));
     199             : 
     200           1 :     passgen_hashmap_free(&map);
     201           1 :     return test_ok;
     202             : }
     203             : 
     204           1 : test_result test_hashmap_lookup_empty(void) {
     205             :     passgen_hashmap map;
     206           1 :     passgen_hashmap_init(&map, NULL);
     207             : 
     208           1 :     passgen_hashmap_entry *entry = passgen_hashmap_lookup(&map, "test");
     209           1 :     assert(!entry);
     210             : 
     211           1 :     passgen_hashmap_free(&map);
     212           1 :     return test_ok;
     213             : }
     214             : 
     215           1 : int function_fails(void *data, passgen_hashmap_entry *entry) {
     216             :     (void) data;
     217             :     (void) entry;
     218           1 :     return 7;
     219             : }
     220             : 
     221           5 : int free_value(void *data, passgen_hashmap_entry *entry) {
     222             :     (void) data;
     223           5 :     free(entry->value);
     224           5 :     return 0;
     225             : }
     226             : 
     227           1 : test_result test_hashmap_foreach(void) {
     228             :     passgen_hashmap map;
     229           1 :     passgen_hashmap_init(&map, NULL);
     230             : 
     231           1 :     passgen_hashmap_insert(&map, "alpha", malloc(255));
     232           1 :     passgen_hashmap_insert(&map, "beta", malloc(255));
     233           1 :     passgen_hashmap_insert(&map, "gamma", malloc(255));
     234           1 :     passgen_hashmap_insert(&map, "delta", malloc(255));
     235           1 :     passgen_hashmap_insert(&map, "epsilon", malloc(255));
     236             : 
     237           1 :     assert_eq(passgen_hashmap_foreach(&map, NULL, function_fails), 7);
     238           1 :     assert_eq(passgen_hashmap_foreach(&map, NULL, free_value), 0);
     239             : 
     240           1 :     passgen_hashmap_free(&map);
     241           1 :     return test_ok;
     242             : }

Generated by: LCOV version 1.14