Module:Convert/tester: Difference between revisions

Content deleted Content added
try "make_expected=yes" option
better for make_tests to be function; p.tests can be a table
Line 4:
-- The expected text must be in a single line, but can include "\n" (two characters)
-- to indicate that a newline is expected.
-- Tests are run (or created) by setting p.tests then(string executingor run_teststable), or
-- by setting page=PAGE_TITLE (and optionally section=SECTION_TITLE) in the invoke,
-- then executing run_tests (or make_tests).
-- Adapted from [[Module:ConvertTestcase]].
 
local function boolean(text)
-- Return true if text represents a "true" option value.
if text then
text = text:lower()
if text == 'on' or text == 'yes' then
return true
end
end
return false
end
 
local function collection()
Line 88 ⟶ 77:
end
 
local function run_template(frame, template, collapse_multiline)
local title, argstr = template:match('^{{%s*(.-)%s*|(.*)}}$')
if title == nil or title == '' or argstr == '' then
Line 106 ⟶ 95:
end
local ok, result = pcall(expand, { title = title, args = args })
if not ok then
returnresult = 'Error: ' .. result
end
if collapse_multiline then
return 'Error: ' .. result
result = result:gsub('\n', '\\n')
end
return result
end
 
local function _run_tests_make_tests(frame, all_tests)
local maxlen = 38
if type(all_tests) ~= 'string' then
for _, item in ipairs(all_tests) do
error('No tests were specified; see [[Module:Convert/tester/doc]].', 0)
local template = item[1]
local templen = mw.ustring.len(template)
item.templen = templen
if maxlen < templen and templen <= 70 then
maxlen = templen
end
end
local make_expectedresult = booleancollection(frame.args.make_expected)
for _, item in ipairs(all_tests) do
local function collapse_multiline(text)
returnlocal text:gsub('\n',template '\\n')= item[1]
local actual = run_template(frame, template, true)
local pad = string.rep(' ', maxlen - item.templen) .. ' '
result:add(template .. pad .. actual)
end
-- Pre tags returned by a module are html tags, not like wikitext <pre>...</pre>.
return '<pre>\n' .. mw.text.nowiki(result:join()) .. '\n</pre>\n'
end
 
local function _run_tests(frame, all_tests)
local function safe_cell(text, multiline)
-- For testing {{convert}}, want wikitext like '[[kilogram|kg]]' to be unchanged
Line 138 ⟶ 144:
return text
end
local maxlen = 60 -- should determine this by examining each template
local stats = { pass = 0, fail = 0, ignored = 0 }
local result = collection()
result:add('{| class="wikitable"')
if not make_expected then
result:add('{|! Template !! Expected !! Actual, if different !! class="wikitable"Status')
for _, item in ipairs(all_tests) do
result:add('! Template !! Expected !! Actual, if different !! Status')
local template, expected = item[1], item[2]
end
local actual = run_template(frame, template, true)
for pos, template, expected in all_tests:gmatch('()({{.-}})(.-)\n') do
local sbox, isfail
-- Skip templates that are not at the start of a line to reduce likelihood
actual, sbox, isfail = status_box(stats, expected, actual)
-- of using unwanted templates when reading a page.
result:add('|-')
if pos == 1 or all_tests:sub(pos-1, pos-1) == '\n' then
result:add('| ' .. local actual = collapse_multilinesafe_cell(run_template(frame, template))
result:add('| ' .. safe_cell(expected, true))
if make_expected then
result:add('| ' .. safe_cell(actual, true))
local pad = string.rep(' ', maxlen - mw.ustring.len(template))
result:add(template .. pad .. '| ' .. actualsbox)
if isfail elsethen
local sbox, isfailresult:add('|-')
result:add('| expected align="center"| strip(expectedabove, nowiki)')
result:add('| ' .. actual, sbox, isfail = status_boxnowiki_cell(stats, expected, actualtrue))
result:add('|- ' .. nowiki_cell(actual, true))
result:add('| ' .. safe_cell(template))
result:add('| ' .. safe_cell(expected, true))
result:add('| ' .. safe_cell(actual, true))
result:add('| ' .. sbox)
if isfail then
result:add('|-')
result:add('| align="center"| (above, nowiki)')
result:add('| ' .. nowiki_cell(expected, true))
result:add('| ' .. nowiki_cell(actual, true))
result:add('|')
end
end
end
end
if make_expected then
-- Pre tags returned by a module are html tags, not like wikitext <pre>...</pre>.
return '<pre>\n' .. mw.text.nowiki(result:join()) .. '\n</pre>\n'
end
result:add('|}')
Line 223 ⟶ 213:
end
 
local function get_tests(page_titleframe, section_title, test_texttests)
local args = frame.args
local page_title, section_title = args.page, args.section
if not empty(page_title) then
if not empty(test_texttests) then
error('Invoke must not set "page=' .. page_title .. '" if also setting p.tests.', 0)
end
Line 231 ⟶ 223:
page_title = strip(page_title:sub(3, -3))
end
test_texttests = get_page_content(page_title)
if not empty(section_title) then
local s = sections(test_texttests)
while true do
local heading = s:next_heading()
if heading then
if heading == section_title then
returntests = s:current_body()
break
end
else
Line 246 ⟶ 239:
end
end
if type(tests) ~= 'string' then
return test_text
if type(tests) == 'table' then
return tests
end
error('No tests were specified; see [[Module:Convert/tester/doc]].', 0)
end
local all_tests = collection()
for line in (tests .. '\n'):gmatch('([^\n]+)\n') do
local template, expected = line:match('^({{.-}})%s*(.-)%s*$')
if template then
all_tests:add({ template, expected })
end
end
if all_tests.n == 0 then
error('No templates found; see [[Module:Convert/tester/doc]].', 0)
end
return all_tests
end
 
local pfunction =main(frame, p, {}worker)
local ok, result = pcall(get_tests, frame, p.tests)
 
function p.run_tests(frame)
local args = frame.args
local ok, result = pcall(get_tests, args.page, args.section, p.tests)
if ok then
ok, result = pcall(_run_testsworker, frame, result)
if ok then
return result
Line 261 ⟶ 267:
end
return '<strong class="error">Error</strong>\n\n' .. result
end
 
local p = {}
 
function p.make_tests(frame)
return main(frame, p, _make_tests)
end
 
function p.run_tests(frame)
return main(frame, p, _run_tests)
end