chiark / gitweb /
test/test.sod: New file containing miscellaneous tests.
authorMark Wooding <mdw@distorted.org.uk>
Tue, 5 Jan 2016 17:20:55 +0000 (17:20 +0000)
committerMark Wooding <mdw@distorted.org.uk>
Sun, 29 May 2016 13:40:40 +0000 (14:40 +0100)
Currently there's just a tidied-up version of the aggregating method
combination tests I was using during development.

test/Makefile.am
test/test.sod [new file with mode: 0644]
vars.am

index abd524e3b7b4de9e286e1f6becc75b58e7cb7823..08d6625e708f70fd372e6526f1e5ab60775a3f2a 100644 (file)
@@ -40,4 +40,12 @@ check-local:: chimaera chimaera.ref
        ./chimaera >chimaera.out
        diff -u $(srcdir)/chimaera.ref chimaera.out
 
+###--------------------------------------------------------------------------
+### Other tests.
+
+TESTS                  += test
+check_PROGRAMS         += test
+nodist_test_SOURCES     = test.c test.h
+BUILT_SOURCES          += $(nodist_test_SOURCES)
+
 ###----- That's all, folks --------------------------------------------------
diff --git a/test/test.sod b/test/test.sod
new file mode 100644 (file)
index 0000000..e5025b5
--- /dev/null
@@ -0,0 +1,205 @@
+/* -*-sod-*- */
+
+code h : includes {
+#include "sod.h"
+}
+
+code c : includes {
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "test.h"
+}
+
+code c : early_user {
+/*----- Preliminary definitions -------------------------------------------*/
+
+/* Confuse the fragment scanner... */
+#define LBRACE {
+#define RBRACE }
+
+static const char *test_name;
+static int test_seq;
+
+static void prepare(const char *name) { test_name = name; test_seq = 0; }
+
+static void step(int q, const char *where)
+{
+  if (test_seq != q) {
+    fprintf(stderr, "test %s (%s): step %d instead of %d\n",
+           test_name, where, q, test_seq);
+    abort();
+  }
+  test_seq++;
+}
+
+static void done(int q, const char *where) { step(q, where); }
+
+#define STRINGIFY_(x) #x
+#define STRINGIFY(x) STRINGIFY_(x)
+#define WHERE __FILE__ ":" STRINGIFY(__LINE__)
+#define STEP(q) step((q), WHERE)
+#define DONE(q) done((q), WHERE)
+
+}
+
+code c : (tests head)
+  [user (tests head) tests (tests tail) main (user end)]
+{
+/*----- Test machinery ----------------------------------------------------*/
+
+static void tests(void)
+LBRACE
+}
+code c : (tests tail) {
+RBRACE
+
+}
+
+code c : main {
+/*----- Main program ------------------------------------------------------*/
+
+int main(void)
+{
+  tests();
+  return (0);
+}
+
+}
+
+/*----- Various kinds of method combinations ------------------------------*/
+
+code h : early_user {
+struct item {
+  struct item *next;
+  const char *p;
+};
+
+}
+
+code c : early_user {
+static void *xmalloc(size_t n)
+{
+  void *p = malloc(n);
+  if (!p) { perror("malloc"); exit(EXIT_FAILURE); }
+  return (p);
+}
+
+static struct item *make_item(const char *p)
+  { struct item *q = xmalloc(sizeof(*q)); q->p = p; return (q); }
+
+static void free_list(struct item *i)
+  { struct item *ii; while (i) { ii = i->next; free(i); i = ii; } }
+
+static int check_list(struct item *i, ...)
+{
+  va_list ap;
+  const char *p;
+  int rc = -1;
+
+  va_start(ap, i);
+  for (;;) {
+    p = va_arg(ap, const char *);
+    if (!p) break;
+    if (!i || strcmp(i->p, p) != 0) break;
+    i = i->next;
+  }
+  if (!i) rc = 0;
+  va_end(ap);
+  return (rc);
+}
+
+struct vec { int *v; size_t n; };
+
+static void free_vec(struct vec *v) { free(v->v); }
+
+static int check_vec(struct vec *v, ...)
+{
+  va_list ap;
+  int j;
+  size_t i = 0;
+  int rc = -1;
+
+  va_start(ap, v);
+  for (;;) {
+    j = va_arg(ap, int);
+    if (j < 0) break;
+    if (i == v->n || j != v->v[i]) break;
+    i++;
+  }
+  if (i == v->n) rc = 0;
+  va_end(ap);
+  return (rc);
+}
+
+}
+
+[link = SodObject, nick = t1base]
+class T1Base : SodObject {
+  [combination = progn] void aprogn() { STEP(1); }
+  [combination = sum] int asum() { return 1; }
+  [combination = and] int aand() { return 8; }
+  [combination = max] int amax() { return 12; }
+
+  [combination = custom,
+   decls = { struct item **head = &sod_ret; },
+   each = { *head = sod_val; head = &sod_val->next; },
+   after = { *head = 0; }]
+  struct item *alist() { return make_item("base"); }
+
+  [combination = custom,
+   decls = { int *v; size_t i = 0; }, methty = <int>, count = n,
+   before = { v = xmalloc(n*sizeof(int)); },
+   each = { v[i++] = sod_val; },
+   after = { sod_ret.v = v; sod_ret.n = n; }]
+  struct vec avec();
+  int t1base.avec() { return 19; }
+}
+
+[link = T1Base, nick = t1sub]
+class T1Sub : T1Base {
+  void t1base.aprogn() { STEP(0); }
+  int t1base.asum() { return 2; }
+  int t1base.aand() { return 6; }
+  int t1base.amax() { return 17; }
+  struct item *t1base.alist() { return make_item("sub"); }
+  int t1base.avec() { return 4; }
+}
+
+code c : tests {
+  prepare("aggregate, base");
+  { SOD_DECL(T1Base, t1);
+    struct item *l;
+    struct vec v;
+    STEP(0); T1Base_aprogn(t1); /* 1 */
+    if (T1Base_asum(t1) == 1) STEP(2);
+    if (T1Base_aand(t1) == 8) STEP(3);
+    if (T1Base_amax(t1) == 12) STEP(4);
+    l = T1Base_alist(t1);
+    if (!check_list(l, "base", (const char *)0)) STEP(5);
+    free_list(l);
+    v = T1Base_avec(t1);
+    if (!check_vec(&v, 19, -1)) STEP(6);
+    free_vec(&v);
+    DONE(7);
+  }
+  prepare("aggregate, sub");
+  { SOD_DECL(T1Sub, t1);
+    struct item *l;
+    struct vec v;
+    T1Base_aprogn(t1); /* 0, 1 */
+    if (T1Base_asum(t1) == 3) STEP(2);
+    if (T1Base_aand(t1) == 8) STEP(3);
+    if (T1Base_amax(t1) == 17) STEP(4);
+    l = T1Base_alist(t1);
+    if (!check_list(l, "sub", "base", (const char *)0)) STEP(5);
+    free_list(l);
+    v = T1Base_avec(t1);
+    if (!check_vec(&v, 4, 19, -1)) STEP(6);
+    free_vec(&v);
+    DONE(7);
+  }
+}
+
+/*----- That's all, folks -------------------------------------------------*/
diff --git a/vars.am b/vars.am
index dd7b931a76085c05233e05554b2bc9d781c39631..0c83837fd67e53a218b7ff66d48d8d3f85d0f568 100644 (file)
--- a/vars.am
+++ b/vars.am
@@ -42,6 +42,7 @@ BUILT_SOURCES          =
 bin_PROGRAMS            =
 check_PROGRAMS          =
 pkginclude_HEADERS      =
+TESTS                   =
 
 dist_man_MANS           =