commit 1715f48abd1f7070eb0ae0ba44fde2a9483a6c41
parent 0f61313c2da4475e6f114570e14f03f9add56b07
Author: Ed van Bruggen <edvb@uw.edu>
Date: Thu, 3 Jan 2019 20:28:02 -0800
Write unit tests in C
Diffstat:
29 files changed, 251 insertions(+), 286 deletions(-)
diff --git a/Makefile b/Makefile
@@ -4,9 +4,10 @@
include config.mk
EXE = tisp
-SRC = $(wildcard *.c */*.c)
-OBJ = $(SRC:.c=.o)
-LIB = tib/libtibmath.so
+SRC = tisp.c main.c util.c extern/linenoise.c
+TIB = tib/math.c tib/io.c
+OBJ = $(SRC:.c=.o) $(TIB:.c=.o)
+LIB = tib/libtibmath.so tib/libtibio.so
all: options $(EXE)
@@ -29,7 +30,7 @@ config.h:
@echo creating $@ from config.def.h
@cp config.def.h $@
-$(LIB): $(wildcard tib/*.c)
+$(LIB): $(TIB)
@echo $(CC) -o $@
@gcc -shared -o $@ $(OBJ)
@@ -39,7 +40,7 @@ $(EXE): $(OBJ) $(LIB)
clean:
@echo cleaning
- @rm -f $(OBJ) $(LIB) $(EXE)
+ @rm -f $(OBJ) $(LIB) $(EXE) test test.o test.out
install: all
@echo installing $(EXE) to $(DESTDIR)$(PREFIX)/bin
@@ -62,9 +63,11 @@ uninstall:
@echo removing libraries from $(DESTDIR)$(PREFIX)/lib/tisp
@rm -rf $(DESTDIR)$(PREFIX)/lib/tisp/
-test: $(EXE)
+test: $(OBJ) $(LIB) test.o
@echo running tests
- @cd t && ./t
+ @echo $(CC) -o test
+ @$(CC) -o test tisp.o tib/math.o util.o test.o $(LDFLAGS)
+ @./test
man:
@echo -n updating man page $(EXE).1 ...
@@ -79,4 +82,4 @@ man:
md2roff - | sed "9s/]/]\ /g" | sed "9s/|/|\ /g" > $(EXE).1
@echo \ done
-.PHONY: all options clean install uninstall man
+.PHONY: all options clean install uninstall test man
diff --git a/t/math/add.expect b/t/math/add.expect
@@ -1,3 +0,0 @@
-2
-4
-1312
diff --git a/t/math/add.tsp b/t/math/add.tsp
@@ -1,3 +0,0 @@
-(+ 1 1)
-(+ 1 (+ 1 2))
-(+ 1029 283)
diff --git a/t/math/compare.expect b/t/math/compare.expect
@@ -1,12 +0,0 @@
-t
-()
-()
-t
-t
-()
-t
-()
-()
-t
-t
-()
diff --git a/t/math/compare.tsp b/t/math/compare.tsp
@@ -1,12 +0,0 @@
-(< 2 3)
-(< 3 3)
-(< 4 3)
-(<= -2 +4)
-(<= -2 -2)
-(<= 4 -2)
-(> 89 34)
-(> 48 48)
-(> 98 183)
-(>= +4 -282)
-(>= 39 39)
-(>= -32 -30)
diff --git a/t/math/sub.expect b/t/math/sub.expect
@@ -1,5 +0,0 @@
--3
--3
-289
-1
--35
diff --git a/t/math/sub.tsp b/t/math/sub.tsp
@@ -1,5 +0,0 @@
-(- 3)
-(- +3)
-(- -289)
-(- 5 4)
-(- 53 88)
diff --git a/t/prim/cond.expect b/t/prim/cond.expect
@@ -1,8 +0,0 @@
-()
-1
-1
-3
-2
-()
-2
-()
diff --git a/t/prim/cond.tsp b/t/prim/cond.tsp
@@ -1,8 +0,0 @@
-(cond)
-(cond (t 1))
-(cond ((= 1 1) 1) ((= 1 2) 2) (t 3))
-(cond ((= 1 2) 1) ((= 1 2) 2) (t (+ 1 2)))
-(cond ((= 1 2) 1) ((= 1 1) 2) (t 3))
-(cond ((= 1 2) 1) ((= 1 3) 2))
-(cond ((= 1 2) 1) ("foo" 2) (t 3))
-(cond (() (+ 1 2)))
diff --git a/t/prim/cons.expect b/t/prim/cons.expect
@@ -1,6 +0,0 @@
-(1 . 2)
-(1 2 . 3)
-(1 2 3 . 4)
-("foo" . "bar")
-(3 . 3)
-((1 . 2) 3 . 4)
diff --git a/t/prim/cons.tsp b/t/prim/cons.tsp
@@ -1,6 +0,0 @@
-(cons 1 2)
-(cons 1 (cons 2 3))
-(cons 1 (cons 2 (cons 3 4)))
-(cons "foo" "bar")
-(cons (+ 1 2) 3)
-(cons (cons 1 2) (cons 3 4))
diff --git a/t/prim/cxr.expect b/t/prim/cxr.expect
@@ -1,11 +0,0 @@
-1
-2
-1
-2
-3
-4
-(2 3 4)
-(3 4)
-1
-(2 . 3)
-3
diff --git a/t/prim/cxr.tsp b/t/prim/cxr.tsp
@@ -1,14 +0,0 @@
-(car (cons 1 2))
-(cdr (cons 1 2))
-
-(car (quote (1 2 3 4)))
-(car (cdr (quote (1 2 3 4))))
-(car (cdr (cdr (quote (1 2 3 4)))))
-(car (cdr (cdr (cdr (quote (1 2 3 4))))))
-
-(cdr (quote (1 2 3 4)))
-(cdr (cdr (quote (1 2 3 4))))
-
-(car (cons 1 (cons 2 3)))
-(cdr (cons 1 (cons 2 3)))
-(cdr (cdr (cons 1 (cons 2 3))))
diff --git a/t/prim/define.expect b/t/prim/define.expect
@@ -1,3 +0,0 @@
-4
-4
-8
diff --git a/t/prim/define.tsp b/t/prim/define.tsp
@@ -1,6 +0,0 @@
-(define foo 4)
-foo
-(define bar foo)
-bar
-(define add +)
-(add foo bar)
diff --git a/t/prim/eq.expect b/t/prim/eq.expect
@@ -1,29 +0,0 @@
-t
-t
-t
-t
-t
-()
-()
-()
-()
-t
-t
-t
-t
-()
-()
-()
-()
-t
-t
-()
-t
-()
-()
-()
-()
-t
-t
-()
-t
diff --git a/t/prim/eq.tsp b/t/prim/eq.tsp
@@ -1,29 +0,0 @@
-(=)
-(= 1)
-(= "foo")
-(= 1 1)
-(= 1 1 1 1 1 1)
-(= 1 2)
-(= 1 1 2 1 1 1)
-(= 1 1 1 1 1 2)
-(= 2 1 1 1 1 1)
-(= 4/5 4/5)
-(= 2/1 2)
-(= 2/4 1/2)
-(= 2/4 1/2 4/8 3/6)
-(= 1/2 4/5)
-(= 5/4 4/5)
-(= 3 3/2)
-(= 3 3/2 3 3 3)
-(= (+ 1 1) (+ 2 0))
-(= "foo" "foo")
-(= "foo" "bar")
-(= "foo" "foo" "foo" "foo" "foo")
-(= "foo" "bar" "foo" "foo" "foo")
-(= "foo" 3)
-(= "foo" "foo" 4 "foo" "foo")
-(= "foo" "FOO")
-(= t t)
-(= car car)
-(= car cdr)
-(= quote quote quote)
diff --git a/t/prim/lambda.expect b/t/prim/lambda.expect
@@ -1,5 +0,0 @@
-3
-3
-9
-4
-5
diff --git a/t/prim/lambda.tsp b/t/prim/lambda.tsp
@@ -1,5 +0,0 @@
-((lambda (x) x) 3)
-((lambda (x) x) (+ 1 2))
-((lambda (x) (+ x 1)) 8)
-((lambda (a b) (+ a b)) 2 2)
-((lambda () 5))
diff --git a/t/prim/quote.expect b/t/prim/quote.expect
@@ -1,10 +0,0 @@
-1
-9234
-"foo"
-bar
-(1 2 3 4)
-(quote 1)
-(+ 2 2)
-12
-foo
-(1 2 3 4)
diff --git a/t/prim/quote.tsp b/t/prim/quote.tsp
@@ -1,11 +0,0 @@
-(quote 1)
-(quote 9234)
-(quote "foo")
-(quote bar)
-(quote (1 2 3 4))
-(quote (quote 1))
-(quote (+ 2 2))
-
-'12
-'foo
-'(1 2 3 4)
diff --git a/t/simple/comments.expect b/t/simple/comments.expect
@@ -1,2 +0,0 @@
-2
-4
diff --git a/t/simple/comments.tsp b/t/simple/comments.tsp
@@ -1,11 +0,0 @@
-; commment
-; (+ 1 1)
-(+ 1 ; more comments
- 1)
-
- ; white space too
- (+ 2 2)
-
-
-
-; another comment
diff --git a/t/simple/frac.expect b/t/simple/frac.expect
@@ -1,11 +0,0 @@
-3/4
-4/3
-1/2
-2
-2
-1/2
-1192/3619
--1/2
--1/2
--2
-2
diff --git a/t/simple/frac.tsp b/t/simple/frac.tsp
@@ -1,11 +0,0 @@
-3/4
-4/3
-1/2
-2/1
-8/4
-4/8
-02384/7238
--1/2
-1/-2
--6/3
--6/-3
diff --git a/t/simple/self.expect b/t/simple/self.expect
@@ -1,14 +0,0 @@
-1
-2
-0
-30
-12
--4
--83
-0
-4
-123
-"foo"
-"foo bar"
-t
-()
diff --git a/t/simple/self.tsp b/t/simple/self.tsp
@@ -1,14 +0,0 @@
-1
-2
-0
-30
-12
--4
--083
--0
-+4
-+123
-"foo"
-"foo bar"
-t
-()
diff --git a/t/t b/t/t
@@ -1,24 +0,0 @@
-#!/usr/bin/env bash
-
-total=0
-pass=0
-
-export LD_LIBRARY_PATH="$PWD/../tib:$LD_LIBRARY_PATH"
-
-for file in */*.tsp; do
- expect=${file%.tsp}.expect
-
- echo -n "testing $file ... "
- if [[ $(../tisp "$file" 2>&1 | diff -q "$expect" - 2>&1 ) ]]; then
- echo fail
- else
- echo ok
- ((pass++))
- fi
- ((total++))
-done
-
-echo "$pass/$total tests passed"
-
-[[ $pass == $total ]] && exit 0
-exit 1
diff --git a/test.c b/test.c
@@ -0,0 +1,240 @@
+/* See LICENSE file for copyright and license details. */
+#include <assert.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "../util.h"
+#include "../tisp.h"
+#include "../tib/math.h"
+
+int
+tisp_test(Env env, const char *input, const char *expect)
+{
+ struct Str str;
+ Val v;
+ FILE *f = fopen("test.out", "w");
+ size_t nread;
+ char buf[BUFSIZ] = {0};
+
+ str.d = strdup(input);
+ v = tisp_read(env, &str);
+ if (!(v = tisp_eval(env, v)))
+ return 0;
+
+ tisp_print(f, v);
+ fclose(f);
+ f = fopen("test.out", "r");
+ while ((nread = fread(buf, 1, sizeof(buf), f)) > 0) ;
+
+ return strcmp(buf, expect) == 0;
+}
+
+/* TODO mark and show which lines error-ed */
+char *tests[][2] = {
+
+ { "self", NULL },
+ { "1", "1" },
+ { "2", "2" },
+ { "0", "0" },
+ { "30", "30" },
+ { "12", "12" },
+ { "-4", "-4" },
+ { "-083", "-83" },
+ { "-0", "0" },
+ { "+4", "4" },
+ { "+123", "123" },
+ { "12.0", "12.0" },
+ { "08", "8" },
+ { "+12.34", "12.3" },
+ { ".34", "0.3" },
+ { "2.", "2.0" },
+ { "1e0", "1" },
+ { "1E+0", "1" },
+ { "1e-0", "1" },
+ { "1E4", "10000" },
+ { ".1e-4", "0.0" },
+ { "-5.0e006", "-5000000.0" },
+ { "-5.E+16", "-50000000000000000.0" },
+ { "-.05", "-0.1" },
+ { "-.0", "-0.0" },
+ { "-1.e6", "-1000000.0" },
+ { "\"foo\"", "\"foo\"" },
+ { "\"foo bar\"", "\"foo bar\"" },
+ { "t", "t" },
+ { "()", "()" },
+
+ { "frac", NULL },
+ { "3/4", "3/4" },
+ { "4/3", "4/3" },
+ { "+1/2", "1/2" },
+ { "2/1", "2" },
+ { "8/+1", "8" },
+ { "8/4", "2" },
+ { "4/8", "1/2" },
+ { "02384/7238", "1192/3619" },
+ { "-1/2", "-1/2" },
+ { "1/-2", "-1/2" },
+ { "-6/3", "-2" },
+ { "-6/-3", "2" },
+
+ { "comments", NULL },
+ { "; commment", "()" },
+ { "; (+ 1 1)", "()" },
+ { "(+ 1 ; more comments\n1)", "2" },
+
+ { "whitespace", NULL },
+ { "\t \n \n\n\t\n \t\n", "()" },
+ { "\t \t(+ \t\t5 \n \n5 \n\t)", "10" },
+
+ { "quote", NULL },
+ { "(quote 1)", "1" },
+ { "(quote 9234)", "9234" },
+ { "(quote \"foo\")", "\"foo\"" },
+ { "(quote bar)", "bar" },
+ { "(quote (1 2 3 4))", "(1 2 3 4)" },
+ { "(quote (quote 1))", "(quote 1)" },
+ { "(quote (+ 2 2))", "(+ 2 2)" },
+ { "'12", "12" },
+ { "'foo", "foo" },
+ { "'(1 2 3 4)", "(1 2 3 4)" },
+
+ { "cons", NULL },
+ { "(cons 1 2)", "(1 . 2)" },
+ { "(cons 1 (cons 2 3))", "(1 2 . 3)" },
+ { "(cons 1 (cons 2 (cons 3 4)))", "(1 2 3 . 4)" },
+ { "(cons \"foo\" \"bar\")", "(\"foo\" . \"bar\")" },
+ { "(cons (+ 1 2) 3)", "(3 . 3)" },
+ { "(cons (cons 1 2) (cons 3 4))", "((1 . 2) 3 . 4)" },
+
+ { "cxr", NULL },
+ { "(car (cons 1 2))", "1" },
+ { "(cdr (cons 1 2))", "2" },
+ { "(car (quote (1 2 3 4)))", "1" },
+ { "(car (cdr (quote (1 2 3 4))))", "2" },
+ { "(car (cdr (cdr (quote (1 2 3 4)))))", "3" },
+ { "(car (cdr (cdr (cdr (quote (1 2 3 4))))))", "4" },
+ { "(cdr (quote (1 2 3 4)))", "(2 3 4)" },
+ { "(cdr (cdr (quote (1 2 3 4))))", "(3 4)" },
+ { "(car (cons 1 (cons 2 3)))", "1" },
+ { "(cdr (cons 1 (cons 2 3)))", "(2 . 3)" },
+ { "(cdr (cdr (cons 1 (cons 2 3))))", "3" },
+
+ { "cond", NULL },
+ { "(cond)", "()" },
+ { "(cond (t 1))", "1" },
+ { "(cond ((= 1 1) 1) ((= 1 2) 2) (t 3))", "1" },
+ { "(cond ((= 1 2) 1) ((= 1 2) 2) (t (+ 1 2)))", "3" },
+ { "(cond ((= 1 2) 1) ((= 1 1) 2) (t 3))", "2" },
+ { "(cond ((= 1 2) 1) ((= 1 3) 2))", "()" },
+ { "(cond ((= 1 2) 1) (\"foo\" 2) (t 3))", "2" },
+ { "(cond (() (+ 1 2)))", "()" },
+
+ { "eq", NULL },
+ { "(=)", "t" },
+ { "(= 1)", "t" },
+ { "(= \"foo\")", "t" },
+ { "(= 1 1)", "t" },
+ { "(= 1 1 1 1 1 1)", "t" },
+ { "(= 1 2)", "()" },
+ { "(= 1 1 2 1 1 1)", "()" },
+ { "(= 1 1 1 1 1 2)", "()" },
+ { "(= 2 1 1 1 1 1)", "()" },
+ { "(= 4/5 4/5)", "t" },
+ { "(= 2/1 2)", "t" },
+ { "(= 2/4 1/2)", "t" },
+ { "(= 2/4 1/2 4/8 3/6)", "t" },
+ { "(= 1/2 4/5)", "()" },
+ { "(= 5/4 4/5)", "()" },
+ { "(= 3 3/2)", "()" },
+ { "(= 3 3/2 3 3 3)", "()" },
+ { "(= (+ 1 1) (+ 2 0))", "t" },
+ { "(= \"foo\" \"foo\")", "t" },
+ { "(= \"foo\" \"bar\")", "()" },
+ { "(= \"foo\" \"foo\" \"foo\" \"foo\" \"foo\")", "t" },
+ { "(= \"foo\" \"bar\" \"foo\" \"foo\" \"foo\")", "()" },
+ { "(= \"foo\" 3)", "()" },
+ { "(= \"foo\" \"foo\" 4 \"foo\" \"foo\")", "()" },
+ { "(= \"foo\" \"FOO\")", "()" },
+ { "(= t t)", "t" },
+ { "(= car car)", "t" },
+ { "(= car cdr)", "()" },
+ { "(= quote quote quote)", "t" },
+
+ { "define", NULL },
+ { "(define foo 4)", "" },
+ { "foo", "4" },
+ { "(define bar foo)", "" },
+ { "bar", "4" },
+ { "(define add +)", "" },
+ { "(add foo bar)", "8" },
+ { "(define (one x) (add x 1))", "" },
+ { "(one foo)", "5" },
+
+ { "lambda", NULL },
+ { "((lambda (x) x) 3)", "3" },
+ { "((lambda (x) x) (+ 1 2))", "3" },
+ { "((lambda (x) (+ x 1)) 8)", "9" },
+ { "((lambda (a b) (+ a b)) 2 2)", "4" },
+ { "((lambda () 5))", "5" },
+
+ { "add", NULL },
+ { "(+ 1 1)", "2" },
+ { "(+ 1 (+ 1 2))", "4" },
+ { "(+ 1029 283)", "1312" },
+
+ { "sub", NULL },
+ { "(- 3)", "-3" },
+ { "(- +3)", "-3" },
+ { "(- -289)", "289" },
+ { "(- 5 4)", "1" },
+ { "(- 53 88)", "-35" },
+
+ { "compare", NULL },
+ { "(< 2 3)", "t" },
+ { "(< 3 3)", "()" },
+ { "(< 4 3)", "()" },
+ { "(<= -2 +4)", "t" },
+ { "(<= -2 -2)", "t" },
+ { "(<= 4 -2)", "()" },
+ { "(> 89 34)", "t" },
+ { "(> 48 48)", "()" },
+ { "(> 98 183)", "()" },
+ { "(>= +4 -282)", "t" },
+ { "(>= 39 39)", "t" },
+ { "(>= -32 -30)", "()" },
+
+ { NULL, NULL },
+};
+
+int
+main(void)
+{
+ int correct = 0, total = 0, seccorrect = 0, sectotal = 0;
+ Env env = tisp_env_init(64);
+ tib_env_math(env);
+
+ for (int i = 0; ; i++) {
+ if (!tests[i][1]) {
+ if (i != 0)
+ printf("%d/%d\n", seccorrect, sectotal);
+ if (!tests[i][0])
+ break;
+ printf("%-10s ", tests[i][0]);
+ seccorrect = 0;
+ sectotal = 0;
+ } else {
+ if (tisp_test(env, tests[i][0], tests[i][1])) {
+ correct++;
+ seccorrect++;
+ }
+ total++;
+ sectotal++;
+ }
+ }
+ printf("%-10s %d/%d\n", "total", correct, total);
+
+ tisp_env_free(env);
+ return correct != total;
+}