439
edits
(allow suppression of headers and of individual templates, and track any "heading" arguments in Category:Test cases using heading parameters) |
m (87 revisions imported from wikipedia:Module:Template_test_case) |
||
(29 intermediate revisions by 11 users not shown) | |||
Line 94: | Line 94: | ||
function Template:getFullPage() | function Template:getFullPage() | ||
if self.template then | if not self.template then | ||
return self.title.prefixedText | |||
elseif self.template:sub(1, 7) == '#invoke' then | |||
return 'Module' .. self.template:sub(8):gsub('|.*', '') | |||
else | |||
local strippedTemplate, hasColon = self.template:gsub('^:', '', 1) | local strippedTemplate, hasColon = self.template:gsub('^:', '', 1) | ||
hasColon = hasColon > 0 | hasColon = hasColon > 0 | ||
Line 106: | Line 110: | ||
return mw.site.namespaces[10].name .. ':' .. strippedTemplate | return mw.site.namespaces[10].name .. ':' .. strippedTemplate | ||
end | end | ||
end | end | ||
end | end | ||
Line 138: | Line 140: | ||
function Template:getInvocation(format) | function Template:getInvocation(format) | ||
local invocation = self._invocation:getInvocation | local invocation = self._invocation:getInvocation{ | ||
template = self:getName(), | |||
requireMagicWord = self.requireMagicWord, | |||
} | |||
if format == 'code' then | if format == 'code' then | ||
invocation = '<code>' .. mw.text.nowiki(invocation) .. '</code>' | invocation = '<code>' .. mw.text.nowiki(invocation) .. '</code>' | ||
elseif format == 'kbd' then | |||
invocation = '<kbd>' .. mw.text.nowiki(invocation) .. '</kbd>' | |||
elseif format == 'plain' then | elseif format == 'plain' then | ||
invocation = mw.text.nowiki(invocation) | invocation = mw.text.nowiki(invocation) | ||
Line 153: | Line 160: | ||
function Template:getOutput() | function Template:getOutput() | ||
return self._invocation | local protect = require('Module:Protect') | ||
-- calling self._invocation:getOutput{...} | |||
return protect(self._invocation.getOutput)(self._invocation, { | |||
template = self:getName(), | |||
requireMagicWord = self.requireMagicWord, | |||
}) | |||
end | end | ||
Line 169: | Line 181: | ||
columns = 'renderColumns', | columns = 'renderColumns', | ||
rows = 'renderRows', | rows = 'renderRows', | ||
tablerows = 'renderRows', | |||
inline = 'renderInline', | inline = 'renderInline', | ||
cells = 'renderCells', | |||
default = 'renderDefault' | default = 'renderDefault' | ||
} | } | ||
Line 197: | Line 211: | ||
generalOptions.showcode = yesno(generalOptions.showcode) | generalOptions.showcode = yesno(generalOptions.showcode) | ||
generalOptions.showheader = yesno(generalOptions.showheader) ~= false | generalOptions.showheader = yesno(generalOptions.showheader) ~= false | ||
generalOptions.showcaption = yesno(generalOptions.showcaption) ~= false | |||
generalOptions.collapsible = yesno(generalOptions.collapsible) | generalOptions.collapsible = yesno(generalOptions.collapsible) | ||
generalOptions.notcollapsed = yesno(generalOptions.notcollapsed) | |||
generalOptions.wantdiff = yesno(generalOptions.wantdiff) | |||
obj.options = generalOptions | obj.options = generalOptions | ||
Line 264: | Line 281: | ||
return ret | return ret | ||
end)(templateOptions) | end)(templateOptions) | ||
-- Don't require the __TEMPLATENAME__ magic word for nowiki invocations if | |||
-- there is only one template being output. | |||
if #templateOptions <= 1 then | |||
templateOptions[1].requireMagicWord = false | |||
end | |||
mw.logObject(templateOptions) | |||
-- Make the template objects | -- Make the template objects | ||
obj.templates = {} | obj.templates = {} | ||
for i, | for i, options in ipairs(templateOptions) do | ||
table.insert(obj.templates, Template.new(invocationObj, | table.insert(obj.templates, Template.new(invocationObj, options)) | ||
end | end | ||
-- Add tracking categories. At the moment we are only tracking templates | -- Add tracking categories. At the moment we are only tracking templates | ||
-- that use any "heading" parameters. | -- that use any "heading" parameters or an "output" parameter. | ||
obj.categories = {} | obj.categories = {} | ||
for k, v in pairs(options) do | for k, v in pairs(options) do | ||
if type(k) == 'string' and k:find('heading') then | if type(k) == 'string' and k:find('heading') then | ||
categories['Test cases using heading parameters'] = true | obj.categories['Test cases using heading parameters'] = true | ||
elseif k == 'output' then | |||
obj.categories['Test cases using output parameter'] = true | |||
end | end | ||
end | end | ||
Line 301: | Line 327: | ||
local out = obj:getOutput() | local out = obj:getOutput() | ||
-- Remove the random parts from strip markers. | -- Remove the random parts from strip markers. | ||
out = out:gsub('(% | out = out:gsub('(\127\'"`UNIQ.-)%-%x+%-(QINU`"\'\127)', '%1%2') | ||
return out | return out | ||
end | end | ||
Line 315: | Line 341: | ||
function TestCase:makeCollapsible(s) | function TestCase:makeCollapsible(s) | ||
local title = self.options.title or self.templates[1]:makeHeader() | |||
if self.options.titlecode then | |||
title = self.templates[1]:getInvocation('kbd') | |||
end | |||
local isEqual = self:templateOutputIsEqual() | local isEqual = self:templateOutputIsEqual() | ||
local root = mw.html.create('table') | local root = mw.html.create('table') | ||
if self.options.wantdiff then | |||
root | |||
:addClass('mw-collapsible') | |||
if self.options.notcollapsed == false then | |||
root | |||
:addClass('mw-collapsed') | |||
end | |||
root | root | ||
:addClass('collapsible') | :css('background-color', 'transparent') | ||
:addClass(isEqual and 'collapsed' or nil) | :css('width', '100%') | ||
:css('border', 'solid silver 1px') | |||
:tag('tr') | |||
:tag('th') | |||
:css('background-color', isEqual and 'yellow' or '#90a8ee') | |||
:wikitext(title) | |||
:done() | |||
:done() | |||
:tag('tr') | |||
:tag('td') | |||
:newline() | |||
:wikitext(s) | |||
:newline() | |||
else | |||
root | |||
:addClass('mw-collapsible') | |||
if self.options.notcollapsed == false then | |||
root | |||
:addClass('mw-collapsed') | |||
end | |||
if self.options.notcollapsed ~= true or false then | |||
root | |||
:addClass(isEqual and 'mw-collapsed' or nil) | |||
end | |||
root | |||
:css('background-color', 'transparent') | :css('background-color', 'transparent') | ||
:css('width', '100%') | :css('width', '100%') | ||
Line 326: | Line 387: | ||
:tag('th') | :tag('th') | ||
:css('background-color', isEqual and 'lightgreen' or 'yellow') | :css('background-color', isEqual and 'lightgreen' or 'yellow') | ||
:wikitext( | :wikitext(title) | ||
:done() | :done() | ||
:done() | :done() | ||
Line 334: | Line 395: | ||
:wikitext(s) | :wikitext(s) | ||
:newline() | :newline() | ||
end | |||
return tostring(root) | return tostring(root) | ||
end | end | ||
Line 349: | Line 411: | ||
if self.options.showheader then | if self.options.showheader then | ||
-- Caption | -- Caption | ||
tableroot | if self.options.showcaption then | ||
tableroot | |||
:addClass(self.options.class) | |||
:cssText(self.options.style) | |||
:tag('caption') | |||
:wikitext(self.options.caption or self:message('columns-header')) | |||
end | |||
-- Headers | -- Headers | ||
Line 386: | Line 450: | ||
-- Template output | -- Template output | ||
for i, obj in ipairs(self.templates) do | for i, obj in ipairs(self.templates) do | ||
dataRow:tag('td') | if self.options.output == 'nowiki+' then | ||
:newline() | dataRow:tag('td') | ||
:wikitext(self.options.before) | :newline() | ||
:wikitext(self.options.before) | |||
:wikitext(self:getTemplateOutput(obj)) | |||
:wikitext(self.options.after) | |||
:wikitext('<pre style="white-space: pre-wrap;">') | |||
:wikitext(mw.text.nowiki(self.options.before or "")) | |||
:wikitext(mw.text.nowiki(self:getTemplateOutput(obj))) | |||
:wikitext(mw.text.nowiki(self.options.after or "")) | |||
:wikitext('</pre>') | |||
elseif self.options.output == 'nowiki' then | |||
dataRow:tag('td') | |||
:newline() | |||
:wikitext(mw.text.nowiki(self.options.before or "")) | |||
:wikitext(mw.text.nowiki(self:getTemplateOutput(obj))) | |||
:wikitext(mw.text.nowiki(self.options.after or "")) | |||
else | |||
dataRow:tag('td') | |||
:newline() | |||
:wikitext(self.options.before) | |||
:wikitext(self:getTemplateOutput(obj)) | |||
:wikitext(self.options.after) | |||
end | |||
end | end | ||
Line 416: | Line 499: | ||
for _, obj in ipairs(self.templates) do | for _, obj in ipairs(self.templates) do | ||
-- | local dataRow = tableroot:tag('tr') | ||
-- Header | |||
if self.options.showheader then | if self.options.showheader then | ||
if self.options.format == 'tablerows' then | |||
:css('text-align', 'center') | dataRow:tag('th') | ||
:attr('scope', 'row') | |||
:wikitext(obj: | :css('vertical-align', 'top') | ||
:css('text-align', 'left') | |||
:wikitext(obj:makeHeader()) | |||
dataRow:tag('td') | |||
:css('vertical-align', 'top') | |||
:css('padding', '0 1em') | |||
:wikitext('→') | |||
else | |||
dataRow:tag('td') | |||
:css('text-align', 'center') | |||
:css('font-weight', 'bold') | |||
:wikitext(obj:makeHeader()) | |||
dataRow = tableroot:tag('tr') | |||
end | |||
end | |||
-- Template output | |||
if self.options.output == 'nowiki+' then | |||
dataRow:tag('td') | |||
:newline() | |||
:wikitext(self:getTemplateOutput(obj)) | |||
:wikitext('<pre style="white-space: pre-wrap;">') | |||
:wikitext(mw.text.nowiki(self:getTemplateOutput(obj))) | |||
:wikitext('</pre>') | |||
elseif self.options.output == 'nowiki' then | |||
dataRow:tag('td') | |||
:newline() | |||
:wikitext(mw.text.nowiki(self:getTemplateOutput(obj))) | |||
else | |||
dataRow:tag('td') | |||
:newline() | |||
:wikitext(self:getTemplateOutput(obj)) | |||
end | end | ||
end | end | ||
Line 436: | Line 549: | ||
for i, obj in ipairs(self.templates) do | for i, obj in ipairs(self.templates) do | ||
local line = {} | local line = {} | ||
line[#line + 1] = '* ' | line[#line + 1] = self.options.prefix or '* ' | ||
if self.options.showcode then | if self.options.showcode then | ||
line[#line + 1] = obj:getInvocation('code') | line[#line + 1] = obj:getInvocation('code') | ||
Line 443: | Line 556: | ||
line[#line + 1] = ' ' | line[#line + 1] = ' ' | ||
end | end | ||
line[#line + 1] = self:getTemplateOutput(obj) | if self.options.output == 'nowiki+' then | ||
line[#line + 1] = self:getTemplateOutput(obj) | |||
line[#line + 1] = '<pre style="white-space: pre-wrap;">' | |||
line[#line + 1] = mw.text.nowiki(self:getTemplateOutput(obj)) | |||
line[#line + 1] = '</pre>' | |||
elseif self.options.output == 'nowiki' then | |||
line[#line + 1] = mw.text.nowiki(self:getTemplateOutput(obj)) | |||
else | |||
line[#line + 1] = self:getTemplateOutput(obj) | |||
end | |||
ret[#ret + 1] = table.concat(line) | |||
end | |||
if self.options.addline then | |||
local line = {} | |||
line[#line + 1] = self.options.prefix or '* ' | |||
line[#line + 1] = self.options.addline | |||
ret[#ret + 1] = table.concat(line) | ret[#ret + 1] = table.concat(line) | ||
end | end | ||
return table.concat(ret, '\n') | return table.concat(ret, '\n') | ||
end | |||
function TestCase:renderCells() | |||
local root = mw.html.create() | |||
local dataRow = root:tag('tr') | |||
dataRow | |||
:css('vertical-align', 'top') | |||
:addClass(self.options.class) | |||
:cssText(self.options.style) | |||
-- Row header | |||
if self.options.rowheader then | |||
dataRow:tag('th') | |||
:attr('scope', 'row') | |||
:newline() | |||
:wikitext(self.options.rowheader or self:message('row-header')) | |||
end | |||
-- Caption | |||
if self.options.showcaption then | |||
dataRow:tag('th') | |||
:attr('scope', 'row') | |||
:newline() | |||
:wikitext(self.options.caption or self:message('columns-header')) | |||
end | |||
-- Show code | |||
if self.options.showcode then | |||
dataRow:tag('td') | |||
:newline() | |||
:wikitext(self:getInvocation('code')) | |||
end | |||
-- Template output | |||
for i, obj in ipairs(self.templates) do | |||
if self.options.output == 'nowiki+' then | |||
dataRow:tag('td') | |||
:newline() | |||
:wikitext(self.options.before) | |||
:wikitext(self:getTemplateOutput(obj)) | |||
:wikitext(self.options.after) | |||
:wikitext('<pre style="white-space: pre-wrap;">') | |||
:wikitext(mw.text.nowiki(self.options.before or "")) | |||
:wikitext(mw.text.nowiki(self:getTemplateOutput(obj))) | |||
:wikitext(mw.text.nowiki(self.options.after or "")) | |||
:wikitext('</pre>') | |||
elseif self.options.output == 'nowiki' then | |||
dataRow:tag('td') | |||
:newline() | |||
:wikitext(mw.text.nowiki(self.options.before or "")) | |||
:wikitext(mw.text.nowiki(self:getTemplateOutput(obj))) | |||
:wikitext(mw.text.nowiki(self.options.after or "")) | |||
else | |||
dataRow:tag('td') | |||
:newline() | |||
:wikitext(self.options.before) | |||
:wikitext(self:getTemplateOutput(obj)) | |||
:wikitext(self.options.after) | |||
end | |||
end | |||
return tostring(root) | |||
end | end | ||
Line 459: | Line 649: | ||
ret[#ret + 1] = obj:makeHeader() | ret[#ret + 1] = obj:makeHeader() | ||
end | end | ||
ret[#ret + 1] = self:getTemplateOutput(obj) | if self.options.output == 'nowiki+' then | ||
ret[#ret + 1] = self:getTemplateOutput(obj) .. '<pre style="white-space: pre-wrap;">' .. mw.text.nowiki(self:getTemplateOutput(obj)) .. '</pre>' | |||
elseif self.options.output == 'nowiki' then | |||
ret[#ret + 1] = mw.text.nowiki(self:getTemplateOutput(obj)) | |||
else | |||
ret[#ret + 1] = self:getTemplateOutput(obj) | |||
end | |||
end | end | ||
return table.concat(ret, '\n\n') | return table.concat(ret, '\n\n') | ||
Line 500: | Line 696: | ||
end | end | ||
function NowikiInvocation:getInvocation( | function NowikiInvocation:getInvocation(options) | ||
template = template:gsub('%%', '%%%%') -- Escape "%" with "%%" | local template = options.template:gsub('%%', '%%%%') -- Escape "%" with "%%" | ||
local invocation, count = self.invocation:gsub( | local invocation, count = self.invocation:gsub( | ||
self.cfg.templateNameMagicWordPattern, | self.cfg.templateNameMagicWordPattern, | ||
template | template | ||
) | ) | ||
if count < 1 then | if options.requireMagicWord ~= false and count < 1 then | ||
error(self:message( | error(self:message( | ||
'nowiki-magic-word-error', | 'nowiki-magic-word-error', | ||
Line 515: | Line 711: | ||
end | end | ||
function NowikiInvocation:getOutput( | function NowikiInvocation:getOutput(options) | ||
local invocation = self:getInvocation( | local invocation = self:getInvocation(options) | ||
return mw.getCurrentFrame():preprocess(invocation) | return mw.getCurrentFrame():preprocess(invocation) | ||
end | end | ||
Line 536: | Line 732: | ||
end | end | ||
function TableInvocation:getInvocation( | function TableInvocation:getInvocation(options) | ||
if self.code then | if self.code then | ||
local nowikiObj = NowikiInvocation.new(self.code, self.cfg) | local nowikiObj = NowikiInvocation.new(self.code, self.cfg) | ||
return nowikiObj:getInvocation( | return nowikiObj:getInvocation(options) | ||
else | else | ||
return require('Module:Template invocation').invocation( | return require('Module:Template invocation').invocation( | ||
template, | options.template, | ||
self.invokeArgs | self.invokeArgs | ||
) | ) | ||
Line 548: | Line 744: | ||
end | end | ||
function TableInvocation:getOutput(template) | function TableInvocation:getOutput(options) | ||
if (options.template:sub(1, 7) == '#invoke') then | |||
local moduleCall = mw.text.split(options.template, '|', true) | |||
local args = mw.clone(self.invokeArgs) | |||
table.insert(args, 1, moduleCall[2]) | |||
return mw.getCurrentFrame():callParserFunction(moduleCall[1], args) | |||
end | |||
return mw.getCurrentFrame():expandTemplate{ | return mw.getCurrentFrame():expandTemplate{ | ||
title = template, | title = options.template, | ||
args = self.invokeArgs | args = self.invokeArgs | ||
} | } |