aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--Makefile5
-rw-r--r--tests/Makefile39
-rw-r--r--tests/fib/fib.fwd24
-rw-r--r--tests/fib/test.mk1
-rw-r--r--tests/ptrs/ptrs.fwd8
-rw-r--r--tests/ptrs/test.mk1
-rwxr-xr-xtests/scripts/gen-xfail29
-rwxr-xr-xtests/scripts/gen-xpass15
-rw-r--r--tests/scripts/makefile19
10 files changed, 143 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
index d07d688..bd4f9aa 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,3 +6,5 @@ fwd
gen/*.c
gen/*.inc
!include/fwd
+reports
+tests.mk
diff --git a/Makefile b/Makefile
index 0485621..1f20ab0 100644
--- a/Makefile
+++ b/Makefile
@@ -25,6 +25,10 @@ setup:
@echo -n > deps.mk
@./scripts/gen-deps -p FWD -c COMPILE_FWD -b fwd "$(FWD_SOURCES)"
+.PHONY: check
+check: all
+ $(MAKE) -C tests -k check
+
CLEANUP := build deps.mk fwd
CLEANUP_CMD :=
FWD_SOURCES :=
@@ -51,6 +55,7 @@ RM = rm
.PHONY: clean
clean:
+ $(MAKE) -C tests clean
$(RM) -rf $(CLEANUP)
.PHONY: clean_docs
diff --git a/tests/Makefile b/tests/Makefile
new file mode 100644
index 0000000..ce009fc
--- /dev/null
+++ b/tests/Makefile
@@ -0,0 +1,39 @@
+check:
+ $(MAKE) -f scripts/makefile check
+
+.DEFAULT:
+ $(MAKE) -f scripts/makefile $<
+
+TESTS != find . -name test.mk
+DO != echo -n > tests.mk && rm -rf reports
+
+# collect tests that are expected to pass into XPASS, each testcase is assumed
+# to be in a separate directory, let's call it $NAME, and have a $NAME/test.mk
+# file which just appends the $NAME of to XPASS if the test should pass, so
+#
+# XPASS += $NAME
+#
+# or to XFAIL along, with the expected error message with the format
+#
+# XFAIL += $NAME,'error message'
+#
+# Note that it's very important to use single quotes here, otherwise Make might
+# start splitting the error message along spaces into arguments.
+#
+# Each test is assumed to have a fwd file called $NAME/$NAME.fwd, which should
+# exercise some part of the compiler. The test framework links all libraries in
+# `../mod` into the binary automatically. Test logs, along with some other
+# useful stuff, is written out to `reports/$NAME`.
+XPASS :=
+XFAIL :=
+
+include $(TESTS)
+
+DO != ./scripts/gen-xpass $(XPASS)
+DO != ./scripts/gen-xfail $(XFAIL)
+
+RM ?= rm
+
+.PHONY: clean
+clean:
+ $(RM) -rf reports
diff --git a/tests/fib/fib.fwd b/tests/fib/fib.fwd
new file mode 100644
index 0000000..e07d8af
--- /dev/null
+++ b/tests/fib/fib.fwd
@@ -0,0 +1,24 @@
+import "../../mod/libfwdio.so"
+
+fib(i64 n, (i64) res)
+{
+ if n < 2 {
+ res(1);
+ } else {
+ fib(n - 1) => i64 f1;
+ fib(n - 2) => i64 f2;
+ res(f1 + f2);
+ }
+}
+
+main()
+{
+ fib(20) => i64 n;
+ if n == 10946 {
+ fwdprint_str("OK\n");
+ } else {
+ fwdprint_str("expected 10946, got ");
+ fwdprint_i64(n);
+ fwdprint_nl();
+ }
+}
diff --git a/tests/fib/test.mk b/tests/fib/test.mk
new file mode 100644
index 0000000..3ace25e
--- /dev/null
+++ b/tests/fib/test.mk
@@ -0,0 +1 @@
+XPASS += fib
diff --git a/tests/ptrs/ptrs.fwd b/tests/ptrs/ptrs.fwd
new file mode 100644
index 0000000..fbb9cbb
--- /dev/null
+++ b/tests/ptrs/ptrs.fwd
@@ -0,0 +1,8 @@
+import "../../mod/libfwdmem.so"
+
+main()
+{
+ fwdmalloc(sizeof(i64)) => *i64 i;
+ /* deref not allowed on raw pointers */
+ i* + 20 => int something;
+}
diff --git a/tests/ptrs/test.mk b/tests/ptrs/test.mk
new file mode 100644
index 0000000..3003a8c
--- /dev/null
+++ b/tests/ptrs/test.mk
@@ -0,0 +1 @@
+XFAIL += ptrs,'deref of raw ptr not allowed'
diff --git a/tests/scripts/gen-xfail b/tests/scripts/gen-xfail
new file mode 100755
index 0000000..c4cf382
--- /dev/null
+++ b/tests/scripts/gen-xfail
@@ -0,0 +1,29 @@
+#!/bin/sh
+
+mkdir -p $(for d in "${@}"; do echo "$d"; done \
+ | sed "s|,.*||" | uniq | sed "s|^|reports/|")
+
+for s in "${@}"
+do
+ NAME=${s%%,*}
+ EMSG=${s#${NAME},}
+ echo ".PHONY: $NAME" >> tests.mk
+ echo "$NAME:" >> tests.mk
+ echo " ../fwd $NAME/$NAME.fwd \\" >> tests.mk
+ echo " > reports/$NAME/gen.c 2> reports/$NAME/log \\" >> tests.mk
+ echo " && echo 'Wrong retval' > reports/$NAME/OK \\" >> tests.mk
+ echo " || :" >> tests.mk
+ echo " grep '$EMSG' reports/$NAME/log > /dev/null \\" >> tests.mk
+ echo " && echo OK > reports/$NAME/OK \\" >> tests.mk
+ echo " || echo EMSG > reports/$NAME/OK" >> tests.mk
+done
+
+echo -n "TESTS +=" >> tests.mk
+for s in "${@}"
+do
+ NAME=${s%%,*}
+ echo -n " $NAME" >> tests.mk
+done
+
+# append newline
+echo "" >> tests.mk
diff --git a/tests/scripts/gen-xpass b/tests/scripts/gen-xpass
new file mode 100755
index 0000000..762650e
--- /dev/null
+++ b/tests/scripts/gen-xpass
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+mkdir -p $(for d in "${@}"; do echo "$d"; done | uniq | sed "s|^|reports/|")
+
+for s in "${@}"
+do
+ echo ".PHONY: $s" >> tests.mk
+ echo "$s:" >> tests.mk
+ echo " ../fwd $s/$s.fwd > reports/$s/gen.c 2> reports/$s/log" >> tests.mk
+ echo " \$(COMPILE_TEST) reports/$s/gen.c -o reports/$s/$s \\" >> tests.mk
+ echo " \$(TEST_LIBS)" >> tests.mk
+ echo " ./reports/$s/$s > reports/$s/OK 2>&1" >> tests.mk
+done
+
+echo "TESTS += " "${@}" >> tests.mk
diff --git a/tests/scripts/makefile b/tests/scripts/makefile
new file mode 100644
index 0000000..21b1418
--- /dev/null
+++ b/tests/scripts/makefile
@@ -0,0 +1,19 @@
+.PHONY: all
+all: check
+
+COMPILE_TEST := $(CC) -L../mod -I../include -I../lib -Wl,-rpath=../mod -O2
+TEST_LIBS := -lfwdio -lfwdmem -lfwdutil
+
+TESTS :=
+include tests.mk
+
+.PHONY: check
+check: $(TESTS)
+ @cd reports; for d in * ; do \
+ if [ ! -f "$$d/OK" ]; then \
+ echo "BROKEN: $$d" ; \
+ elif [ "$$(tail -n1 $$d/OK)" != "OK" ]; then \
+ echo "FAIL: $$d" ; \
+ fi \
+ done
+ @echo "Done."