Module:Template test case: Difference between revisions

    m (Mr. Stradivarius moved page Module:Template test cases to Module:Template test case without leaving a redirect: more accurate name - this module only produces one test case, not several)
    (simplify the wrapper template config by loading it in from a data module)
    Line 1: Line 1:
    -- This module provides several methods to generate test cases.
    -- This module provides several methods to generate test cases.


    -- Load required modules
    local yesno = require('Module:Yesno')
    local yesno = require('Module:Yesno')
    local mTableTools = require('Module:TableTools')
    local mTableTools = require('Module:TableTools')


    local TEMPLATE_NAME_MAGIC_WORD = '__TEMPLATENAME__'
    -- Set constants
    local TEMPLATE_NAME_MAGIC_WORD_ESCAPED = TEMPLATE_NAME_MAGIC_WORD:gsub('%p', '%%%0')
    local DATA_MODULE = 'Module:Template test case/data'


    -------------------------------------------------------------------------------
    -------------------------------------------------------------------------------
    Line 152: Line 153:
    TestCase.__index = TestCase
    TestCase.__index = TestCase


    function TestCase.new(invocationObj, options)
    function TestCase.new(invocationObj, options, cfg)
    local obj = setmetatable({}, TestCase)
    local obj = setmetatable({}, TestCase)
    obj.cfg = cfg


    -- Validate options
    -- Validate options
    Line 364: Line 366:
    NowikiInvocation.__index = NowikiInvocation
    NowikiInvocation.__index = NowikiInvocation


    function NowikiInvocation.new(invocation)
    function NowikiInvocation.new(invocation, cfg)
    local obj = setmetatable({}, NowikiInvocation)
    local obj = setmetatable({}, NowikiInvocation)
    obj.cfg = cfg
    invocation = mw.text.unstrip(invocation)
    invocation = mw.text.unstrip(invocation)
    -- Decode HTML entities for <, >, and ". This means that HTML entities in
    -- Decode HTML entities for <, >, and ". This means that HTML entities in
    Line 381: Line 384:
    template = template:gsub('%%', '%%%%') -- Escape "%" with "%%"
    template = template:gsub('%%', '%%%%') -- Escape "%" with "%%"
    local invocation, count = self.invocation:gsub(
    local invocation, count = self.invocation:gsub(
    TEMPLATE_NAME_MAGIC_WORD_ESCAPED,
    self.cfg.templateNameMagicWordPattern,
    template
    template
    )
    )
    Line 388: Line 391:
    "the template invocation must include '%s' in place " ..
    "the template invocation must include '%s' in place " ..
    "of the template name",
    "of the template name",
    TEMPLATE_NAME_MAGIC_WORD
    self.cfg.templateNameMagicWord
    ))
    ))
    end
    end
    Line 406: Line 409:
    TableInvocation.__index = TableInvocation
    TableInvocation.__index = TableInvocation


    function TableInvocation.new(invokeArgs, nowikiCode)
    function TableInvocation.new(invokeArgs, nowikiCode, cfg)
    local obj = setmetatable({}, TableInvocation)
    local obj = setmetatable({}, TableInvocation)
    obj.cfg = cfg
    obj.invokeArgs = invokeArgs
    obj.invokeArgs = invokeArgs
    obj.code = nowikiCode
    obj.code = nowikiCode
    Line 436: Line 440:
    -------------------------------------------------------------------------------
    -------------------------------------------------------------------------------


    -- Table-based exports
    local p = {}


    local function getTableArgs(frame, wrappers)
    function p.table(args, cfg)
    return require('Module:Arguments').getArgs(frame, {
    cfg = cfg or mw.loadData(DATA_MODULE)
    wrappers = wrappers,
    trim = false,
    removeBlanks = false
    })
    end


    local p = {}
    function p._table(args)
    local options, invokeArgs = {}, {}
    local options, invokeArgs = {}, {}
    for k, v in pairs(args) do
    for k, v in pairs(args) do
    Line 470: Line 466:
    options.code = nil
    options.code = nil


    local invocationObj = TableInvocation.new(invokeArgs, nowikiCode)
    local invocationObj = TableInvocation.new(invokeArgs, nowikiCode, cfg)
    local testCaseObj = TestCase.new(invocationObj, options)
    local testCaseObj = TestCase.new(invocationObj, options, cfg)
    return tostring(testCaseObj)
    return tostring(testCaseObj)
    end
    end


    function p.table(frame)
    function p.nowiki(args, cfg)
    return p._table(getTableArgs(frame, 'Template:Test case from arguments'))
    cfg = cfg or mw.loadData(DATA_MODULE)
    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 invocationObj = NowikiInvocation.new(args.code, cfg)
    local invocationObj = NowikiInvocation.new(args.code)
    args.code = nil
    args.code = nil
    -- Assume we want to see the code as we already passed it in.
    -- Assume we want to see the code as we already passed it in.
    args.showcode = args.showcode or true
    args.showcode = args.showcode or true
    local testCaseObj = TestCase.new(invocationObj, args)
    local testCaseObj = TestCase.new(invocationObj, args, cfg)
    return tostring(testCaseObj)
    return tostring(testCaseObj)
    end
    end


    function p.nowiki(frame)
    function p.main(frame, cfg)
    local args = require('Module:Arguments').getArgs(frame, {
    cfg = cfg or mw.loadData(DATA_MODULE)
    wrappers = 'Template:Test case from invocation'
     
    -- Load the wrapper config, if any.
    local wrapperConfig
    if frame.getParent then
    local title = frame:getParent():getTitle()
    local template = title:gsub(cfg.sandboxSubpagePattern, '')
    wrapperConfig = cfg.wrappers[template]
    end
     
    -- Work out the function we will call, use it to generate the config for
    -- Module:Arguments, and use Module:Arguments to find the arguments passed
    -- by the user.
    local func = wrapperConfig and wrapperConfig.func or 'table'
    local isTableFunc = func == 'table'
    local userArgs = require('Module:Arguments').getArgs(frame, {
    parentOnly = wrapperConfig,
    frameOnly = not wrapperConfig,
    trim = not isTableFunc,
    removeBlanks = not isTableFunc
    })
    })
    return p._nowiki(args)
     
    -- Get default args and build the args table. User-specified args overwrite
    -- default args.
    local defaultArgs = wrapperConfig and wrapperConfig.args or {}
    local args = {}
    for k, v in pairs(defaultArgs) do
    args[k] = v
    end
    for k, v in pairs(userArgs) do
    args[k] = v
    end
     
    return p[func](args, cfg)
    end
    end