Add lua tests for config file parsing
Bare-bones for now, more tests needed.
This commit is contained in:
11
doc/lua.adoc
11
doc/lua.adoc
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
|
||||
43
src/files.c
43
src/files.c
@@ -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 */
|
||||
|
||||
@@ -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
49
test/test_cnf.lua
Normal 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
|
||||
Reference in New Issue
Block a user