#include "hs_tests.h" static int testfunc1(lua_State *L) { return 0; } static int testfunc2(lua_State *L) { return 0; } /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * tests for hs_create_table * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ TEST(table_correct_index) { int top_old = lua_gettop(L); int index = hs_create_table(L); mu_assert("the stack is unchanged!", lua_gettop(L) != top_old); mu_assert("returned incorrect index!", index == lua_gettop(L)); return 0; } #define load_key(index, value, pushf) do { \ pushf(L, value); lua_gettable(L, index); \ mu_assert("value at key '" #value "' is nil!", \ !lua_isnil(L, -1)); \ } while(0) #define loadkey_bool(index, value) \ load_key(index, value, lua_pushboolean) #define loadkey_int(index, value) \ load_key(index, value, lua_pushinteger) #define loadkey_num(index, value) \ load_key(index, value, lua_pushnumber) #define loadkey_str(index, value) \ load_key(index, value, lua_pushstring) #define loadkey_tbl(index, value) do { \ lua_pushvalue(L, value); lua_gettable(L, index); \ mu_assert("value at table (index '" #value "') is nil!", \ !lua_isnil(L, -1)); \ } while(0) #define loadkey_func(index, value) do { \ lua_pushvalue(L, value); lua_gettable(L, index); \ mu_assert("value at function (index '" #value "') is nil!", \ !lua_isnil(L, -1)); \ } while(0) #define loadkey_cfunc(index, value) \ load_key(index, value, lua_pushcfunction) #define loadkey_user(index, value) do { \ lua_pushvalue(L, value); lua_gettable(L, index); \ mu_assert("value at userdata (index '" #value "') is nil!", \ !lua_isnil(L, -1)); \ } while(0) #define loadkey_light(index, value) \ load_key(index, value, lua_pushlightuserdata) #define check_value(is_type, typestring, type, conversion, comparison) \ do { \ mu_assert("value is not of type " typestring, is_type(L, -1)); \ type value = conversion(L, -1); lua_pop(L, 1); \ mu_assert("test " #comparison " failed!", (comparison)); \ lua_pop(L, 1); /* remove key */ \ } while(0) #define checkval_bool(expected) \ check_value(lua_isboolean, "boolean", bool, lua_toboolean, value==expected) #define checkval_int(expected) \ check_value(lua_isnumber, "integer", lua_Integer, lua_tointeger, value==expected) #define checkval_num(expected) \ check_value(lua_isnumber, "number", lua_Number, lua_tonumber, value==expected) #define checkval_str(expected) \ check_value(lua_isstring, "string", const char *, lua_tostring, strcmp(value, expected)) #define checkval_tbl(expected) \ check_value(lua_istable, "table", const void *, lua_topointer, value==lua_topointer(L, expected)) #define checkval_func(expected) \ check_value(lua_isfunction, "function", const void *, lua_topointer, value==lua_topointer(L, expected)) #define checkval_cfunc(expected) \ check_value(lua_iscfunction, "C function", lua_CFunction, lua_tocfunction, value==expected) #define checkval_user(expected) \ check_value(lua_isuserdata, "userdata", void *, lua_touserdata, value==lua_topointer(L, expected)) #define checkval_light(expected) \ check_value(lua_islightuserdata, "light userdata", void *, lua_touserdata, value==expected) /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * boolean keys * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ TEST(create_table_bool_bool) { int index = hs_create_table (L, hs_bool_bool(true, true), hs_bool_bool(false, true)); loadkey_bool(index, true); checkval_bool(true); loadkey_bool(index, false); checkval_bool(true); return 0; } TEST(create_table_bool_int) { int index = hs_create_table (L, hs_bool_int(true, 15), hs_bool_int(false, 25)); loadkey_bool(index, true); checkval_int(15); loadkey_bool(index, false); checkval_int(25); return 0; } TEST(create_table_bool_num) { int index = hs_create_table (L, hs_bool_num(true, 2.718), hs_bool_num(false, 1.618)); loadkey_bool(index, true); checkval_num(2.718); loadkey_bool(index, false); checkval_num(1.618); return 0; } TEST(create_table_bool_str) { int index = hs_create_table (L, hs_bool_str(true, "hello"), hs_bool_str(false, "world")); loadkey_bool(index, true); checkval_str("hello"); loadkey_bool(index, false); checkval_str("world"); return 0; } TEST(create_table_bool_tbl) { lua_newtable(L); int tbl1 = lua_gettop(L); lua_newtable(L); int tbl2 = lua_gettop(L); int index = hs_create_table (L, hs_bool_tbl(true, tbl1), hs_bool_tbl(false, tbl2)); loadkey_bool(index, true); checkval_tbl(tbl1); loadkey_bool(index, false); checkval_tbl(tbl2); return 0; } TEST(create_table_bool_func) { luaL_loadstring(L, "print('hello')"); int func1 = lua_gettop(L); luaL_loadstring(L, "print('hello')"); int func2 = lua_gettop(L); int index = hs_create_table (L, hs_bool_func(true, func1), hs_bool_func(false, func2)); loadkey_bool(index, true); checkval_func(func1); loadkey_bool(index, false); checkval_func(func2); return 0; } TEST(create_table_bool_cfunc) { int index = hs_create_table (L, hs_bool_cfunc(true, testfunc1), hs_bool_cfunc(false, testfunc2)); loadkey_bool(index, true); checkval_cfunc(testfunc1); loadkey_bool(index, false); checkval_cfunc(testfunc2); return 0; } TEST(create_table_bool_user) { lua_newuserdata(L, sizeof(char)); int user1 = lua_gettop(L); lua_newuserdata(L, sizeof(char)); int user2 = lua_gettop(L); int index = hs_create_table (L, hs_bool_user(true, user1), hs_bool_user(false, user2)); loadkey_bool(index, true); checkval_user(user1); loadkey_bool(index, false); checkval_user(user2); return 0; } TEST(create_table_bool_light) { int a1 = 5; void *light1 = (void *) &a1; int a2 = 6; void *light2 = (void *) &a2; int index = hs_create_table (L, hs_bool_light(true, light1), hs_bool_light(false, light2)); loadkey_bool(index, true); checkval_light(light1); loadkey_bool(index, false); checkval_light(light2); return 0; } /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * integer keys * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ TEST(create_table_int_bool) { int index = hs_create_table (L, hs_int_bool(15, true), hs_int_bool(25, true)); loadkey_int(index, 15); checkval_bool(true); loadkey_int(index, 25); checkval_bool(true); return 0; } TEST(create_table_int_int) { int index = hs_create_table (L, hs_int_int(15, 15), hs_int_int(25, 25)); loadkey_int(index, 15); checkval_int(15); loadkey_int(index, 25); checkval_int(25); return 0; } TEST(create_table_int_num) { int index = hs_create_table (L, hs_int_num(15, 2.718), hs_int_num(25, 1.618)); loadkey_int(index, 15); checkval_num(2.718); loadkey_int(index, 25); checkval_num(1.618); return 0; } TEST(create_table_int_str) { int index = hs_create_table (L, hs_int_str(15, "hello"), hs_int_str(25, "world")); loadkey_int(index, 15); checkval_str("hello"); loadkey_int(index, 25); checkval_str("world"); return 0; } TEST(create_table_int_tbl) { lua_newtable(L); int tbl1 = lua_gettop(L); lua_newtable(L); int tbl2 = lua_gettop(L); int index = hs_create_table (L, hs_int_tbl(15, tbl1), hs_int_tbl(25, tbl2)); loadkey_int(index, 15); checkval_tbl(tbl1); loadkey_int(index, 25); checkval_tbl(tbl2); return 0; } TEST(create_table_int_func) { luaL_loadstring(L, "print('hello')"); int func1 = lua_gettop(L); luaL_loadstring(L, "print('hello')"); int func2 = lua_gettop(L); int index = hs_create_table (L, hs_int_func(15, func1), hs_int_func(25, func2)); loadkey_int(index, 15); checkval_func(func1); loadkey_int(index, 25); checkval_func(func2); return 0; } TEST(create_table_int_cfunc) { int index = hs_create_table (L, hs_int_cfunc(15, testfunc1), hs_int_cfunc(25, testfunc2)); loadkey_int(index, 15); checkval_cfunc(testfunc1); loadkey_int(index, 25); checkval_cfunc(testfunc2); return 0; } TEST(create_table_int_user) { lua_newuserdata(L, sizeof(char)); int user1 = lua_gettop(L); lua_newuserdata(L, sizeof(char)); int user2 = lua_gettop(L); int index = hs_create_table (L, hs_int_user(15, user1), hs_int_user(25, user2)); loadkey_int(index, 15); checkval_user(user1); loadkey_int(index, 25); checkval_user(user2); return 0; } TEST(create_table_int_light) { int a1 = 5; void *light1 = (void *) &a1; int a2 = 6; void *light2 = (void *) &a2; int index = hs_create_table (L, hs_int_light(15, light1), hs_int_light(25, light2)); loadkey_int(index, 15); checkval_light(light1); loadkey_int(index, 25); checkval_light(light2); return 0; } /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * number keys * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ TEST(create_table_num_bool) { int index = hs_create_table (L, hs_num_bool(43.3f, true), hs_num_bool(63.75f, true)); loadkey_num(index, 43.3f); checkval_bool(true); loadkey_num(index, 63.75f); checkval_bool(true); return 0; } TEST(create_table_num_int) { int index = hs_create_table (L, hs_num_int(43.3f, 15), hs_num_int(63.75f, 25)); loadkey_num(index, 43.3f); checkval_int(15); loadkey_num(index, 63.75f); checkval_int(25); return 0; } TEST(create_table_num_num) { int index = hs_create_table (L, hs_num_num(43.3f, 2.718), hs_num_num(63.75f, 1.618)); loadkey_num(index, 43.3f); checkval_num(2.718); loadkey_num(index, 63.75f); checkval_num(1.618); return 0; } TEST(create_table_num_str) { int index = hs_create_table (L, hs_num_str(43.3f, "hello"), hs_num_str(63.75f, "world")); loadkey_num(index, 43.3f); checkval_str("hello"); loadkey_num(index, 63.75f); checkval_str("world"); return 0; } TEST(create_table_num_tbl) { lua_newtable(L); int tbl1 = lua_gettop(L); lua_newtable(L); int tbl2 = lua_gettop(L); int index = hs_create_table (L, hs_num_tbl(43.3f, tbl1), hs_num_tbl(63.75f, tbl2)); loadkey_num(index, 43.3f); checkval_tbl(tbl1); loadkey_num(index, 63.75f); checkval_tbl(tbl2); return 0; } TEST(create_table_num_func) { luaL_loadstring(L, "print('hello')"); int func1 = lua_gettop(L); luaL_loadstring(L, "print('hello')"); int func2 = lua_gettop(L); int index = hs_create_table (L, hs_num_func(43.3f, func1), hs_num_func(63.75f, func2)); loadkey_num(index, 43.3f); checkval_func(func1); loadkey_num(index, 63.75f); checkval_func(func2); return 0; } TEST(create_table_num_cfunc) { int index = hs_create_table (L, hs_num_cfunc(43.3f, testfunc1), hs_num_cfunc(63.75f, testfunc2)); loadkey_num(index, 43.3f); checkval_cfunc(testfunc1); loadkey_num(index, 63.75f); checkval_cfunc(testfunc2); return 0; } TEST(create_table_num_user) { lua_newuserdata(L, sizeof(char)); int user1 = lua_gettop(L); lua_newuserdata(L, sizeof(char)); int user2 = lua_gettop(L); int index = hs_create_table (L, hs_num_user(43.3f, user1), hs_num_user(63.75f, user2)); loadkey_num(index, 43.3f); checkval_user(user1); loadkey_num(index, 63.75f); checkval_user(user2); return 0; } TEST(create_table_num_light) { int a1 = 5; void *light1 = (void *) &a1; int a2 = 6; void *light2 = (void *) &a2; int index = hs_create_table (L, hs_num_light(43.3f, light1), hs_num_light(63.75f, light2)); loadkey_num(index, 43.3f); checkval_light(light1); loadkey_num(index, 63.75f); checkval_light(light2); return 0; } /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * string keys * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ TEST(create_table_str_bool) { int index = hs_create_table (L, hs_str_bool("hello", true), hs_str_bool("world", true)); loadkey_str(index, "hello"); checkval_bool(true); loadkey_str(index, "world"); checkval_bool(true); return 0; } TEST(create_table_str_int) { int index = hs_create_table (L, hs_str_int("hello", 15), hs_str_int("world", 25)); loadkey_str(index, "hello"); checkval_int(15); loadkey_str(index, "world"); checkval_int(25); return 0; } TEST(create_table_str_num) { int index = hs_create_table (L, hs_str_num("hello", 2.718), hs_str_num("world", 1.618)); loadkey_str(index, "hello"); checkval_num(2.718); loadkey_str(index, "world"); checkval_num(1.618); return 0; } TEST(create_table_str_str) { int index = hs_create_table (L, hs_str_str("hello", "hello"), hs_str_str("world", "world")); loadkey_str(index, "hello"); checkval_str("hello"); loadkey_str(index, "world"); checkval_str("world"); return 0; } TEST(create_table_str_tbl) { lua_newtable(L); int tbl1 = lua_gettop(L); lua_newtable(L); int tbl2 = lua_gettop(L); int index = hs_create_table (L, hs_str_tbl("hello", tbl1), hs_str_tbl("world", tbl2)); loadkey_str(index, "hello"); checkval_tbl(tbl1); loadkey_str(index, "world"); checkval_tbl(tbl2); return 0; } TEST(create_table_str_func) { luaL_loadstring(L, "print('hello')"); int func1 = lua_gettop(L); luaL_loadstring(L, "print('hello')"); int func2 = lua_gettop(L); int index = hs_create_table (L, hs_str_func("hello", func1), hs_str_func("world", func2)); loadkey_str(index, "hello"); checkval_func(func1); loadkey_str(index, "world"); checkval_func(func2); return 0; } TEST(create_table_str_cfunc) { int index = hs_create_table (L, hs_str_cfunc("hello", testfunc1), hs_str_cfunc("world", testfunc2)); loadkey_str(index, "hello"); checkval_cfunc(testfunc1); loadkey_str(index, "world"); checkval_cfunc(testfunc2); return 0; } TEST(create_table_str_user) { lua_newuserdata(L, sizeof(char)); int user1 = lua_gettop(L); lua_newuserdata(L, sizeof(char)); int user2 = lua_gettop(L); int index = hs_create_table (L, hs_str_user("hello", user1), hs_str_user("world", user2)); loadkey_str(index, "hello"); checkval_user(user1); loadkey_str(index, "world"); checkval_user(user2); return 0; } TEST(create_table_str_light) { int a1 = 5; void *light1 = (void *) &a1; int a2 = 6; void *light2 = (void *) &a2; int index = hs_create_table (L, hs_str_light("hello", light1), hs_str_light("world", light2)); loadkey_str(index, "hello"); checkval_light(light1); loadkey_str(index, "world"); checkval_light(light2); return 0; } /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * table keys * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ #define create_table_keys() \ lua_newtable(L); int table1_a = lua_gettop(L); \ lua_newtable(L); int table2_a = lua_gettop(L); \ lua_pushvalue(L, table1_a); int table1_b = lua_gettop(L); \ lua_pushvalue(L, table2_a); int table2_b = lua_gettop(L); TEST(create_table_tbl_bool) { create_table_keys(); int index = hs_create_table (L, hs_tbl_bool(table1_a, true), hs_tbl_bool(table2_a, true)); loadkey_tbl(index, table1_b); checkval_bool(true); loadkey_tbl(index, table2_b); checkval_bool(true); return 0; } TEST(create_table_tbl_int) { create_table_keys(); int index = hs_create_table (L, hs_tbl_int(table1_a, 15), hs_tbl_int(table2_a, 25)); loadkey_tbl(index, table1_b); checkval_int(15); loadkey_tbl(index, table2_b); checkval_int(25); return 0; } TEST(create_table_tbl_num) { create_table_keys(); int index = hs_create_table (L, hs_tbl_num(table1_a, 2.718), hs_tbl_num(table2_a, 1.618)); loadkey_tbl(index, table1_b); checkval_num(2.718); loadkey_tbl(index, table2_b); checkval_num(1.618); return 0; } TEST(create_table_tbl_str) { create_table_keys(); int index = hs_create_table (L, hs_tbl_str(table1_a, "hello"), hs_tbl_str(table2_a, "world")); loadkey_tbl(index, table1_b); checkval_str("hello"); loadkey_tbl(index, table2_b); checkval_str("world"); return 0; } TEST(create_table_tbl_tbl) { create_table_keys(); lua_newtable(L); int tbl1 = lua_gettop(L); lua_newtable(L); int tbl2 = lua_gettop(L); int index = hs_create_table (L, hs_tbl_tbl(table1_a, tbl1), hs_tbl_tbl(table2_a, tbl2)); loadkey_tbl(index, table1_b); checkval_tbl(tbl1); loadkey_tbl(index, table2_b); checkval_tbl(tbl2); return 0; } TEST(create_table_tbl_func) { create_table_keys(); luaL_loadstring(L, "print('hello')"); int func1 = lua_gettop(L); luaL_loadstring(L, "print('hello')"); int func2 = lua_gettop(L); int index = hs_create_table (L, hs_tbl_func(table1_a, func1), hs_tbl_func(table2_a, func2)); loadkey_tbl(index, table1_b); checkval_func(func1); loadkey_tbl(index, table2_b); checkval_func(func2); return 0; } TEST(create_table_tbl_cfunc) { create_table_keys(); int index = hs_create_table (L, hs_tbl_cfunc(table1_a, testfunc1), hs_tbl_cfunc(table2_a, testfunc2)); loadkey_tbl(index, table1_b); checkval_cfunc(testfunc1); loadkey_tbl(index, table2_b); checkval_cfunc(testfunc2); return 0; } TEST(create_table_tbl_user) { create_table_keys(); lua_newuserdata(L, sizeof(char)); int user1 = lua_gettop(L); lua_newuserdata(L, sizeof(char)); int user2 = lua_gettop(L); int index = hs_create_table (L, hs_tbl_user(table1_a, user1), hs_tbl_user(table2_a, user2)); loadkey_tbl(index, table1_b); checkval_user(user1); loadkey_tbl(index, table2_b); checkval_user(user2); return 0; } TEST(create_table_tbl_light) { create_table_keys(); int a1 = 5; void *light1 = (void *) &a1; int a2 = 6; void *light2 = (void *) &a2; int index = hs_create_table (L, hs_tbl_light(table1_a, light1), hs_tbl_light(table2_a, light2)); loadkey_tbl(index, table1_b); checkval_light(light1); loadkey_tbl(index, table2_b); checkval_light(light2); 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); /* boolean keys */ mu_run_test("create table with boolean keys and boolean values", create_table_bool_bool); mu_run_test("create table with boolean keys and integer values", \ create_table_bool_int); mu_run_test("create table with boolean keys and number values", \ create_table_bool_num); mu_run_test("create table with boolean keys and string values", \ create_table_bool_str); mu_run_test("create table with boolean keys and table values", \ create_table_bool_tbl); mu_run_test("create table with boolean keys and function values", \ create_table_bool_func); mu_run_test("create table with boolean keys and C function values", \ create_table_bool_cfunc); mu_run_test("create table with boolean keys and userdata values", \ create_table_bool_user); mu_run_test("create table with boolean keys and light userdata values", \ create_table_bool_light); /* integer keys */ mu_run_test("create table with integer keys and boolean values", create_table_int_bool); mu_run_test("create table with integer keys and integer values", \ create_table_int_int); mu_run_test("create table with integer keys and number values", \ create_table_int_num); mu_run_test("create table with integer keys and string values", \ create_table_int_str); mu_run_test("create table with integer keys and table values", \ create_table_int_tbl); mu_run_test("create table with integer keys and function values", \ create_table_int_func); mu_run_test("create table with integer keys and C function values", \ create_table_int_cfunc); mu_run_test("create table with integer keys and userdata values", \ create_table_int_user); mu_run_test("create table with integer keys and light userdata values", \ create_table_int_light); /* number keys */ mu_run_test("create table with number keys and boolean values", create_table_num_bool); mu_run_test("create table with number keys and integer values", \ create_table_num_int); mu_run_test("create table with number keys and number values", \ create_table_num_num); mu_run_test("create table with number keys and string values", \ create_table_num_str); mu_run_test("create table with number keys and table values", \ create_table_num_tbl); mu_run_test("create table with number keys and function values", \ create_table_num_func); mu_run_test("create table with number keys and C function values", \ create_table_num_cfunc); mu_run_test("create table with number keys and userdata values", \ create_table_num_user); mu_run_test("create table with number keys and light userdata values", \ create_table_num_light); /* string keys */ mu_run_test("create table with string keys and boolean values", create_table_str_bool); mu_run_test("create table with string keys and integer values", \ create_table_str_int); mu_run_test("create table with string keys and number values", \ create_table_str_num); mu_run_test("create table with string keys and string values", \ create_table_str_str); mu_run_test("create table with string keys and table values", \ create_table_str_tbl); mu_run_test("create table with string keys and function values", \ create_table_str_func); mu_run_test("create table with string keys and C function values", \ create_table_str_cfunc); mu_run_test("create table with string keys and userdata values", \ create_table_str_user); mu_run_test("create table with string keys and light userdata values", \ create_table_str_light); /* table keys */ mu_run_test("create table with table keys and boolean values", create_table_tbl_bool); mu_run_test("create table with table keys and integer values", \ create_table_tbl_int); mu_run_test("create table with table keys and number values", \ create_table_tbl_num); mu_run_test("create table with table keys and string values", \ create_table_tbl_str); mu_run_test("create table with table keys and table values", \ create_table_tbl_tbl); mu_run_test("create table with table keys and function values", \ create_table_tbl_func); mu_run_test("create table with table keys and C function values", \ create_table_tbl_cfunc); mu_run_test("create table with table keys and userdata values", \ create_table_tbl_user); mu_run_test("create table with table keys and light userdata values", \ create_table_tbl_light); }