Module:T/sandbox/testcases

From Commons Wiki
Jump to navigation Jump to search

Template:Testcases module


-- <nowiki>
local libraryUtil = require("libraryUtil")
local checkType = libraryUtil.checkType

--------------------------------------------------------------------------------
-- COMMON INPUTS
--------------------------------------------------------------------------------
local PARAMETERS = {
	'""',
	'\'\'',
	'',
	'"value"',
	'\'value\'',
	'description',
	'name=""',
	'name=\'\'',
	'name=',
	'name="value"',
	'name=\'value\'',
	'name=description',
	'name=description=',
	'name&#61;""',
	'name&#61;\'\'',
	'name&#61;',
	'name&#61;"value"',
	'name&#61;\'value\'',
	'name&#61;description',
	'name&#61;description&#61;'
}

local PARAMETERS2 = table.concat(PARAMETERS, '|'):gsub('=', '{{=}}')

--------------------------------------------------------------------------------
-- COMMON OUTPUTS
--------------------------------------------------------------------------------

--[[
-- @local
-- @function buildParameterNode
-- @param {table} args
-- @param[opt] args.index
-- @param[opt] {boolean} args.multiline
-- @param[opt] {boolean} args.noPipe
-- @param[opt] args.name
-- @param args.value
-- @param args.description
--]]
local function buildParameterNode(args)
	checkType("buildParameterNode", 1, args, "table")

	local index = args.index
	local multiline = args.multiline
	local noPipe = args.noPipe
	local name = args.name
	local value = args.value
	local description = args.description

	if (
		(value == nil and description == nil)
		or (value ~= nil and description ~= nil)
	) then
		error('Must specify exactly one of "value" or "description"')
	end

	local span = mw.html.create("span")
		:attr("data-t-role", "parameter-components")
		:attr("data-t-index", index)

	if multiline then
		span:css("display", "block")
	end

	if not noPipe then
		span:wikitext(mw.text.nowiki("|"))
	end

	if name then
		span
			:tag("span")
				:attr("data-t-role", "parameter-name")
				:css("font-weight", "bold")
				:wikitext(name)
			:done()
			:wikitext(" = ")
	end

	if value ~= nil then
		span
			:tag("span")
				:attr("data-t-role", "parameter-value")
				:wikitext(value)
			:done()
	else
		span
			:tag("span")
				:attr("data-t-role", "parameter-description")
				:css("opacity", "0.65")
				:wikitext(mw.text.nowiki("<"))
				:wikitext(description)
				:wikitext(mw.text.nowiki(">"))
			:done()
	end

	return span:done()
end

--[[
-- @local
-- @function buildParameterNodes
-- @param[opt] {boolean} multiline
-- @param[opt] {boolean} noFirstPipe
--]]
local function buildParameterNodes(multiline, noFirstPipe)
	local function buildIndexedParameterDescription(index, description)
		local noPipe = noFirstPipe
		if noFirstPipe then noFirstPipe = false end
		return buildParameterNode{
			index = index,
			multiline = multiline,
			noPipe = noPipe,
			description = description
		}
	end
	local function buildIndexedParameterValue(index, value)
		local noPipe = noFirstPipe
		if noFirstPipe then noFirstPipe = false end
		return buildParameterNode{
			index = index,
			multiline = multiline,
			noPipe = noPipe,
			value = value
		}
	end
	local function buildNamedParameterDescription(index, name, description)
		local noPipe = noFirstPipe
		if noFirstPipe then noFirstPipe = false end
		return buildParameterNode{
			index = index,
			multiline = multiline,
			noPipe = noPipe,
			name = name,
			description = description
		}
	end
	local function buildNamedParameterValue(index, name, value)
		local noPipe = noFirstPipe
		if noFirstPipe then noFirstPipe = false end
		return buildParameterNode{
			index = index,
			multiline = multiline,
			noPipe = noPipe,
			name = name,
			value = value
		}
	end
		
	return mw.html.create()
		:node(buildIndexedParameterValue		("1", ""))
		:node(buildIndexedParameterValue		("2", ""))
		:node(buildIndexedParameterDescription	("3", "..."))
		:node(buildIndexedParameterValue		("4", "value"))
		:node(buildIndexedParameterValue		("5", "value"))
		:node(buildIndexedParameterDescription	("6", "description"))
		:node(buildNamedParameterValue			("7", "name", ""))
		:node(buildNamedParameterValue			("8", "name", ""))
		:node(buildNamedParameterDescription	("9", "name", "..."))
		:node(buildNamedParameterValue			("10", "name", "value"))
		:node(buildNamedParameterValue			("11", "name", "value"))
		:node(buildNamedParameterDescription	("12", "name", "description"))
		:node(buildNamedParameterDescription	("13", "name", "description="))
		:node(buildNamedParameterValue			("14", "name", ""))
		:node(buildNamedParameterValue			("15", "name", ""))
		:node(buildNamedParameterDescription	("16", "name", "..."))
		:node(buildNamedParameterValue			("17", "name", "value"))
		:node(buildNamedParameterValue			("18", "name", "value"))
		:node(buildNamedParameterDescription	("19", "name", "description"))
		:node(buildNamedParameterDescription	("20", "name", "description&#61;"))
