Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
tadd committed Feb 2, 2025
1 parent 6bef298 commit 7aea111
Show file tree
Hide file tree
Showing 7 changed files with 672 additions and 146 deletions.
7 changes: 4 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ ANALYZER=-fanalyzer
SANITIZER=-fsanitize=undefined #,address
TIMEOUT=timeout 2

OBJ_COMMON=schaf.o utils.o
OBJ_COMMON=schaf.o utils.o table.o
OBJ=$(OBJ_COMMON) main.o
OBJ_TEST=$(OBJ_COMMON) basic-test.o

Expand Down Expand Up @@ -60,8 +60,9 @@ microbench: schaf
@$(MAKE) -C $@

utils.o: utils.h
schaf.o main.o: schaf.h utils.h
basic-test.o: schaf.h
schaf.o main.o basic-test.o: schaf.h utils.h
table.o: table.h utils.h
schaf.o basic-test.o: table.h

.PHONY: all clean test test-c test-scheme analyze sanitize \
test-san test-c-san test-scheme-san \
Expand Down
176 changes: 176 additions & 0 deletions basic-test.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
#include <criterion/new/assert.h>

#include "schaf.h"
#include "table.h"
#include "utils.h"

#define expect_stringify(exp, v) do { \
char *s = stringify(v); \
Expand Down Expand Up @@ -218,3 +220,177 @@ Test(schaf, map) {
expect_runtime_error("expected pair but got integer", "(map + 1)");
expect_runtime_error("expected pair but got integer", "(for-each + 1)");
}

Test(table, get_put) {
Table *t = table_new();
table_put(t, 1, 100);
cr_assert(eq(int, 100, table_get(t, 1)));
table_put(t, 2, 200);
table_put(t, 3, 300);
table_put(t, 4, 400);
cr_assert(eq(int, 100, table_get(t, 1)));
cr_assert(eq(int, 200, table_get(t, 2)));
cr_assert(eq(int, 300, table_get(t, 3)));
cr_assert(eq(int, 400, table_get(t, 4)));
table_put(t, 1, 42);
cr_assert(eq(int, 42, table_get(t, 1)));
cr_assert(eq(int, 200, table_get(t, 2)));
cr_assert(eq(int, 300, table_get(t, 3)));
cr_assert(eq(int, 400, table_get(t, 4)));

for (int i = 1; i <= 17; i++)
table_put(t, i, i*10000000);
for (int i = 1; i <= 17; i++)
cr_assert(eq(int, i*10000000, table_get(t, i)));

table_free(t);
}

Test(table, merge) {
Table *t = table_new();
for (size_t i = 1; i <= 11; i++)
table_put(t, i, i*13);
Table *u = table_new();
for (size_t i = 5; i <= 17; i++)
table_put(u, i, i*19);
table_merge(t, u);

for (int i = 1; i < 5; i++)
cr_assert(eq(sz, i*13, table_get(t, i)));
for (int i = 5; i <= 17; i++)
cr_assert(eq(sz, i*19, table_get(t, i)));

table_free(t);
table_free(u);
}

Test(table, merge_precedence) {
Table *t = table_new();
for (size_t i = 1; i <= 3; i++) {
table_put(t, 1, i*10);
cr_assert(eq(sz, i*10, table_get(t, 1)));
}

Table *u = table_new();
for (size_t i = 1; i <= 3; i++) {
table_put(u, 1, i*20);
cr_assert(eq(sz, i*20, table_get(u, 1)));
}

table_merge(t, u);
// the latest entry of `u` should take precedence in `t` too
cr_assert(eq(sz, 60, table_get(t, 1)));

table_free(t);
table_free(u);
}

static inline uint64_t keydup(uint64_t s)
{
return (uint64_t) xstrdup((char *) s);
}

Test(table, string_keys) {
uint64_t k_foo = (uint64_t) "foo";
uint64_t k_bar = (uint64_t) "bar";

Table *t = table_new_str();
table_put(t, keydup(k_foo), 12);
table_put(t, keydup(k_bar), 34);
table_put(t, keydup(k_foo), 56);

cr_assert(eq(int, 56, table_get(t, k_foo)));
cr_assert(eq(int, 34, table_get(t, k_bar)));

table_free(t);
}

Test(table, set_or_put) {
Table *t = table_new();
table_put(t, 1, 123);
table_put(t, 2, 456);

bool s1 = table_set_or_put(t, 2, 789); // overwrite!
bool s2 = table_set_or_put(t, 3, 210); // just add

cr_assert(s1);
cr_assert(not(s2));
cr_assert(eq(int, 123, table_get(t, 1)));
cr_assert(eq(int, 789, table_get(t, 2)));
cr_assert(eq(int, 210, table_get(t, 3)));
table_free(t);
}

Test(table, inherit) {
Table *t = table_new();
table_put(t, 1, 12);
table_put(t, 2, 34);

Table *u = table_inherit(t);
table_put(u, 2, 20);
table_put(u, 3, 30);

cr_assert(eq(int, 12, table_get(t, 1)));
cr_assert(eq(int, 34, table_get(t, 2)));
cr_assert(eq(int, 0, table_get(t, 3)));

cr_assert(eq(int, 12, table_get(u, 1)));
cr_assert(eq(int, 20, table_get(u, 2)));
cr_assert(eq(int, 30, table_get(u, 3)));

table_free(u);
table_free(t);
}

Test(table, inherit_set) {
Table *t = table_new();
table_put(t, 1, 10);
cr_assert(eq(int, 10, table_get(t, 1)));

Table *u = table_inherit(t);
table_put(u, 2, 20);
table_set(u, 1, 30);

cr_assert(eq(int, 30, table_get(t, 1)));
cr_assert(eq(int, 0, table_get(t, 2)));

cr_assert(eq(int, 30, table_get(u, 1)));
cr_assert(eq(int, 20, table_get(u, 2)));

table_free(u);
table_free(t);
}

Test(table, resize_keeping_order) {
Table *t = table_new();
for (size_t i = 1; i <= 100; i++) {
table_put(t, 1, i*10);
cr_assert(eq(sz, i*10, table_get(t, 1)));
}
for (size_t i = 1; i <= 100; i++) {
table_put(t, i*2, i);
cr_assert(eq(sz, i, table_get(t, i*2)));
}
for (size_t i = 1; i <= 100; i++) {
table_put(t, 1, i*10);
cr_assert(eq(sz, i*10, table_get(t, 1)));
}
table_free(t);
}

Test(table, set) {
Table *t = table_new();
table_put(t, 1, 123);
table_put(t, 2, 456);

bool s1 = table_set(t, 2, 789); // overwrite!
bool s2 = table_set(t, 3, 210); // ignored

cr_assert(s1);
cr_assert(not(s2));
cr_assert(eq(int, 123, table_get(t, 1)));
cr_assert(eq(int, 789, table_get(t, 2)));
cr_assert(eq(int, 0, table_get(t, 3))); // still not found!

table_free(t);
}
Loading

0 comments on commit 7aea111

Please sign in to comment.