Module:Template test case: Difference between revisions
(make a start on the exports) |
(add nowiki exports and finish the NowikiInvocation class) |
||
| Line 4: | Line 4: | ||
local libraryUtil = require('libraryUtil') | local libraryUtil = require('libraryUtil') | ||
local checkType = libraryUtil.checkType | local checkType = libraryUtil.checkType | ||
local TEMPLATE_NAME_MAGIC_WORD = '<TEMPLATE_NAME>' | |||
local TEMPLATE_NAME_MAGIC_WORD_ESCAPED = TEMPLATE_NAME_MAGIC_WORD:gsub('%p', '%%%0') | |||
------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | ||
| Line 73: | Line 76: | ||
function Invocation:getOptions() | function Invocation:getOptions() | ||
return self._options | return self._options | ||
end | end | ||
| Line 95: | Line 90: | ||
setmetatable(obj, NowikiInvocation) | setmetatable(obj, NowikiInvocation) | ||
obj.invocation = mw.text.unstrip(args.invocation) | |||
args.invocation = nil | |||
local options = {} | local options = {} | ||
for k, v in pairs(args) do | |||
options[k] = v | |||
end | |||
obj.options = options | |||
return obj | return obj | ||
| Line 101: | Line 102: | ||
function NowikiInvocation:getInvocation(template) | function NowikiInvocation:getInvocation(template) | ||
template = template:gsub('%%', '%%%%') -- Escape a % with %% | |||
local invocation, count = self.invocation:gsub( | |||
TEMPLATE_NAME_MAGIC_WORD_ESCAPED, | |||
template | |||
) | |||
if count < 1 then | |||
error(string.format( | |||
"the template invocation must include '%s' in place " .. | |||
"of the template name", | |||
TEMPLATE_NAME_MAGIC_WORD | |||
)) | |||
end | |||
return invocation | |||
end | end | ||
function NowikiInvocation:getOutput(template) | function NowikiInvocation:getOutput(template) | ||
local invocation = self:getInvocation(template) | |||
return mw.getCurrentFrame():preprocess(invocation) | |||
end | end | ||
| Line 187: | Line 203: | ||
-- Exports | -- Exports | ||
------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | ||
-- Table-based exports | |||
local function getTableArgs(frame, wrappers) | local function getTableArgs(frame, wrappers) | ||
| Line 226: | Line 244: | ||
return p._table(args) | return p._table(args) | ||
end | end | ||
-- Nowiki-based exports | |||
function p._nowiki(args) | |||
local invocation = NowikiInvocation.new(args) | |||
return invocation | |||
end | |||
function p.nowiki(frame) | |||
local args = require('Module:Arguments').getArgs(frame, { | |||
wrappers = 'Template:Test case' | |||
}) | |||
return p._nowiki(args) | |||
end | |||
-- Exports for testing | |||
function p._exportClasses() | function p._exportClasses() | ||
Revision as of 10:16, 24 November 2014
Documentation for this module may be created at Module:Template test case/doc
-- This module provides several methods to generate test cases.
local mTableTools = require('Module:TableTools')
local libraryUtil = require('libraryUtil')
local checkType = libraryUtil.checkType
local TEMPLATE_NAME_MAGIC_WORD = '<TEMPLATE_NAME>'
local TEMPLATE_NAME_MAGIC_WORD_ESCAPED = TEMPLATE_NAME_MAGIC_WORD:gsub('%p', '%%%0')
-------------------------------------------------------------------------------
-- Helper functions
-------------------------------------------------------------------------------
--[[
local function validateTemplateOptions()
-- Add the template names for the first two templates if they weren't
-- specified.
do
local title = mw.title.getCurrentTitle().basePageTitle
local template
if title.namespace == 10 then
template = title.text
elseif title.namespace == 0 then
template = ':' .. title.prefixedText
else
template = title.prefixedText
end
local templatePage = title.prefixedText
templateOptions[1] = templateOptions[1] or {}
templateOptions[1].templatePage = templateOptions[1].template or templatePage
templateOptions[1].template = templateOptions[1].template or template
templateOptions[2] = templateOptions[2] or {}
templateOptions[2].templatePage = templateOptions[2].template or templatePage .. '/sandbox'
templateOptions[2].template = templateOptions[2].template or template .. '/sandbox'
end
-- Validate options for three or more templates.
if #templateOptions >= 3 then
for i = 3, #templateOptions do
local template = templateOptions[i].template
if not template then
error('arguments for a third or subsequent ' ..
'template were found, but no template name ' ..
'was specified', 3)
end
end
end
end
--]]
local function parseTemplateOptions(origOptions)
-- Given a table of raw options, returns a table of general options
-- and template options.
local templateOptions = mTableTools.numData(origOptions, true)
local options = templateOptions.other
templateOptions.other = nil
return options, templateOptions
end
-------------------------------------------------------------------------------
-- Invocation class
-------------------------------------------------------------------------------
local Invocation = {}
Invocation.__index = Invocation
function Invocation.new()
local obj = setmetatable({}, TableInvocation)
return obj
end
function Invocation:setOptions(t)
self._options = t
end
function Invocation:getOptions()
return self._options
end
-------------------------------------------------------------------------------
-- Nowiki invocation class
-------------------------------------------------------------------------------
local NowikiInvocation = setmetatable({}, Invocation)
NowikiInvocation.__index = NowikiInvocation
function NowikiInvocation.new(args)
checkType('NowikiInvocation.new', 'args', args, 'table')
local obj = Invocation.new()
setmetatable(obj, NowikiInvocation)
obj.invocation = mw.text.unstrip(args.invocation)
args.invocation = nil
local options = {}
for k, v in pairs(args) do
options[k] = v
end
obj.options = options
return obj
end
function NowikiInvocation:getInvocation(template)
template = template:gsub('%%', '%%%%') -- Escape a % with %%
local invocation, count = self.invocation:gsub(
TEMPLATE_NAME_MAGIC_WORD_ESCAPED,
template
)
if count < 1 then
error(string.format(
"the template invocation must include '%s' in place " ..
"of the template name",
TEMPLATE_NAME_MAGIC_WORD
))
end
return invocation
end
function NowikiInvocation:getOutput(template)
local invocation = self:getInvocation(template)
return mw.getCurrentFrame():preprocess(invocation)
end
-------------------------------------------------------------------------------
-- Table invocation class
-------------------------------------------------------------------------------
local TableInvocation = {}
TableInvocation.__index = TableInvocation
function TableInvocation.new(args)
checkType('TableInvocation.new', 'args', args, 'table')
local obj = Invocation.new()
setmetatable(obj, TableInvocation)
local rawOptions, invokeArgs = {}, {}
for k, v in pairs(args) do
local optionKey = type(k) == 'string' and k:match('^_(.*)$')
if optionKey then
rawOptions[optionKey] = v
else
invokeArgs[k] = v
end
end
obj.invokeArgs = invokeArgs
local options, templateOptions = parseTemplateOptions(rawOptions)
obj:setOptions(options)
obj:setTemplateOptions(templateOptions)
return obj
end
function TableInvocation:getInvocation(template)
return require('Module:Template invocation').invocation(
template,
self.invokeArgs
)
end
function TableInvocation:getOutput(template)
return mw.getCurrentFrame():expandTemplate{
title = template,
args = self.invokeArgs
}
end
-------------------------------------------------------------------------------
-- TestCase class
-------------------------------------------------------------------------------
local TestCase = {}
TestCase.__index = TestCase
function TestCase.new(invocationObj)
checkType('TestCase.new', 'invocationObj', invocationObj, 'table')
local obj = setmetatable({}, TestCase)
return obj
end
--------------------------------------------------------------------------------
-- Test case display functions
--
-- Test case display functions produce the wikitext to display the template
-- output for one test case. For example, one function might produce templates
-- aligned horizontally, and another function might produce templates aligned
-- one below the other.
--
-- They are named functions that accept the following parameters:
-- * templates - an array of subtables containing data about each template to be
-- displayed. These subtables can contain the following values:
-- * result - the expanded wikitext from the template.
-- * invocation - the original unexpanded wikitext that the output was
-- generated from. This may be nil if the invocation is not available.
-- * name - the name of the template.
-- * link - a normal wikilink to the template page (displays as
-- "Template:Foo").
-- * braceLink - a wikilink to the template page formatted like the {{tl}}
-- template, i.e. it displays as "{{Foo}}".
-- * heading - a heading to display above the template output.
--------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-- Exports
-------------------------------------------------------------------------------
-- Table-based exports
local function getTableArgs(frame, wrappers)
return require('Module:Arguments').getArgs(frame, {
wrappers = wrappers,
valueFunc = function (k, v)
if type(k) == 'string' and k:find('^_') then
v = mw.text.trim(v)
if v ~= '' then
return v
end
else
return v
end
end
})
end
local p = {}
function p._table(args)
local invocation = TableInvocation.new(args)
return invocation
end
function p.table(frame)
return p._table(getTableArgs(frame, 'Template:Test case'))
end
function p.columns(frame)
local args = getTableArgs(frame, 'Template:Testcase table')
args._format = 'columns'
return p._table(args)
end
function p.rows(frame)
local args = getTableArgs(frame, 'Template:Testcase rows')
args._format = 'rows'
return p._table(args)
end
-- Nowiki-based exports
function p._nowiki(args)
local invocation = NowikiInvocation.new(args)
return invocation
end
function p.nowiki(frame)
local args = require('Module:Arguments').getArgs(frame, {
wrappers = 'Template:Test case'
})
return p._nowiki(args)
end
-- Exports for testing
function p._exportClasses()
return {
TestCase = TestCase,
Invocation = Invocation,
NowikiInvocation = NowikiInvocation,
TableInvocation = TableInvocation
}
end
return p