-- Test the output from a template by comparing it with fixed text.-- 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 (string or table), or-- by setting page=PAGE_TITLE (and optionally section=SECTION_TITLE),-- then executing run_tests (or make_tests).
local Collection = Collection.__index = Collectiondo function Collection:add(item) if item ~= nil then self.n = self.n + 1 self[self.n] = item end end function Collection:join(sep) return table.concat(self, sep) end function Collection.new return setmetatable(Collection) endend
local function empty(text) -- Return true if text is nil or empty (assuming a string). return text
end
local function strip(text) -- Return text with no leading/trailing whitespace. return text:match("^%s*(.-)%s*$")end
local function normalize(text) -- Return text with any strip markers normalized by replacing the -- unique number with a fixed value so comparisons work. return text:gsub('(\127[^\127]*UNIQ[^\127]*%-)(%x+)(-QINU[^\127]*\127)', '%100000000%3')end
local function status_box(stats, expected, actual, iscomment) local label, bgcolor, align, isfail if iscomment then actual = align = 'center' bgcolor = 'silver' label = 'Cmnt' elseif expected
normalize(actual) then stats.pass = stats.pass + 1 actual = align = 'center' bgcolor = 'green' label = 'Pass' else stats.fail = stats.fail + 1 align = 'center' bgcolor = 'red' label = 'Fail' isfail = true end local sbox = 'style="text-align:' .. align .. ';color:white;background:' .. bgcolor .. ';" | ' .. label return sbox, actual, isfailend
local function status_text(stats) local bgcolor, ignored_text, msg, ttext if stats.template then ttext = "Using : " else ttext = end if stats.fail
0 then bgcolor = 'salmon' msg = 'No tests performed' else bgcolor = 'green' msg = string.format('All %d tests passed', stats.pass) end else bgcolor = 'darkred' msg = string.format('%d test%s failed', stats.fail, stats.fail
0 then ignored_text = else bgcolor = 'salmon' ignored_text = string.format(', %d test%s ignored because expected text is blank', stats.ignored, stats.ignored
local function run_template(frame, template, args, collapse_multiline) -- Template "" -- gives xargs . if template:sub(1, 2)
'val' then v = strip(v) if v
nil then templatename = args.template or strip(field) if templatename
local function _make_tests(frame, all_tests, args) local maxlen = 38 for _, item in ipairs(all_tests) do local template = item[1] if template then local templen = mw.ustring.len(template) item.templen = templen if maxlen < templen and templen <= 70 then maxlen = templen end end end local result = Collection.new for _, item in ipairs(all_tests) do local template = item[1] if template then local actual = run_template(frame, template, args, true) local pad = string.rep(' ', maxlen - item.templen) .. ' ' result:add(template .. pad .. actual) else local text = item.text if text then result:add(text) end end end -- Pre tags returned by a module are html tags, not like wikitext
.... return '
\n' .. mw.text.nowiki(result:join('\n')) .. '\n'end
local function _run_tests(frame, all_tests, args) local function safe_cell(text, multiline) -- For testing, want wikitext like 'kg' to be unchanged -- so the link works and so the displayed text is short (just "kg" in example). text = text:gsub('(%[%[[^%[%]]-)|(.-%]%])', '%1\0%2') -- replace pipe in piped link with a zero byte text = text:gsub('