ox

The Ox programming language, compiler and tools (WIP)
Log | Files | Refs | README | LICENSE

hmap_test.c (3575B)



#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "hmap.h"

static void
hmap_test_basic(void)
{
	int i;
	printf("Testing dict of integers...\n");

	HashMap* map = hmap_create(sizeof(int));

	struct {
		const char* key;
		int value;
	} items[] = {
		{ "one", 1 },
		{ "two", 2 },
		{ "three", 3 },
	};

	// Insert items
	for (i = 0; i < 3; i++) {
		hmap_put(map, items[i].key, &items[i].value);
	}

	// Retrieve and check
	int v;
	int all_ok = 1;
	for (i = 0; i < 3; i++) {
		if (hmap_get(map, items[i].key, &v) && v == items[i].value) {
			printf("PASS: %s == %d\n", items[i].key, items[i].value);
		} else {
			printf("FAIL: %s\n", items[i].key);
			all_ok = 0;
		}
	}
	if (all_ok) printf("PASS: dict of integers test\n");
}

static void
hmap_test_T(void)
{
	int i;
	printf("Testing struct T...\n");

	struct T {
		int id;
		char name[32];
		int age;
		char email[64];
		float score;
	};

	HashMap* map = hmap_create(sizeof(struct T));

	struct T items[] = {
		{ 1, "alice", 30, "alice@example.com", 95.5f },
		{ 2, "bob", 25, "bob@example.com", 88.0f },
		{ 3, "carol", 28, "carol@example.com", 91.2f },
	};

	// Insert items
	for (i = 0; i < 3; i++) {
		hmap_put(map, items[i].name, &items[i]);
	}

	// Retrieve and check
	struct T v;
	int all_ok = 1;
	for (i = 0; i < 3; i++) {
		if (hmap_get(map, items[i].name, &v) && v.id == items[i].id && strcmp(v.name, items[i].name) == 0 && v.age == items[i].age
			&& strcmp(v.email, items[i].email) == 0 && v.score == items[i].score) {
			printf("PASS: %s == {id:%d, age:%d, email:%s, score:%.1f}\n",
				items[i].name,
				items[i].id,
				items[i].age,
				items[i].email,
				items[i].score);
		} else {
			printf("FAIL: %s\n", items[i].name);
			all_ok = 0;
		}
	}
	if (all_ok) printf("PASS: struct T test\n");
}

static void
hmap_test_memory_bumping(void)
{
	int i;
	printf("Testing memory bumping...\n");

	HashMap* map = hmap_create(sizeof(int));
	const int N = 1000; // Large enough to trigger resizing

	char key[32];
	int all_ok = 1;

	// Insert N items
	for (i = 0; i < N; i++) {
		snprintf(key, sizeof(key), "key_%d", i);
		hmap_put(map, key, &i);
	}

	// Retrieve and check all N items
	for (i = 0; i < N; i++) {
		snprintf(key, sizeof(key), "key_%d", i);
		int v = -1;
		if (hmap_get(map, key, &v) && v == i) {
			// Optionally print only a few
			if (i < 3 || i > N - 3) printf("PASS: %s == %d\n", key, v);
		} else {
			printf("FAIL: %s\n", key);
			all_ok = 0;
		}
	}
	if (all_ok) printf("PASS: memory bumping test\n");
}

static void
hmap_test_removal(void)
{
	int i;
	printf("Testing removal...\n");

	HashMap* map = hmap_create(sizeof(int));

	struct {
		const char* key;
		int value;
	} items[] = {
		{ "alpha", 10 },
		{ "beta", 20 },
		{ "gamma", 30 },
	};

	// Insert items
	for (i = 0; i < 3; i++) {
		hmap_put(map, items[i].key, &items[i].value);
	}

	// Remove "beta"
	hmap_remove(map, "beta");

	// Check "beta" is gone, others remain
	int v;
	int all_ok = 1;
	for (i = 0; i < 3; i++) {
		int found = hmap_get(map, items[i].key, &v);
		if (strcmp(items[i].key, "beta") == 0) {
			if (!found) {
				printf("PASS: %s removed\n", items[i].key);
			} else {
				printf("FAIL: %s still present\n", items[i].key);
				all_ok = 0;
			}
		} else {
			if (found && v == items[i].value) {
				printf("PASS: %s == %d\n", items[i].key, items[i].value);
			} else {
				printf("FAIL: %s\n", items[i].key);
				all_ok = 0;
			}
		}
	}
	if (all_ok) printf("PASS: removal test\n");
}

void
hmap_tests(void)
{
	hmap_test_basic();
	hmap_test_T();
	hmap_test_memory_bumping();
	hmap_test_removal();
}