summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsanine-a <sanine.not@pm.me>2021-07-02 22:02:06 -0500
committersanine-a <sanine.not@pm.me>2021-07-02 22:02:06 -0500
commit6416977ea7e2159a67fd6a9877c5e01abe2f8269 (patch)
tree84941ea147ade3eb3545048d6b7cf68b5ee29e0d
parent8c66847bfc4a6af1ca86e916b678a6b8ce58be2f (diff)
begin refactor of tests into individual source files
-rw-r--r--CMakeLists.txt18
-rw-r--r--README.md12
-rw-r--r--src/tests/colors.h (renamed from src/colors.h)0
-rw-r--r--src/tests/hs_create_table_tests.c139
-rw-r--r--src/tests/hs_parse_args_tests.c (renamed from src/test.c)407
-rw-r--r--src/tests/hs_parse_overloaded_tests.c172
-rw-r--r--src/tests/hs_pushstring_tests.c52
-rw-r--r--src/tests/hs_tests.h55
-rw-r--r--src/tests/hs_type_to_string_tests.c102
-rw-r--r--src/tests/tests_main.c28
10 files changed, 575 insertions, 410 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2e02378..0e3eda3 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -15,7 +15,23 @@ set_target_properties(honeysuckle PROPERTIES
PUBLIC_HEADER src/honeysuckle.h)
# optionally build the tests
-add_executable(test EXCLUDE_FROM_ALL src/test.c)
+set(TEST_ROOT ${CMAKE_SOURCE_DIR}/src/tests)
+set(TEST_SOURCES
+ ${TEST_ROOT}/tests_main.c
+ ${TEST_ROOT}/hs_type_to_string_tests.c
+ ${TEST_ROOT}/hs_parse_args_tests.c
+ ${TEST_ROOT}/hs_parse_overloaded_tests.c
+ ${TEST_ROOT}/hs_create_table_tests.c
+ # ${TEST_ROOT}/hs_create_enum_tests.c
+ # ${TEST_ROOT}/hs_process_table_tests.c
+ # ${TEST_ROOT}/hs_throw_error_tests.c
+ # ${TEST_ROOT}/hs_traceback_tests.c
+ # ${TEST_ROOT}/hs_call_tests.c
+ # ${TEST_ROOT}/hs_call_args_tests.c
+ ${TEST_ROOT}/hs_pushstring_tests.c
+ # ${TEST_ROOT}/hs_rxx_tests.c
+ )
+add_executable(test EXCLUDE_FROM_ALL ${TEST_SOURCES})
target_link_libraries(test ${LUA_LIBRARIES} honeysuckle)
include(GNUInstallDirs)
diff --git a/README.md b/README.md
index 36d809f..2bcfa71 100644
--- a/README.md
+++ b/README.md
@@ -137,8 +137,9 @@ int overloaded_lua_binding(lua_State *L)
constant/value triplets, and finally `HS_END`. It returns the stack index of
the newly created table. Most of the type constants expect their associated
type (e.g. `HS_INT` expects an `int`, `HS_CFUNC` expects `lua_CFunction`,
-etc.) but `HS_FUNC` and `HS_TBL` expect an integer stack index. `hs_create_
-table()` automatically pops any stack indices provided to it.
+etc.) but `HS_FUNC` and `HS_TBL` expect an integer stack index. You cannot
+use `HS_NIL` or `HS_ANY` with this function. `hs_create_table()`
+automatically pops any stack indices provided to it.
```C
int *ptr; // some pointer
@@ -182,7 +183,8 @@ char *str = hs_enum_to_string(L, index, VALUE_3); // "three"
[(Back to top)](#table-of-contents)
`hs_process_table()` is intended for creating lua bindings that can be called
-like `set_config{ debug=true, verbosity=2, logfile='run.log' }`. It can only operate on stringly-keyed values.
+like `set_config{ debug=true, verbosity=2, logfile='run.log' }`. It can
+only operate on stringly-keyed values.
```C
void set_verbosity(int value, void *data) { // set verbosity level }
@@ -210,8 +212,8 @@ hs_process_table(L, tbl_index, NULL,
hs_throw_error(L, "ERROR: %d is not within range", 10);
```
-`hs_traceback()` can be supplied to `lua_pcall()` to get a helpful stack trace
-error message:
+`hs_traceback()` can be supplied to `lua_pcall()` to get a helpful stack
+trace error message:
```C
lua_pushcfunction(L, hs_traceback);
diff --git a/src/colors.h b/src/tests/colors.h
index 21451de..21451de 100644
--- a/src/colors.h
+++ b/src/tests/colors.h
diff --git a/src/tests/hs_create_table_tests.c b/src/tests/hs_create_table_tests.c
new file mode 100644
index 0000000..feca8f5
--- /dev/null
+++ b/src/tests/hs_create_table_tests.c
@@ -0,0 +1,139 @@
+#include "hs_tests.h"
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * tests for hs_create_table
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+TEST(table_correct_index)
+{
+ int index = hs_create_table(L, HS_END);
+ mu_assert("returned incorrect index!", index == lua_gettop(L));
+ return 0;
+}
+
+
+#define check_table_element(field, is_type, typestring, type, conversion, comparison) \
+ do { \
+ lua_getfield(L, -1, field); \
+ if (!is_type(L, -1)) { lua_pop(L, 1); return "field '" field "' is not type " typestring "!"; } \
+ type value = conversion(L, -1); \
+ lua_pop(L, 1); \
+ mu_assert("field '" field "' does not match the expected value!", comparison); \
+ } while(0)
+
+#define check_bool(field, expected) check_table_element(field, lua_isboolean, "boolean", bool, lua_toboolean, value == expected)
+#define check_int(field, expected) check_table_element(field, lua_isnumber, "integer", int, lua_tointeger, value == expected)
+#define check_num(field, expected) check_table_element(field, lua_isnumber, "number", float, lua_tonumber, value == expected)
+#define check_string(field, expected) check_table_element(field, lua_isstring, "string", char*, lua_tostring, strcmp(value, expected))
+#define check_cfunc(field, expected) check_table_element(field, lua_iscfunction, "C function", lua_CFunction, lua_tocfunction, value == expected)
+#define check_user(field, expected) check_table_element(field, lua_isuserdata, "userdata", void*, lua_touserdata, value == expected)
+#define check_light(field, expected) check_table_element(field, lua_islightuserdata, "light userdata", void*, lua_touserdata, value == expected)
+
+TEST(table_create_basic_types)
+{
+ void *userdata = lua_newuserdata(L, sizeof(char));
+ int user_index = lua_gettop(L);
+ char lightuserdata = 'F';
+
+ hs_create_table
+ (L,
+ "boolValue", HS_BOOL, false,
+ "intValue", HS_INT, 15,
+ "numValue", HS_NUM, 33.66,
+ "stringValue", HS_STR, "goober",
+ "cfuncValue", HS_CFUNC, testfunc,
+ "userValue", HS_USER, user_index,
+ "lightValue", HS_LIGHT, &lightuserdata,
+ HS_END);
+
+ check_bool("boolValue", false);
+ check_int("intValue", 15);
+ check_num("numValue", 33.66);
+ check_string("stringValue", "goober");
+ check_cfunc("cfuncValue", testfunc);
+ check_user("userValue", userdata);
+ check_light("lightValue", &lightuserdata);
+ return 0;
+}
+
+
+TEST(table_nesting)
+{
+ int top_init = lua_gettop(L);
+
+ hs_create_table
+ (L,
+ "subtable1", HS_TBL,
+ hs_create_table(L,
+ "subsubtable1", HS_TBL,
+ hs_create_table(L,
+ "fourteen", HS_INT, 14,
+ "phi", HS_NUM, 1.61803f,
+ HS_END),
+ HS_END),
+ "subtable2", HS_TBL,
+ hs_create_table(L,
+ "subsubtable2", HS_TBL,
+ hs_create_table(L,
+ "subsubsubtable", HS_TBL,
+ hs_create_table(L, HS_END),
+ HS_END),
+ HS_END),
+ HS_END);
+
+ lua_getfield(L, -1, "subtable1");
+ mu_assert("subtable1 is not a table!", lua_istable(L, -1));
+ lua_getfield(L, -1, "subsubtable1");
+ mu_assert("subsubtable1 is not a table!", lua_istable(L, -1));
+ check_int("fourteen", 14);
+ check_num("phi", 1.61803f);
+ lua_pop(L, 2);
+
+ lua_getfield(L, -1, "subtable2");
+ mu_assert("subtable2 is not a table!", lua_istable(L, -1));
+ lua_getfield(L, -1, "subsubtable2");
+ mu_assert("subsubtable2 is not a table!", lua_istable(L, -1));
+ lua_getfield(L, -1, "subsubsubtable");
+ mu_assert("subsubsubtable is not a table!", lua_istable(L, -1));
+ lua_pop(L, 4);
+
+ mu_assert("more than one new item on stack!",
+ lua_gettop(L) == top_init + 1);
+ return 0;
+}
+
+
+TEST(table_pop_indices)
+{
+ int top_init = lua_gettop(L);
+ int subtable1_index = hs_create_table(L, HS_END);
+ int subtable2_index = hs_create_table(L, HS_END);
+
+ hs_create_table(L,
+ "sub1", HS_TBL, subtable1_index,
+ "sub2", HS_TBL, subtable2_index,
+ HS_END);
+
+ mu_assert("failed to remove subtables from the stack!",
+ lua_gettop(L) == top_init + 1);
+ return 0;
+}
+
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * test suite
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+void hs_create_table_tests()
+{
+ printf("running hs_create_table() tests...\n");
+ mu_run_test("return correct stack index", table_correct_index);
+ mu_run_test("check creation of basic types", table_create_basic_types);
+ mu_run_test("check table nesting", table_nesting);
+}
diff --git a/src/test.c b/src/tests/hs_parse_args_tests.c
index 816500b..829c144 100644
--- a/src/test.c
+++ b/src/tests/hs_parse_args_tests.c
@@ -1,118 +1,4 @@
-#include <stdio.h>
-#include <string.h>
-#include <stdbool.h>
-
-#include <lua.h>
-#include <lualib.h>
-#include <lauxlib.h>
-
-#include "honeysuckle.h"
-#include "colors.h"
-
-/* minunit testing macros modified from those at
- www.jera.com/techinfo/jtns/jtn002.html */
-#define mu_assert(message, test) do { if (!(test)) return message; } while (0)
-#define mu_run_test(name, test) do { \
- lua_State *L = luaL_newstate(); \
- luaL_openlibs(L); \
- char *message = test(L); \
- lua_close(L); \
- tests_run++; \
- if (message) { \
- printf(RED " test '%s' failed: %s\n" RESET, name, message); \
- tests_failed++; \
- } \
- } while (0)
-
-#define TEST(name) static char* name(lua_State *L)
-
-int tests_run = 0;
-int tests_failed = 0;
-
-/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * tests for hs_type_to_string
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
-
-TEST(hs_bool_to_string)
-{
- mu_assert("HS_BOOL does not result in 'boolean'!",
- strcmp(hs_type_to_string(HS_BOOL), "boolean") == 0);
- return 0;
-}
-
-TEST(hs_int_to_string)
-{
- mu_assert("HS_INT does not result in 'integer'!",
- strcmp(hs_type_to_string(HS_INT), "integer") == 0);
- return 0;
-}
-
-TEST(hs_num_to_string)
-{
- mu_assert("HS_NUM does not result in 'number'!",
- strcmp(hs_type_to_string(HS_NUM), "number") == 0);
- return 0;
-}
-
-TEST(hs_str_to_string)
-{
- mu_assert("HS_STR does not result in 'string'!",
- strcmp(hs_type_to_string(HS_STR), "string") == 0);
- return 0;
-}
-
-TEST(hs_tbl_to_string)
-{
- mu_assert("HS_TBL does not result in 'table'!",
- strcmp(hs_type_to_string(HS_TBL), "table") == 0);
- return 0;
-}
-
-TEST(hs_func_to_string)
-{
- mu_assert("HS_FUNC does not result in 'function'!",
- strcmp(hs_type_to_string(HS_FUNC), "function") == 0);
- return 0;
-}
-
-TEST(hs_cfunc_to_string)
-{
- mu_assert("HS_CFUNC does not result in 'C function'!",
- strcmp(hs_type_to_string(HS_CFUNC), "C function") == 0);
- return 0;
-}
-
-TEST(hs_user_to_string)
-{
- mu_assert("HS_USER does not result in 'userdata'!",
- strcmp(hs_type_to_string(HS_USER), "userdata") == 0);
- return 0;
-}
-
-TEST(hs_light_to_string)
-{
- mu_assert("HS_LIGHT does not result in 'light userdata'!",
- strcmp(hs_type_to_string(HS_LIGHT), "light userdata") == 0);
- return 0;
-}
-
-TEST(hs_nil_to_string)
-{
- mu_assert("HS_NIL does not result in 'nil'!",
- strcmp(hs_type_to_string(HS_NIL), "nil") == 0);
- return 0;
-}
-
-TEST(hs_any_to_string)
-{
- mu_assert("HS_ANY does not result in 'any'!",
- strcmp(hs_type_to_string(HS_ANY), "any") == 0);
- return 0;
-}
-
+#include "hs_tests.h"
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
@@ -658,273 +544,15 @@ TEST(parse_readme_example)
return 0;
}
-
-/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * tests for hs_parse_overloaded
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
-
-#define PARSE_OVERLOADED \
- bool b; int i, ti, fi, ni; float f; char *str; \
- lua_CFunction fn; void *user, *light; \
- int choice = hs_parse_overloaded \
- (L, \
- HS_BOOL, &b, HS_END, HS_INT, &i, HS_END, HS_NUM, &f, HS_END, \
- HS_STR, &str, HS_END, HS_TBL, &ti, HS_END, HS_FUNC, &fi, \
- HS_END, HS_CFUNC, &fn, HS_END, HS_USER, &user, HS_END, \
- HS_LIGHT, &light, HS_END, HS_NIL, &ni, HS_END, HS_END);
-
-TEST(parse_bool_overloaded)
-{
- lua_pushboolean(L, true);
- PARSE_OVERLOADED;
- mu_assert("boolean option was not chosen!", choice == 0);
- mu_assert("failed to properly parse boolean!", b);
- return 0;
-}
-
-TEST(parse_integer_overloaded)
-{
- lua_pushinteger(L, 5);
- PARSE_OVERLOADED;
- mu_assert("integer option was not chosen!", choice == 1);
- mu_assert("failed to properly parse integer!", i == 5);
- return 0;
-}
-
-TEST(parse_number_overloaded)
-{
- lua_pushnumber(L, 42.0f);
- PARSE_OVERLOADED;
- mu_assert("number option was not chosen!", choice == 2);
- mu_assert("failed to properly parse boolean!", f == 42.0f);
- return 0;
-}
-
-TEST(parse_string_overloaded)
-{
- lua_pushstring(L, "hello, world!");
- PARSE_OVERLOADED;
- mu_assert("string option was not chosen!", choice == 3);
- mu_assert("failed to properly parse string!",
- strcmp(str, "hello, world!") == 0);
- return 0;
-}
-
-TEST(parse_table_overloaded)
-{
- lua_getglobal(L, "debug");
- int expected = lua_gettop(L);
- PARSE_OVERLOADED;
- mu_assert("table option was not chosen!", choice == 4);
- mu_assert("failed to properly parse table!", ti == expected);
- return 0;
-}
-
-TEST(parse_function_overloaded)
-{
- lua_getglobal(L, "type");
- int expected = lua_gettop(L);
- PARSE_OVERLOADED;
- mu_assert("function option was not chosen!", choice == 5);
- mu_assert("failed to properly parse function!", fi == expected);
- return 0;
-}
-
-TEST(parse_cfunction_overloaded)
-{
- lua_pushcfunction(L, testfunc);
- PARSE_OVERLOADED;
- mu_assert("C function option was not chosen!", choice == 6);
- mu_assert("failed to properly parse C function!", fn == testfunc);
- return 0;
-}
-
-TEST(parse_userdata_overloaded)
-{
- void *userdata = lua_newuserdata(L, sizeof(char));
- PARSE_OVERLOADED;
- mu_assert("userdata option was not chosen!", choice == 7);
- mu_assert("failed to properly parse userdata!", user == userdata);
- return 0;
-}
-
-TEST(parse_lightuserdata_overloaded)
-{
- int five = 5;
- lua_pushlightuserdata(L, &five);
- PARSE_OVERLOADED;
- mu_assert("light userdata option was not chosen!", choice == 8);
- mu_assert("failed to properly parse light userdata!", light == &five);
- return 0;
-}
-
-TEST(parse_nil_overloaded)
-{
- lua_pushnil(L);
- int expected = lua_gettop(L);
- PARSE_OVERLOADED;
- mu_assert("nil option was not chosen!", choice == 9);
- mu_assert("failed to properly parse nil!", ni == expected);
- return 0;
-}
-
-TEST(parse_2_3_overload_0)
-{
- lua_pushinteger(L, 69);
- lua_pushstring(L, "foo");
- int i; char *str; void *data;
- int choice = hs_parse_overloaded
- (L, HS_INT, &i, HS_STR, &str, HS_END,
- HS_INT, &i, HS_STR, &str, HS_USER, &data, HS_END,
- HS_END);
-
- mu_assert("incorrectly selected option other than 0!", choice == 0);
- mu_assert("failed to properly parse integer!", i == 69);
- mu_assert("failed to properly parse string!", strcmp(str, "foo") == 0);
- return 0;
-}
-
-TEST(parse_2_3_overload_1)
-{
- lua_pushinteger(L, 69);
- lua_pushstring(L, "foo");
- void *userdata = lua_newuserdata(L, sizeof(char));
- int i; char *str; void *data;
- int choice = hs_parse_overloaded
- (L, HS_INT, &i, HS_STR, &str, HS_END,
- HS_INT, &i, HS_STR, &str, HS_USER, &data, HS_END,
- HS_END);
-
- mu_assert("incorrectly selected option other than 1!", choice == 1);
- mu_assert("failed to properly parse integer!", i == 69);
- mu_assert("failed to properly parse string!", strcmp(str, "foo") == 0);
- mu_assert("failed to properly parse userdata!", userdata == data);
- return 0;
-}
-
-
-/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * tests for hs_create_table
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
-
-TEST(table_correct_index)
-{
- int index = hs_create_table(L, HS_END);
- mu_assert("returned incorrect index!", index == lua_gettop(L));
- return 0;
-}
-
-
-#define check_table_element(field, is_type, typestring, type, conversion, comparison) \
- do { \
- lua_getfield(L, -1, field); \
- if (!is_type(L, -1)) { lua_pop(L, 1); return "field '" field "' is not type " typestring "!"; } \
- type value = conversion(L, -1); \
- lua_pop(L, 1); \
- mu_assert("field '" field "' does not match the expected value!", comparison); \
- } while(0)
-
-#define check_bool(field, expected) check_table_element(field, lua_isboolean, "boolean", bool, lua_toboolean, value == expected)
-#define check_int(field, expected) check_table_element(field, lua_isnumber, "integer", int, lua_tointeger, value == expected)
-#define check_num(field, expected) check_table_element(field, lua_isnumber, "number", float, lua_tonumber, value == expected)
-#define check_string(field, expected) check_table_element(field, lua_isstring, "string", char*, lua_tostring, strcmp(value, expected))
-#define check_cfunc(field, expected) check_table_element(field, lua_iscfunction, "C function", lua_CFunction, lua_tocfunction, value == expected)
-#define check_user(field, expected) check_table_element(field, lua_isuserdata, "userdata", void*, lua_touserdata, value == expected)
-#define check_light(field, expected) check_table_element(field, lua_islightuserdata, "light userdata", void*, lua_touserdata, value == expected)
-
-TEST(table_create_basic_types)
-{
- void *userdata = lua_newuserdata(L, sizeof(char));
- int user_index = lua_gettop(L);
- char lightuserdata = 'F';
-
- hs_create_table
- (L,
- "boolValue", HS_BOOL, false,
- "intValue", HS_INT, 15,
- "numValue", HS_NUM, 33.66,
- "stringValue", HS_STR, "goober",
- "cfuncValue", HS_CFUNC, testfunc,
- "userValue", HS_USER, user_index,
- "lightValue", HS_LIGHT, &lightuserdata,
- HS_END);
-
- check_bool("boolValue", false);
- check_int("intValue", 15);
- check_num("numValue", 33.66);
- check_string("stringValue", "goober");
- check_cfunc("cfuncValue", testfunc);
- check_user("userValue", userdata);
- check_light("lightValue", &lightuserdata);
- return 0;
-}
-
-
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
- * tests for hs_pushstring
+ * test suite
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
-TEST(push_noformat)
+void hs_parse_args_tests()
{
- hs_pushstring(L, "a string");
- mu_assert("no string at top of stack!", lua_isstring(L, -1));
- const char *string = lua_tostring(L, -1);
- mu_assert("string != 'a string'", strcmp(string, "a string") == 0);
- return 0;
-}
-
-TEST(push_formatint)
-{
- hs_pushstring(L, "%d is 5", 5);
- mu_assert("no string at top of stack!", lua_isstring(L, -1));
- const char *string = lua_tostring(L, -1);
- mu_assert("string != '5 is 5'", strcmp(string, "5 is 5") == 0);
- return 0;
-}
-
-TEST(push_formatstring)
-{
- hs_pushstring(L, "%s is 'hello'", "hello");
- mu_assert("no string at top of stack!", lua_isstring(L, -1));
- const char *string = lua_tostring(L, -1);
- mu_assert("string != 'hello is 'hello''",
- strcmp(string, "hello is 'hello'") == 0);
- return 0;
-}
-
-/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * RUN TESTS
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
-
-int main()
-{
- printf("================ start tests ================\n\n");
-
- printf("running hs_type_to_string() tests...\n");
- mu_run_test("bool to string", hs_bool_to_string);
- mu_run_test("int to string", hs_int_to_string);
- mu_run_test("num to string", hs_num_to_string);
- mu_run_test("str to string", hs_str_to_string);
- mu_run_test("tbl to string", hs_tbl_to_string);
- mu_run_test("func to string", hs_func_to_string);
- mu_run_test("cfunc to string", hs_cfunc_to_string);
- mu_run_test("user to string", hs_user_to_string);
- mu_run_test("light to string", hs_light_to_string);
- mu_run_test("nil to string", hs_nil_to_string);
- mu_run_test("any to string", hs_any_to_string);
-
printf("running hs_parse_args() typechecking tests...\n");
mu_run_test("parse bool typecheck", parse_bool_typecheck);
mu_run_test("parse int typecheck", parse_int_typecheck);
@@ -953,33 +581,4 @@ int main()
mu_run_test("parse any", parse_any);
mu_run_test("parse all", parse_all);
mu_run_test("parse readme example", parse_readme_example);
-
- printf("running hs_parse_overloaded() parsing tests...\n");
- mu_run_test("parse bool overloaded", parse_bool_overloaded);
- mu_run_test("parse integer overloaded", parse_integer_overloaded);
- mu_run_test("parse number overloaded", parse_number_overloaded);
- mu_run_test("parse string overloaded", parse_string_overloaded);
- mu_run_test("parse table overloaded", parse_table_overloaded);
- mu_run_test("parse function overloaded", parse_function_overloaded);
- mu_run_test("parse cfunction overloaded", parse_cfunction_overloaded);
- mu_run_test("parse userdata overloaded", parse_userdata_overloaded);
- mu_run_test("parse lightuserdata overloaded", parse_lightuserdata_overloaded);
- mu_run_test("parse nil overloaded", parse_nil_overloaded);
- mu_run_test("parse 2/3 overload 0", parse_2_3_overload_0);
- mu_run_test("parse 2/3 overload 1", parse_2_3_overload_1);
-
- printf("running hs_create_table() tests...\n");
- mu_run_test("return correct stack index", table_correct_index);
- mu_run_test("check creation of basic types", table_create_basic_types);
-
- printf("running hs_pushstring() tests...\n");
- mu_run_test("hs_pushstring (no printf formatting)", push_noformat);
- mu_run_test("hs_pushstring (integer formatting)", push_formatint);
- mu_run_test("hs_pushstring (string formatting)", push_formatstring);
-
- printf("\n=============== tests finished ===============\n\n");
-
- const char *color = tests_failed == 0 ? GREEN : RED;
- printf("%sran %d tests, %d failed\n" RESET, color, tests_run, tests_failed);
- return 0;
}
diff --git a/src/tests/hs_parse_overloaded_tests.c b/src/tests/hs_parse_overloaded_tests.c
new file mode 100644
index 0000000..de364db
--- /dev/null
+++ b/src/tests/hs_parse_overloaded_tests.c
@@ -0,0 +1,172 @@
+#include "hs_tests.h"
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * tests for hs_parse_overloaded
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+#define PARSE_OVERLOADED \
+ bool b; int i, ti, fi, ni; float f; char *str; \
+ lua_CFunction fn; void *user, *light; \
+ int choice = hs_parse_overloaded \
+ (L, \
+ HS_BOOL, &b, HS_END, HS_INT, &i, HS_END, HS_NUM, &f, HS_END, \
+ HS_STR, &str, HS_END, HS_TBL, &ti, HS_END, HS_FUNC, &fi, \
+ HS_END, HS_CFUNC, &fn, HS_END, HS_USER, &user, HS_END, \
+ HS_LIGHT, &light, HS_END, HS_NIL, &ni, HS_END, HS_END);
+
+TEST(parse_bool_overloaded)
+{
+ lua_pushboolean(L, true);
+ PARSE_OVERLOADED;
+ mu_assert("boolean option was not chosen!", choice == 0);
+ mu_assert("failed to properly parse boolean!", b);
+ return 0;
+}
+
+TEST(parse_integer_overloaded)
+{
+ lua_pushinteger(L, 5);
+ PARSE_OVERLOADED;
+ mu_assert("integer option was not chosen!", choice == 1);
+ mu_assert("failed to properly parse integer!", i == 5);
+ return 0;
+}
+
+TEST(parse_number_overloaded)
+{
+ lua_pushnumber(L, 42.0f);
+ PARSE_OVERLOADED;
+ mu_assert("number option was not chosen!", choice == 2);
+ mu_assert("failed to properly parse boolean!", f == 42.0f);
+ return 0;
+}
+
+TEST(parse_string_overloaded)
+{
+ lua_pushstring(L, "hello, world!");
+ PARSE_OVERLOADED;
+ mu_assert("string option was not chosen!", choice == 3);
+ mu_assert("failed to properly parse string!",
+ strcmp(str, "hello, world!") == 0);
+ return 0;
+}
+
+TEST(parse_table_overloaded)
+{
+ lua_getglobal(L, "debug");
+ int expected = lua_gettop(L);
+ PARSE_OVERLOADED;
+ mu_assert("table option was not chosen!", choice == 4);
+ mu_assert("failed to properly parse table!", ti == expected);
+ return 0;
+}
+
+TEST(parse_function_overloaded)
+{
+ lua_getglobal(L, "type");
+ int expected = lua_gettop(L);
+ PARSE_OVERLOADED;
+ mu_assert("function option was not chosen!", choice == 5);
+ mu_assert("failed to properly parse function!", fi == expected);
+ return 0;
+}
+
+TEST(parse_cfunction_overloaded)
+{
+ lua_pushcfunction(L, testfunc);
+ PARSE_OVERLOADED;
+ mu_assert("C function option was not chosen!", choice == 6);
+ mu_assert("failed to properly parse C function!", fn == testfunc);
+ return 0;
+}
+
+TEST(parse_userdata_overloaded)
+{
+ void *userdata = lua_newuserdata(L, sizeof(char));
+ PARSE_OVERLOADED;
+ mu_assert("userdata option was not chosen!", choice == 7);
+ mu_assert("failed to properly parse userdata!", user == userdata);
+ return 0;
+}
+
+TEST(parse_lightuserdata_overloaded)
+{
+ int five = 5;
+ lua_pushlightuserdata(L, &five);
+ PARSE_OVERLOADED;
+ mu_assert("light userdata option was not chosen!", choice == 8);
+ mu_assert("failed to properly parse light userdata!", light == &five);
+ return 0;
+}
+
+TEST(parse_nil_overloaded)
+{
+ lua_pushnil(L);
+ int expected = lua_gettop(L);
+ PARSE_OVERLOADED;
+ mu_assert("nil option was not chosen!", choice == 9);
+ mu_assert("failed to properly parse nil!", ni == expected);
+ return 0;
+}
+
+TEST(parse_2_3_overload_0)
+{
+ lua_pushinteger(L, 69);
+ lua_pushstring(L, "foo");
+ int i; char *str; void *data;
+ int choice = hs_parse_overloaded
+ (L, HS_INT, &i, HS_STR, &str, HS_END,
+ HS_INT, &i, HS_STR, &str, HS_USER, &data, HS_END,
+ HS_END);
+
+ mu_assert("incorrectly selected option other than 0!", choice == 0);
+ mu_assert("failed to properly parse integer!", i == 69);
+ mu_assert("failed to properly parse string!", strcmp(str, "foo") == 0);
+ return 0;
+}
+
+TEST(parse_2_3_overload_1)
+{
+ lua_pushinteger(L, 69);
+ lua_pushstring(L, "foo");
+ void *userdata = lua_newuserdata(L, sizeof(char));
+ int i; char *str; void *data;
+ int choice = hs_parse_overloaded
+ (L, HS_INT, &i, HS_STR, &str, HS_END,
+ HS_INT, &i, HS_STR, &str, HS_USER, &data, HS_END,
+ HS_END);
+
+ mu_assert("incorrectly selected option other than 1!", choice == 1);
+ mu_assert("failed to properly parse integer!", i == 69);
+ mu_assert("failed to properly parse string!", strcmp(str, "foo") == 0);
+ mu_assert("failed to properly parse userdata!", userdata == data);
+ return 0;
+}
+
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * test suite
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+void hs_parse_overloaded_tests()
+{
+ printf("running hs_parse_overloaded() parsing tests...\n");
+ mu_run_test("parse bool overloaded", parse_bool_overloaded);
+ mu_run_test("parse integer overloaded", parse_integer_overloaded);
+ mu_run_test("parse number overloaded", parse_number_overloaded);
+ mu_run_test("parse string overloaded", parse_string_overloaded);
+ mu_run_test("parse table overloaded", parse_table_overloaded);
+ mu_run_test("parse function overloaded", parse_function_overloaded);
+ mu_run_test("parse cfunction overloaded", parse_cfunction_overloaded);
+ mu_run_test("parse userdata overloaded", parse_userdata_overloaded);
+ mu_run_test("parse lightuserdata overloaded", parse_lightuserdata_overloaded);
+ mu_run_test("parse nil overloaded", parse_nil_overloaded);
+ mu_run_test("parse 2/3 overload 0", parse_2_3_overload_0);
+ mu_run_test("parse 2/3 overload 1", parse_2_3_overload_1);
+}
diff --git a/src/tests/hs_pushstring_tests.c b/src/tests/hs_pushstring_tests.c
new file mode 100644
index 0000000..e7fa1b4
--- /dev/null
+++ b/src/tests/hs_pushstring_tests.c
@@ -0,0 +1,52 @@
+#include "hs_tests.h"
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * tests for hs_pushstring
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+TEST(push_noformat)
+{
+ hs_pushstring(L, "a string");
+ mu_assert("no string at top of stack!", lua_isstring(L, -1));
+ const char *string = lua_tostring(L, -1);
+ mu_assert("string != 'a string'", strcmp(string, "a string") == 0);
+ return 0;
+}
+
+TEST(push_formatint)
+{
+ hs_pushstring(L, "%d is 5", 5);
+ mu_assert("no string at top of stack!", lua_isstring(L, -1));
+ const char *string = lua_tostring(L, -1);
+ mu_assert("string != '5 is 5'", strcmp(string, "5 is 5") == 0);
+ return 0;
+}
+
+TEST(push_formatstring)
+{
+ hs_pushstring(L, "%s is 'hello'", "hello");
+ mu_assert("no string at top of stack!", lua_isstring(L, -1));
+ const char *string = lua_tostring(L, -1);
+ mu_assert("string != 'hello is 'hello''",
+ strcmp(string, "hello is 'hello'") == 0);
+ return 0;
+}
+
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * test suite
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+void hs_pushstring_tests()
+{
+ printf("running hs_pushstring() tests...\n");
+ mu_run_test("hs_pushstring (no printf formatting)", push_noformat);
+ mu_run_test("hs_pushstring (integer formatting)", push_formatint);
+ mu_run_test("hs_pushstring (string formatting)", push_formatstring);
+}
diff --git a/src/tests/hs_tests.h b/src/tests/hs_tests.h
new file mode 100644
index 0000000..df73318
--- /dev/null
+++ b/src/tests/hs_tests.h
@@ -0,0 +1,55 @@
+#pragma once
+
+#include <stdio.h>
+#include <string.h>
+#include <stdbool.h>
+
+#include <lua.h>
+#include <lualib.h>
+#include <lauxlib.h>
+
+#include "../honeysuckle.h"
+#include "colors.h"
+
+/* minunit testing macros modified from those at
+ www.jera.com/techinfo/jtns/jtn002.html */
+#define mu_assert(message, test) do { if (!(test)) return message; } while (0)
+#define mu_run_test(name, test) do { \
+ lua_State *L = luaL_newstate(); \
+ luaL_openlibs(L); \
+ const char *message = test(L); \
+ lua_close(L); \
+ tests_run++; \
+ if (message) { \
+ printf(RED " test '%s' failed: %s\n" RESET, name, message); \
+ tests_failed++; \
+ } \
+ } while (0)
+
+#define TEST(name) static const char* name(lua_State *L)
+
+extern int tests_run, tests_failed;
+
+void hs_type_to_string_tests();
+void hs_parse_args_tests();
+void hs_parse_overloaded_tests();
+void hs_create_table_tests();
+void hs_create_enum_tests();
+void hs_process_table_tests();
+void hs_throw_error_tests();
+void hs_traceback_tests();
+void hs_call_tests();
+void hs_call_args_tests();
+void hs_pushstring_tests();
+void hs_rxx_tests();
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * tests for hs_create_enum
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+#define check_value(string, value)
+
+
diff --git a/src/tests/hs_type_to_string_tests.c b/src/tests/hs_type_to_string_tests.c
new file mode 100644
index 0000000..3b158ab
--- /dev/null
+++ b/src/tests/hs_type_to_string_tests.c
@@ -0,0 +1,102 @@
+#include "hs_tests.h"
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * tests for hs_type_to_string
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+TEST(hs_bool_to_string)
+{
+ mu_assert("HS_BOOL does not result in 'boolean'!",
+ strcmp(hs_type_to_string(HS_BOOL), "boolean") == 0);
+ return 0;
+}
+
+TEST(hs_int_to_string)
+{
+ mu_assert("HS_INT does not result in 'integer'!",
+ strcmp(hs_type_to_string(HS_INT), "integer") == 0);
+ return 0;
+}
+
+TEST(hs_num_to_string)
+{
+ mu_assert("HS_NUM does not result in 'number'!",
+ strcmp(hs_type_to_string(HS_NUM), "number") == 0);
+ return 0;
+}
+
+TEST(hs_str_to_string)
+{
+ mu_assert("HS_STR does not result in 'string'!",
+ strcmp(hs_type_to_string(HS_STR), "string") == 0);
+ return 0;
+}
+
+TEST(hs_tbl_to_string)
+{
+ mu_assert("HS_TBL does not result in 'table'!",
+ strcmp(hs_type_to_string(HS_TBL), "table") == 0);
+ return 0;
+}
+
+TEST(hs_func_to_string)
+{
+ mu_assert("HS_FUNC does not result in 'function'!",
+ strcmp(hs_type_to_string(HS_FUNC), "function") == 0);
+ return 0;
+}
+
+TEST(hs_cfunc_to_string)
+{
+ mu_assert("HS_CFUNC does not result in 'C function'!",
+ strcmp(hs_type_to_string(HS_CFUNC), "C function") == 0);
+ return 0;
+}
+
+TEST(hs_user_to_string)
+{
+ mu_assert("HS_USER does not result in 'userdata'!",
+ strcmp(hs_type_to_string(HS_USER), "userdata") == 0);
+ return 0;
+}
+
+TEST(hs_light_to_string)
+{
+ mu_assert("HS_LIGHT does not result in 'light userdata'!",
+ strcmp(hs_type_to_string(HS_LIGHT), "light userdata") == 0);
+ return 0;
+}
+
+TEST(hs_nil_to_string)
+{
+ mu_assert("HS_NIL does not result in 'nil'!",
+ strcmp(hs_type_to_string(HS_NIL), "nil") == 0);
+ return 0;
+}
+
+TEST(hs_any_to_string)
+{
+ mu_assert("HS_ANY does not result in 'any'!",
+ strcmp(hs_type_to_string(HS_ANY), "any") == 0);
+ return 0;
+}
+
+
+void hs_type_to_string_tests()
+{
+ printf("running hs_type_to_string() tests...\n");
+ mu_run_test("bool to string", hs_bool_to_string);
+ mu_run_test("int to string", hs_int_to_string);
+ mu_run_test("num to string", hs_num_to_string);
+ mu_run_test("str to string", hs_str_to_string);
+ mu_run_test("tbl to string", hs_tbl_to_string);
+ mu_run_test("func to string", hs_func_to_string);
+ mu_run_test("cfunc to string", hs_cfunc_to_string);
+ mu_run_test("user to string", hs_user_to_string);
+ mu_run_test("light to string", hs_light_to_string);
+ mu_run_test("nil to string", hs_nil_to_string);
+ mu_run_test("any to string", hs_any_to_string);
+}
diff --git a/src/tests/tests_main.c b/src/tests/tests_main.c
new file mode 100644
index 0000000..06c6940
--- /dev/null
+++ b/src/tests/tests_main.c
@@ -0,0 +1,28 @@
+#include "hs_tests.h"
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * RUN TESTS
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+int tests_run = 0;
+int tests_failed = 0;
+
+int main()
+{
+ printf("================ start tests ================\n\n");
+
+ hs_type_to_string_tests();
+ hs_parse_args_tests();
+ hs_parse_overloaded_tests();
+
+ hs_pushstring_tests();
+
+ printf("\n=============== tests finished ===============\n\n");
+
+ const char *color = tests_failed == 0 ? GREEN : RED;
+ printf("%sran %d tests, %d failed\n" RESET, color, tests_run, tests_failed);
+ return tests_failed;
+}