end


---------------------------------------------------------------------------------
-- @local
-- @function addSubstPrefix
-- @param html
---------------------------------------------------------------------------------
local function addSubstPrefix(html)
	return html:attr("data-t-subst", "data-t-subst")
		:tag('span')
			:attr('data-t-role', 'subst')
			:wikitext('[[mw:Help:Substitution|subst]]')
			:tag('span')
				:attr('data-t-role', 'substitution-colon')
				:wikitext(mw.text.nowiki(':'))
			:done()
		:done()
end

---------------------------------------------------------------------------------
-- @local
-- @function closeNode
-- @param html
-- @returns mw.html.Node
---------------------------------------------------------------------------------
local function closeNode(html)
	return html:tag("span")
			:attr("data-t-role", "closer")
			:wikitext(mw.text.nowiki("}}"))
		:done()
	:done()
end

-- Transclusion
local TRANSCLUSION_MODE_OUTPUT_NOPARAMS = tostring(
	closeNode(mw.html.create("code")
		:attr("data-t-role", "wrapper")
		:attr("data-t-mode", "transclusion")
		:css("all", "unset")
		:css("font-family", "monospace")
		:tag("span")
			:attr("data-t-role", "opener")
			:wikitext(mw.text.nowiki("{{"))
			:wikitext("[[Template:title|title]]")
		:done()
	)
)
local TRANSCLUSION_MODE_OUTPUT = tostring(
	closeNode(mw.html.create("code")
		:attr("data-t-role", "wrapper")
		:attr("data-t-mode", "transclusion")
		:css("all", "unset")
		:css("font-family", "monospace")
		:tag("span")
			:attr("data-t-role", "opener")
			:wikitext(mw.text.nowiki("{{"))
			:wikitext("[[Template:title|title]]")
		:done()
		:node(buildParameterNodes(false))
	)
)

local MULTILINE_TRANSCLUSION_MODE_OUTPUT_NOPARAMS = tostring(
	closeNode(mw.html.create("code")
		:attr("data-t-role", "wrapper")
		:attr("data-t-mode", "transclusion")
		:attr("data-t-multiline", "data-t-multiline")
		:css("all", "unset")
		:css("font-family", "monospace")
		:tag("span")
			:attr("data-t-role", "opener")
			:wikitext(mw.text.nowiki("{{"))
			:wikitext("[[Template:title|title]]")
		:done()
	)
)
local MULTILINE_TRANSCLUSION_MODE_OUTPUT = tostring(
	closeNode(mw.html.create("code")
		:attr("data-t-role", "wrapper")
		:attr("data-t-mode", "transclusion")
		:attr("data-t-multiline", "data-t-multiline")
		:css("all", "unset")
		:css("font-family", "monospace")
		:tag("span")
			:attr("data-t-role", "opener")
			:wikitext(mw.text.nowiki("{{"))
			:wikitext("[[Template:title|title]]")
		:done()
		:node(buildParameterNodes(true))
	)
)

