Add lua tests for config file parsing

Bare-bones for now, more tests needed.
This commit is contained in:
Pasi Kallinen
2021-02-10 19:15:35 +02:00
parent 9576154690
commit cc25f40d69
5 changed files with 107 additions and 0 deletions

View File

@@ -171,12 +171,23 @@ Example:
=== parse_config
Parse string as if it was read from a config file.
Always call parse_config_errors afterwards to check for any parsing errors.
Example:
nh.parse_config("OPTIONS=color");
=== parse_config_errors
Returns any errors found when parsing a config file string with parse_config.
Example:
local errors = nh.parse_config("OPTIONS=color\nOPTIONS=!color");
nh.pline("Line: " .. errors[1].line .. ", " .. errors[1].error);
=== pline
Show the text in the message area.

View File

@@ -743,6 +743,9 @@ extern void makerogueghost(void);
/* ### files.c ### */
#if !defined(CROSSCOMPILE) || defined(CROSSCOMPILE_TARGET)
extern int l_get_config_errors(lua_State *);
#endif
extern char *fname_encode(const char *, char, char *, char *, int);
extern char *fname_decode(char, char *, char *, int);
extern const char *fqname(const char *, int, int);

View File

@@ -2798,6 +2798,12 @@ can_read_file(const char *filename)
}
#endif /* USER_SOUNDS */
struct _config_error_errmsg {
int line_num;
char *errormsg;
struct _config_error_errmsg *next;
};
struct _config_error_frame {
int line_num;
int num_errors;
@@ -2810,6 +2816,7 @@ struct _config_error_frame {
};
static struct _config_error_frame *config_error_data = 0;
static struct _config_error_errmsg *config_error_msg = 0;
void
config_error_init(boolean from_file, const char *sourcename, boolean secure)
@@ -2856,6 +2863,32 @@ config_error_nextline(const char *line)
return TRUE;
}
int
l_get_config_errors(lua_State *L)
{
struct _config_error_errmsg *dat = config_error_msg;
struct _config_error_errmsg *tmp;
int idx = 1;
lua_newtable(L);
while (dat) {
lua_pushinteger(L, idx++);
lua_newtable(L);
nhl_add_table_entry_int(L, "line", dat->line_num);
nhl_add_table_entry_str(L, "error", dat->errormsg);
lua_settable(L, -3);
tmp = dat->next;
free(dat->errormsg);
dat->errormsg = (char *) 0;
free(dat);
dat = tmp;
}
config_error_msg = (struct _config_error_errmsg *) 0;
return 1;
}
/* varargs 'config_error_add()' moved to pline.c */
void
config_erradd(const char *buf)
@@ -2865,6 +2898,16 @@ config_erradd(const char *buf)
if (!buf || !*buf)
buf = "Unknown error";
if (iflags.in_lua) {
struct _config_error_errmsg *dat = (struct _config_error_errmsg *) alloc(sizeof (struct _config_error_errmsg));
dat->next = config_error_msg;
dat->line_num = config_error_data->line_num;
dat->errormsg = dupstr(buf);
config_error_msg = dat;
return;
}
if (!config_error_data) {
/* either very early, where pline() will use raw_print(), or
player gave bad value when prompted by interactive 'O' command */

View File

@@ -830,6 +830,7 @@ static const struct luaL_Reg nhl_functions[] = {
{"level_difficulty", nhl_level_difficulty},
{"parse_config", nhl_parse_config},
{"get_config", nhl_get_config},
{"get_config_errors", l_get_config_errors},
{NULL, NULL}
};

49
test/test_cnf.lua Normal file
View File

@@ -0,0 +1,49 @@
local configtests = {
{ test = "OPTIONS=color", -- config string to parse
result = { }, -- errors, result of parsing the config string
extra = function() return nh.get_config("color") == "true" end -- optional, function that returns boolean, and false means the test failed.
},
{ test = "OPTIONS=!color",
result = { },
extra = function() return nh.get_config("color") == "false" end
},
{ test = "OPTIONS=!color\nOPTIONS=color",
result = { { line = 2, error = "boolean option specified multiple times: color" } }
},
};
function testtable(t1, t2)
if type(t1) ~= type(t2) then return false end
for k1, v1 in pairs(t1) do
if type(v1) == "table" and type(t2[k1]) == "table" then
if not testtable(v1, t2[k1]) then return false end
else
if v1 ~= t2[k1] then return false end
end
end
return true
end
for k, v in pairs(configtests) do
local cnf = configtests[k].test;
local err = configtests[k].result;
nh.parse_config(cnf);
local res = nh.get_config_errors();
if not testtable(err, res) then
error("Config: Results don't match");
end
if (type(configtests[k].extra) == "function") then
if configtests[k].extra() == "false" then
error("Config: Failed extra test.");
end
end
end