summaryrefslogtreecommitdiffstats
path: root/tests/test_direct.c
diff options
context:
space:
mode:
authorEthan Werner <mail@ethanwerner.com>2026-09-19 06:09:54 +0000
committerEthan Werner <mail@ethanwerner.com>2026-09-19 06:09:54 +0000
commitbf19b9938508f70011395f4dc283ca758ec6a8d3 (patch)
tree46dc4c442ed8d8d43040433c6a4794e76f8e618a /tests/test_direct.c
parent96ecf29e8be977f51f351308ef2c7c492bb829aa (diff)
llm toolingHEADmaster
Diffstat (limited to 'tests/test_direct.c')
-rw-r--r--tests/test_direct.c157
1 files changed, 157 insertions, 0 deletions
diff --git a/tests/test_direct.c b/tests/test_direct.c
new file mode 100644
index 0000000..7f0e192
--- /dev/null
+++ b/tests/test_direct.c
@@ -0,0 +1,157 @@
+// Tests for direct.h - computation graph connectivity and updates
+#include <stdio.h>
+typedef double direct_value_t;
+#define DT_IMPLEMENTATION
+#include "../include/direct.h"
+
+#include <math.h>
+
+#define EPS 1e-9
+
+#define ASSERT(cond, msg) \
+ do { \
+ if (!(cond)) { \
+ fprintf(stderr, "FAIL: %s (test_direct.c:%d)\n", msg, __LINE__); \
+ failures++; \
+ } \
+ } while (0)
+
+#define ASSERT_FLOAT_EQ(a, b, msg) \
+ do { \
+ if (fabs((a) - (b)) > EPS) { \
+ fprintf(stderr, "FAIL: %s (got %f, expected %f) (test_direct.c:%d)\n", \
+ msg, (double)(a), (double)(b), __LINE__); \
+ failures++; \
+ } \
+ } while (0)
+
+static int failures = 0;
+
+void test_connect() {
+ node_t a = {NULL, 1, 0, &dt_one};
+ node_t b = {NULL, 2, 0, &dt_add};
+
+ ASSERT(dt_connect(&b, &a), "connect returns 1 on success");
+ ASSERT(b.edge != NULL, "connect sets edge");
+ if (!b.edge) { dt_clear_edges(&b); return; }
+ ASSERT(b.edge->node == &a, "connect sets correct node");
+
+ dt_clear_edges(&b);
+}
+
+void test_disconnect() {
+ node_t a = {NULL, 1, 0, &dt_one};
+ node_t b = {NULL, 2, 0, &dt_add};
+
+ dt_connect(&b, &a);
+ dt_disconnect(&b, &a);
+ ASSERT(b.edge == NULL, "disconnect removes edge");
+}
+
+void test_connect_ok_null() {
+ node_t a = {NULL, 1, 0, &dt_one};
+ node_t b = {NULL, 2, 0, &dt_add};
+
+ ASSERT(!dt_connect_ok(NULL, &a), "connect_ok NULL to returns 0");
+ ASSERT(!dt_connect_ok(&b, NULL), "connect_ok NULL from returns 0");
+ ASSERT(!dt_connect_ok(NULL, NULL), "connect_ok both NULL returns 0");
+}
+
+void test_add() {
+ node_t a = {NULL, 0, 0, &dt_one};
+ node_t b = {NULL, 0, 0, &dt_one};
+ node_t sum = {NULL, 0, 0, &dt_add};
+
+ dt_connect(&sum, &a);
+ dt_connect(&sum, &b);
+ dt_update(&sum);
+
+ ASSERT_FLOAT_EQ(a.x, 1, "dt_one sets a to 1");
+ ASSERT_FLOAT_EQ(b.x, 1, "dt_one sets b to 1");
+ ASSERT_FLOAT_EQ(sum.x, 2, "add sums edges: 0+1+1");
+
+ dt_clear_edges(&sum);
+}
+
+void test_subtract() {
+ node_t a = {NULL, 0, 0, &dt_one};
+ node_t b = {NULL, 0, 0, &dt_one};
+ node_t c = {NULL, 0, 0, &dt_one};
+ node_t diff = {NULL, 0, 0, &dt_subtract};
+
+ dt_connect(&diff, &a);
+ dt_connect(&diff, &b);
+ dt_connect(&diff, &c);
+ dt_update(&diff);
+
+ ASSERT_FLOAT_EQ(diff.x, -3, "subtract: 0 - 1 - 1 - 1");
+
+ dt_clear_edges(&diff);
+}
+
+void test_multiple_connections() {
+ node_t a = {NULL, 0, 0, &dt_one};
+ node_t b = {NULL, 0, 0, &dt_one};
+ node_t c = {NULL, 0, 0, &dt_one};
+ node_t sum = {NULL, 5, 0, &dt_add};
+
+ dt_connect(&sum, &a);
+ dt_connect(&sum, &b);
+ dt_connect(&sum, &c);
+ dt_update(&sum);
+
+ ASSERT_FLOAT_EQ(sum.x, 8, "add: 5 + 1 + 1 + 1");
+
+ dt_clear_edges(&sum);
+}
+
+void test_chained_addition() {
+ node_t a = {NULL, 0, 0, &dt_one};
+ node_t b = {NULL, 0, 0, &dt_one};
+ node_t c = {NULL, 0, 0, &dt_one};
+
+ node_t ab = {NULL, 0, 0, &dt_add};
+ dt_connect(&ab, &a);
+ dt_connect(&ab, &b);
+
+ node_t abc = {NULL, 10, 0, &dt_add};
+ dt_connect(&abc, &ab);
+ dt_connect(&abc, &c);
+
+ dt_update(&abc);
+ ASSERT_FLOAT_EQ(ab.x, 2, "ab: 0+1+1=2");
+ ASSERT_FLOAT_EQ(abc.x, 13, "abc: 10+2+1=13");
+
+ dt_clear_edges(&ab);
+ dt_clear_edges(&abc);
+}
+
+void test_clear_edges() {
+ node_t a = {NULL, 1, 0, &dt_one};
+ node_t b = {NULL, 0, 0, &dt_add};
+
+ dt_connect(&b, &a);
+ dt_clear_edges(&b);
+ ASSERT(b.edge == NULL, "clear_edges sets edge to NULL");
+}
+
+void test_single_node() {
+ node_t n = {NULL, 42, 0, &dt_one};
+ dt_update(&n);
+ ASSERT_FLOAT_EQ(n.x, 1, "single node with dt_one");
+}
+
+int main() {
+ test_connect();
+ test_disconnect();
+ test_add();
+ test_subtract();
+ test_multiple_connections();
+ test_chained_addition();
+ test_clear_edges();
+ test_single_node();
+ test_connect_ok_null();
+
+ printf("test_direct: %d failures\n", failures);
+ return failures;
+}