-- Invocation
local INVOCATION_MODE_OUTPUT_NOPARAMS = tostring(
	closeNode(mw.html.create("code")
		:attr("data-t-role", "wrapper")
		:attr("data-t-mode", "invocation")
		:css("all", "unset")
		:css("font-family", "monospace")
		:tag("span")
			:attr("data-t-role", "opener")
			:wikitext(mw.text.nowiki("{{"))
			:wikitext("#invoke:[[Module:module|module]]")
			:wikitext(mw.text.nowiki("|"))
			:wikitext("function")
		:done()
	)
)

local INVOCATION_MODE_OUTPUT = tostring(
	closeNode(mw.html.create("code")
		:attr("data-t-role", "wrapper")
		:attr("data-t-mode", "invocation")
		:css("all", "unset")
		:css("font-family", "monospace")
		:tag("span")
			:attr("data-t-role", "opener")
			:wikitext(mw.text.nowiki("{{"))
			:wikitext("#invoke:[[Module:module|module]]")
			:wikitext(mw.text.nowiki("|"))
			:wikitext("function")
		:done()
		:node(buildParameterNodes(false))
	)
)

local MULTILINE_INVOCATION_MODE_OUTPUT_NOPARAMS = tostring(
	closeNode(mw.html.create("code")
		:attr("data-t-role", "wrapper")
		:attr("data-t-mode", "invocation")
		:attr("data-t-multiline", "data-t-multiline")
		:css("all", "unset")
		:css("font-family", "monospace")
		:tag("span")
			:attr("data-t-role", "opener")
			:wikitext(mw.text.nowiki("{{"))
			:wikitext("#invoke:[[Module:module|module]]")
			:wikitext(mw.text.nowiki("|"))
			:wikitext("function")
		:done()
	)
)

local MULTILINE_INVOCATION_MODE_OUTPUT = tostring(
	closeNode(mw.html.create("code")
		:attr("data-t-role", "wrapper")
		:attr("data-t-mode", "invocation")
		:attr("data-t-multiline", "data-t-multiline")
		:css("all", "unset")
		:css("font-family", "monospace")
		:tag("span")
			:attr("data-t-role", "opener")
			:wikitext(mw.text.nowiki("{{"))
			:wikitext("#invoke:[[Module:module|module]]")
			:wikitext(mw.text.nowiki("|"))
			:wikitext("function")
		:done()
		:node(buildParameterNodes(true))
	)
)

-- Parser Function
local PARSER_MODE_OUTPUT_NOPARAMS = tostring(
	closeNode(mw.html.create("code")
		:attr("data-t-role", "wrapper")
		:attr("data-t-mode", "parser")
		:css("all", "unset")
		:css("font-family", "monospace")
		:tag("span")
			:attr("data-t-role", "opener")
			:wikitext(mw.text.nowiki("{{"))
			:wikitext("[[mw:Help:Extension:ParserFunctions##time|#time]]")
			:wikitext(mw.text.nowiki(":"))
		:done()
	)
)

local PARSER_MODE_OUTPUT_SUBST_NOPARAMS = tostring(
	closeNode(addSubstPrefix(mw.html.create("code")
		:attr("data-t-role", "wrapper")
		:attr("data-t-mode", "parser")
		:css("all", "unset")
		:css("font-family", "monospace")
		:tag("span")
			:attr("data-t-role", "opener")
			:wikitext(mw.text.nowiki("{{")))
			:wikitext("[[mw:Help:Extension:ParserFunctions##time|#time]]")
			:wikitext(mw.text.nowiki(":"))
		:done()
	)
)

local PARSER_MODE_OUTPUT = tostring(
	closeNode(mw.html.create("code")
		:attr("data-t-role", "wrapper")
		:attr("data-t-mode", "parser")
		:css("all", "unset")
		:css("font-family", "monospace")
		:tag("span")
			:attr("data-t-role", "opener")
			:wikitext(mw.text.nowiki("{{"))
			:wikitext("[[mw:Help:Extension:ParserFunctions##time|#time]]")
			:wikitext(mw.text.nowiki(":"))
		:done()
		:node(buildParameterNodes(false, true))
	)
)

