From 096074509441f1ae1d10120ab4d12a328af09464 Mon Sep 17 00:00:00 2001 From: Sami Samhuri Date: Sun, 1 May 2011 21:01:57 -0700 Subject: [PATCH] add test for core lake functions --- test/Makefile | 6 +- test/laketest.c | 10 +++ test/laketest.h | 2 + test/test_lake.c | 187 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 203 insertions(+), 2 deletions(-) create mode 100644 test/test_lake.c diff --git a/test/Makefile b/test/Makefile index 5c6fab3..6aeebb7 100644 --- a/test/Makefile +++ b/test/Makefile @@ -2,10 +2,9 @@ CC = gcc CFLAGS := -Wall -g -I../src $(shell pkg-config --cflags glib-2.0) LFLAGS := $(shell pkg-config --libs glib-2.0) OBJS = ../build/liblake.a -TESTS = test_comment test_dlist test_env test_eval test_fn test_int +TESTS = test_comment test_dlist test_env test_eval test_fn test_int test_lake all: $(TESTS) - @clear @for test in $(TESTS); do \ echo; \ ./$$test; \ @@ -31,6 +30,9 @@ test_fn: laketest.o test_fn.o test_int: laketest.o test_int.o $(CC) $(CFLAGS) $(LFLAGS) $^ $(OBJS) -o $@ +test_lake: laketest.o test_lake.o + $(CC) $(CFLAGS) $(LFLAGS) $^ $(OBJS) -o $@ + clean: -rm -f *.o $(TESTS) diff --git a/test/laketest.c b/test/laketest.c index 9d109a7..05e7d3d 100644 --- a/test/laketest.c +++ b/test/laketest.c @@ -11,8 +11,12 @@ #include #include +#include #include +#include "eval.h" +#include "lake.h" #include "laketest.h" +#include "parse.h" static int captured = 0; @@ -64,3 +68,9 @@ int lt_run_tests(char *title, test_fn *tests) } return pass; } + +LakeVal *lt_eval(LakeCtx *lake, char *s) +{ + LakeVal *v = parse_expr(lake, s, strlen(s)); + return eval(lake, lake->toplevel, v); +} diff --git a/test/laketest.h b/test/laketest.h index eceb2f8..77cf5c4 100644 --- a/test/laketest.h +++ b/test/laketest.h @@ -10,6 +10,7 @@ */ #include +#include "lake.h" void restore_output(void); @@ -26,3 +27,4 @@ typedef char *(*test_fn)(void); /* Returns non-zero if all passed, or zero if any failed */ int lt_run_tests(char *title, test_fn *tests); +LakeVal *lt_eval(LakeCtx *lake, char *s); \ No newline at end of file diff --git a/test/test_lake.c b/test/test_lake.c new file mode 100644 index 0000000..bb73141 --- /dev/null +++ b/test/test_lake.c @@ -0,0 +1,187 @@ +/** + * test_lake.c + * Lake Scheme + * + * Copyright 2011 Sami Samhuri + * MIT License + * + */ + +#include "laketest.h" +#include "int.h" +#include "lake.h" +#include "str.h" +#include "sym.h" + +static LakeCtx *lake; + +/* #define LAKE_VERSION "0.1" */ +static char *test_lake_version(void) +{ + lt_assert("LAKE_VERSION is not set", NULL != LAKE_VERSION); + return 0; +} + +/* LakeCtx *lake_init(void) */ +static char *test_lake_init(void) +{ + lt_assert("lake_init returned null", NULL != lake); + lt_assert("toplevel is null", NULL != lake->toplevel); + lt_assert("symbol table is null", NULL != lake->symbols); + lt_assert("special form handlers map is null", + NULL != lake->special_form_handlers); + lt_assert("T is null", NULL != lake->T); + lt_assert("F is null", NULL != lake->F); + lt_assert("T is not a boolean", IS(TYPE_BOOL, lake->T)); + lt_assert("F is not a boolean", IS(TYPE_BOOL, lake->F)); + lt_assert("value of T is zero", BOOL_VAL(lake->T)); + lt_assert("value of F is non-zero", !BOOL_VAL(lake->F)); + return 0; +} + +static gboolean _is(void *a, void *b) +{ + return lake_is(VAL(a), VAL(b)); +} + +/* gboolean lake_is(LakeVal *a, LakeVal *b) */ +static char *test_lake_is(void) +{ + LakeInt *i = int_from_c(42); + + // ints are compared by value + lt_assert("ints with equal values are not the same", _is(i, int_from_c(42))); + + // nil is compared by value + lt_assert("null values are not the same", _is(list_make(), list_make())); + + // everything else compared by reference + LakeList *a = list_make(); + LakeList *b = list_make(); + list_append(a, VAL(i)); + list_append(b, VAL(i)); + lt_assert("distinct lists are the same", !_is(a, b)); + lt_assert("list is not itself", _is(a, a)); + + return 0; +} + +static gboolean _equal(void *a, void *b) +{ + return lake_equal(VAL(a), VAL(b)); +} + +/* gboolean lake_equal(LakeVal *a, LakeVal *b) */ +static char *test_lake_equal(void) +{ + LakeInt *i = int_from_c(42); + LakeInt *j = int_from_c(42); + LakeStr *arthur = str_from_c("arthur"); + + // values with different types are never equal + lt_assert("values with different types are equal", !_equal(i, arthur)); + + // symbols are compared by reference + LakeSym *a = sym_intern(lake, "a"); + LakeSym *a2 = sym_intern(lake, "a"); + LakeSym *b = sym_intern(lake, "b"); + lt_assert("symbol is not equal to itself", _equal(a, a)); + lt_assert("symbol is not equal to itself", _equal(a, a2)); + lt_assert("different symbols are equal", !_equal(a, b)); + + // booleans are compared by reference + lt_assert("true is not equal to itself", _equal(lake->T, lake->T)); + lt_assert("true is equal to false", !_equal(lake->T, lake->F)); + + // primitives are compared by reference + LakePrimitive *null = PRIM(lt_eval(lake, "null?")); + LakePrimitive *null2 = PRIM(lt_eval(lake, "null?")); + LakePrimitive *pair = PRIM(lt_eval(lake, "pair?")); + lt_assert("primitive is not equal to itself", _equal(null, null)); + lt_assert("primitive is not equal to itself", _equal(null, null2)); + lt_assert("different primitives are equal to each other", !_equal(null, pair)); + + // functions are compared by reference + LakeFn *inc = FN(lt_eval(lake, "(lambda (x) (+ x 1))")); + LakeFn *inc1 = FN(lt_eval(lake, "(lambda (x) (+ x 1))")); + lt_assert("functions is not equal to itself", _equal(inc, inc)); + lt_assert("distinct functions are equal to each other", !_equal(inc, inc1)); + + // ints are compared by value + lt_assert("ints with the same value are not equal", _equal(i, j)); + lt_assert("int is not equal to itself", _equal(i, i)); + + // strings are compared by value + LakeStr *arthur2 = str_from_c("arthur"); + LakeStr *zaphod = str_from_c("zaphod"); + lt_assert("string is not equal to itself", _equal(arthur, arthur)); + lt_assert("string is not equal to itself", _equal(arthur, arthur2)); + lt_assert("different strings are equal", !_equal(arthur, zaphod)); + + // lists are compared by value + #define S(s) VAL(str_from_c(s)) + LakeList *fruits = list_make(); + list_append(fruits, S("mango")); + list_append(fruits, S("pear")); + list_append(fruits, S("pineapple")); + + LakeList *ninjas = list_make(); + list_append(ninjas, S("donatello")); + list_append(ninjas, S("leonardo")); + list_append(ninjas, S("michelangelo")); + list_append(ninjas, S("raphael")); + + lt_assert("list is not equal to itself", _equal(fruits, fruits)); + lt_assert("different lists are equal", !_equal(fruits, ninjas)); + + LakeList *fruits_copy = list_copy(fruits); + lt_assert("copy of list is not equal to original", _equal(fruits, fruits_copy)); + #undef S + + // dotted lists are compared by value + LakeDottedList *destruction = dlist_make(fruits, VAL(ninjas)); + LakeDottedList *mayhem = dlist_make(ninjas, VAL(destruction)); + LakeDottedList *more_destruction = dlist_make(fruits, VAL(ninjas)); + lt_assert("dotted list is not equal to itself", _equal(mayhem, mayhem)); + lt_assert("different dotted lists are equal", !_equal(destruction, mayhem)); + lt_assert("identical dotted lists are not equal", + _equal(destruction, more_destruction)); + + // comments are compared by value + LakeComment *comment = comment_from_c("a comment"); + LakeComment *different = comment_from_c("a different comment"); + LakeComment *same = comment_from_c("a comment"); + lt_assert("comment is not equal to itself", _equal(comment, comment)); + lt_assert("different comments are equal", !_equal(comment, different)); + lt_assert("identical comments are not equal", _equal(comment, same)); + + // else FALSE + lt_assert("LakeCtx was compared by lake_equal", !_equal(lake, lake)); + + return 0; +} + +/* char *lake_repr(LakeVal *val) */ +static char *test_lake_repr(void) +{ + /* TODO */ + return 0; +} + +void setup(void) +{ + lake = lake_init(); +} + +int main(int argc, char const *argv[]) +{ + setup(); + return !lt_run_tests("Lake", (test_fn[]){ + test_lake_version, + test_lake_init, + test_lake_is, + test_lake_equal, + test_lake_repr, + NULL + }); +} \ No newline at end of file