local PARSER_MODE_OUTPUT_SUBST = tostring(
	closeNode(addSubstPrefix(mw.html.create("code")
		:attr("data-t-role", "wrapper")
		:attr("data-t-mode", "parser")
		:css("all", "unset")
		:css("font-family", "monospace")
		:tag("span")
			:attr("data-t-role", "opener")
			:wikitext(mw.text.nowiki("{{")))
			:wikitext("[[mw:Help:Extension:ParserFunctions##time|#time]]")
			:wikitext(mw.text.nowiki(":"))
		:done()
		:node(buildParameterNodes(false, true))
	)
)

local MULTILINE_PARSER_MODE_OUTPUT_NOPARAMS = tostring(
	closeNode(mw.html.create("code")
		:attr("data-t-role", "wrapper")
		:attr("data-t-mode", "parser")
		:attr("data-t-multiline", "data-t-multiline")
		:css("all", "unset")
		:css("font-family", "monospace")
		:tag("span")
			:attr("data-t-role", "opener")
			:wikitext(mw.text.nowiki("{{"))
			:wikitext("[[mw:Help:Extension:ParserFunctions##time|#time]]")
			:wikitext(mw.text.nowiki(":"))
		:done()
	)
)

local MULTILINE_PARSER_MODE_OUTPUT_NOPARAMS_SUBST = tostring(
	closeNode(mw.html.create("code")
		:attr("data-t-role", "wrapper")
		:attr("data-t-mode", "parser")
		:attr("data-t-multiline", "data-t-multiline")
		:css("all", "unset")
		:css("font-family", "monospace")
		:tag("span")
			:attr("data-t-role", "opener")
			:wikitext(mw.text.nowiki("{{"))
			:wikitext("[[mw:Help:Extension:ParserFunctions##time|#time]]")
			:wikitext(mw.text.nowiki(":"))
		:done()
	)
)
local MULTILINE_PARSER_MODE_OUTPUT = tostring(
	closeNode(mw.html.create("code")
		:attr("data-t-role", "wrapper")
		:attr("data-t-mode", "parser")
		:attr("data-t-multiline", "data-t-multiline")
		:css("all", "unset")
		:css("font-family", "monospace")
		:tag("span")
			:attr("data-t-role", "opener")
			:wikitext(mw.text.nowiki("{{"))
			:wikitext("[[mw:Help:Extension:ParserFunctions##time|#time]]")
			:wikitext(mw.text.nowiki(":"))
		:done()
		:node(buildParameterNodes(true, true))
	)
)

--------------------------------------------------------------------------------
-- TEST CASES
--------------------------------------------------------------------------------
return {
	transclusion = {
		options = {
			mode = 'method',
			unpk = true,
			nowiki = false
		},
		tests = {
			{
				{},
				'no title specified',
				{err = true}
			},
			{
				{'title'},
				TRANSCLUSION_MODE_OUTPUT_NOPARAMS,
			},
			{
				{'title', PARAMETERS},
				TRANSCLUSION_MODE_OUTPUT
			},
			{
				{nil, nil, {multiline = true}},
				'no title specified',
				{err = true}
			},
			{
				{'title', nil, {multiline = true}},
				MULTILINE_TRANSCLUSION_MODE_OUTPUT_NOPARAMS,
			},
			{
				{'title', PARAMETERS, {multiline = true}},
				MULTILINE_TRANSCLUSION_MODE_OUTPUT
			}
		}
	},
	invocation = {
		options = {
			mode = 'method',
			unpk = true,
			nowiki = false
		},
		tests = {
			{
				{},
				'no module specified',
				{err = true}
			},
			{
				{'module'},
				'no function specified',
				{err = true}
			},
			{
				{'module', 'function'},
				INVOCATION_MODE_OUTPUT_NOPARAMS,
			},
			{
				{'module', 'function', PARAMETERS},
				INVOCATION_MODE_OUTPUT
			},
			{
				{nil, nil, nil, {multiline = true}},
				'no module specified',
				{err = true}
			},
			{
				{'module', nil, nil, {multiline = true}},
				'no function specified',
				{err = true}
			},
			{
				{'module', 'function', nil, {multiline = true}},
				MULTILINE_INVOCATION_MODE_OUTPUT_NOPARAMS,
			},
			{
				{'module', 'function', PARAMETERS, {multiline = true}},
				MULTILINE_INVOCATION_MODE_OUTPUT
			}
		}
	},
	
	parser = {
		options = {
			mode = 'method',
			unpk = true,
			nowiki = false
		},
		tests = {
			{
				{},
				'no parser function specified',
				{err = true}
			},
			{
				{'time'},
				PARSER_MODE_OUTPUT_NOPARAMS,
			},
			{
				{'time', nil, {subst=true}},
				PARSER_MODE_OUTPUT_SUBST_NOPARAMS,
			},
			{
				{'time', PARAMETERS},
				PARSER_MODE_OUTPUT
			},
			{
				{nil, nil, {multiline = true}},
				'no parser function specified',
				{err = true}
			},
			{
				{'time', nil, {multiline = true}},
				MULTILINE_PARSER_MODE_OUTPUT_NOPARAMS,
			},
			{
				{'time', PARAMETERS, {multiline = true}},
				MULTILINE_PARSER_MODE_OUTPUT
			}
		}
	},

	main = {
		options = {
			mode = 'invocation',
			preprocess = true,
			nowiki = false
		},
		tests = {
			--------------------------------------------------------------------
			-- TRANSCLUSION MODE
			--------------------------------------------------------------------
			{
				'',
				'<strong class="error">Error: no title specified.</strong>'
			},
			{
				'title',
				TRANSCLUSION_MODE_OUTPUT_NOPARAMS,
			},
			{
				table.concat({'title', PARAMETERS2}, '|'),
				TRANSCLUSION_MODE_OUTPUT
			},
			--------------------------------------------------------------------
			-- MULTILINE TRANSCLUSION MODE (FULL FLAG NAMES)
			--------------------------------------------------------------------
			{
				'multiline=true',
				'<strong class="error">Error: no title specified.</strong>'
			},
			{
				'multiline=true|title',
				MULTILINE_TRANSCLUSION_MODE_OUTPUT_NOPARAMS,
			},
			{
				table.concat({'multiline=true', 'title', PARAMETERS2}, '|'),
				MULTILINE_TRANSCLUSION_MODE_OUTPUT
			},
			--------------------------------------------------------------------
			-- MULTILINE TRANSCLUSION MODE (TRUNCATED FLAG NAMES)
			--------------------------------------------------------------------
			{
				'm=true',
				'<strong class="error">Error: no title specified.</strong>'
			},
			{
				'm=true|title',
				MULTILINE_TRANSCLUSION_MODE_OUTPUT_NOPARAMS,
			},
			{
				table.concat({'m=true', 'title', PARAMETERS2}, '|'),
				MULTILINE_TRANSCLUSION_MODE_OUTPUT
			},
			--------------------------------------------------------------------
			-- INVOCATION MODE (FULL FLAG NAMES)
			--------------------------------------------------------------------
			{
				'invocation=true',
				'<strong class="error">Error: no module specified.</strong>'
			},
			{
				'invocation=true|module',
				'<strong class="error">Error: no function specified.</strong>'
			},
			{
				'invocation=true|module|function',
				INVOCATION_MODE_OUTPUT_NOPARAMS,
			},
			{
				table.concat({'invocation=true', 'module', 'function', PARAMETERS2}, '|'),
				INVOCATION_MODE_OUTPUT
			},
			--------------------------------------------------------------------
			-- INVOCATION MODE (TRUNCATED FLAG NAMES)
			--------------------------------------------------------------------
			{
				'i=true',
				'<strong class="error">Error: no module specified.</strong>'
			},
			{
				'i=true|module',
				'<strong class="error">Error: no function specified.</strong>'
			},
			{
				'i=true|module|function',
				INVOCATION_MODE_OUTPUT_NOPARAMS,
			},
			{
				table.concat({'i=true', 'module', 'function', PARAMETERS2}, '|'),
				INVOCATION_MODE_OUTPUT
			},
			--------------------------------------------------------------------
			-- MULTILINE INVOCATION MODE (FULL FLAG NAMES)
			--------------------------------------------------------------------
			{
				'invocation=true|multiline=true',
				'<strong class="error">Error: no module specified.</strong>'
			},
			{
				'invocation=true|multiline=true|module',
				'<strong class="error">Error: no function specified.</strong>'
			},
			{
				'invocation=true|multiline=true|module|function',
				MULTILINE_INVOCATION_MODE_OUTPUT_NOPARAMS,
			},
			{
				table.concat({'invocation=true', 'multiline=true', 'module', 'function', PARAMETERS2}, '|'),
				MULTILINE_INVOCATION_MODE_OUTPUT
			},
			--------------------------------------------------------------------
			-- MULTILINE INVOCATION MODE (TRUNCATED FLAG NAMES)
			--------------------------------------------------------------------
			{
				'i=true|m=true',
				'<strong class="error">Error: no module specified.</strong>'
			},
			{
				'i=true|m=true|module',
				'<strong class="error">Error: no function specified.</strong>'
			},
			{
				'i=true|m=true|module|function',
				MULTILINE_INVOCATION_MODE_OUTPUT_NOPARAMS,
			},
			{
				table.concat({'i=true', 'm=true', 'module', 'function', PARAMETERS2}, '|'),
				MULTILINE_INVOCATION_MODE_OUTPUT
			},
			--------------------------------------------------------------------
			-- PARSER MODE
			--------------------------------------------------------------------
			{
				'parser=true',
				'<strong class="error">Error: no parser function specified.</strong>'
			},
			{
				'time|parser=true',
				PARSER_MODE_OUTPUT_NOPARAMS,
			},
			{
				table.concat({'parser=true', 'time', PARAMETERS2}, '|'),
				PARSER_MODE_OUTPUT
			},
			
			--------------------------------------------------------------------
			-- PARSER MODE
			--------------------------------------------------------------------
			{
				'parser=true',
				'<strong class="error">Error: no parser function specified.</strong>'
			},
			{
				'time|parser=true',
				PARSER_MODE_OUTPUT_NOPARAMS,
			},
			{
				table.concat({'parser=true', 'time', PARAMETERS2}, '|'),
				PARSER_MODE_OUTPUT
			},
		
			--------------------------------------------------------------------
			-- PARSER MODE (TRUNCATED FLAG NAMES)
			--------------------------------------------------------------------
			{
				'p=true',
				'<strong class="error">Error: no parser function specified.</strong>'
			},
			{
				'time|p=true',
				PARSER_MODE_OUTPUT_NOPARAMS,
			},
			{
				table.concat({'p=true', 'time', PARAMETERS2}, '|'),
				PARSER_MODE_OUTPUT
			},
			--------------------------------------------------------------------
			-- MULTILINE PARSER MODE (FULL FLAG NAMES)
			--------------------------------------------------------------------
			{
				'parser=true|multiline=true',
				'<strong class="error">Error: no parser function specified.</strong>'
			},
			{
				'multiline=true|parser=true|time',
				MULTILINE_PARSER_MODE_OUTPUT_NOPARAMS,
			},
			{
				table.concat({'parser=true|multiline=true', 'time', PARAMETERS2}, '|'),
				MULTILINE_PARSER_MODE_OUTPUT
			},
			--------------------------------------------------------------------
			-- MULTILINE PARSER MODE (TRUNCATED FLAG NAMES)
			--------------------------------------------------------------------
			{
				'm=true|p=true',
				'<strong class="error">Error: no parser function specified.</strong>'
			},
			{
				'm=true|p=true|time',
				MULTILINE_PARSER_MODE_OUTPUT_NOPARAMS,
			},
			{
				table.concat({'m=true|p=true', 'time', PARAMETERS2}, '|'),
				MULTILINE_PARSER_MODE_OUTPUT
			},
		}
	}
}