Modul:Arguments/testcases
local getArgs = require('Module:Arguments/sandkasse').getArgs
local ScribuntoUnit = require('Module:ScribuntoUnit')
local suite = ScribuntoUnit:new()
--------------------------------------------------------------------------
-- Default values
--------------------------------------------------------------------------
local d = {}
d.frameTitle = 'Frame title'
d.parentTitle = 'Parent title'
-- Precedence-testing values
d.firstFrameArg = 'first frame argument'
d.firstParentArg = 'first parent argument'
d.secondParentArg = 'second parent argument'
d.uniqueFrameArg = 'unique frame argument'
d.uniqueFrameArgKey = 'uniqueFrameArgKey'
d.uniqueParentArg = 'unique parent argument'
d.uniqueParentArgKey = 'uniqueParentArgKey'
-- Trimming and whitespace values.
-- Whitespace gets trimmed from named parameters, so keys for these need
-- to be numbers to make this a proper test.
d.blankArg = ''
d.blankArgKey = 100
d.spacesArg = '\n '
d.spacesArgKey = 101
d.untrimmedArg = '\n foo bar '
d.untrimmedArgKey = 102
d.trimmedArg = 'foo bar'
d.valueFuncValue = 'valueFuncValue'
d.defaultValueFunc = function() return d.valueFuncValue end
--------------------------------------------------------------------------
-- Helper functions
--------------------------------------------------------------------------
function suite.getFrames(frameTitle, frameArgs, parentTitle, parentArgs)
frameTitle = frameTitle or d.frameTitle
frameArgs = frameArgs or {
d.firstFrameArg,
[d.uniqueFrameArgKey] = d.uniqueFrameArg,
[d.blankArgKey] = d.blankArg,
[d.spacesArgKey] = d.spacesArg,
[d.untrimmedArgKey] = d.untrimmedArg
}
parentTitle = parentTitle or d.parentTitle
parentArgs = parentArgs or {
d.firstParentArg,
d.secondParentArg,
[d.uniqueParentArgKey] = d.uniqueParentArg
}
local currentFrame = mw.getCurrentFrame()
local parent = currentFrame:newChild{title = parentTitle, args = parentArgs}
local frame = parent:newChild{title = frameTitle, args = frameArgs}
return frame, parent
end
function suite.getDefaultArgs(options, frameTitle, frameArgs, parentTitle, parentArgs)
local frame, parent = suite.getFrames(frameTitle, frameArgs, parentTitle, parentArgs)
local args = getArgs(frame, options)
return args
end
function suite:assertError(func, ...)
-- Asserts that executing the function func results in an error.
-- Parameters after func are func's arguments.
local success, msg = pcall(func, ...)
self:assertFalse(success)
end
function suite:assertNumberOfIterations(expected, iterator, t)
local noIterations = 0
for k, v in iterator(t) do
noIterations = noIterations + 1
end
self:assertEquals(expected, noIterations)
end
--------------------------------------------------------------------------
-- Test precedence
--------------------------------------------------------------------------
function suite:assertDefaultPrecedence(args)
self:assertEquals(d.firstFrameArg, args[1])
self:assertEquals(d.secondParentArg, args[2])
self:assertEquals(d.uniqueFrameArg, args[d.uniqueFrameArgKey])
self:assertEquals(d.uniqueParentArg, args[d.uniqueParentArgKey])
end
function suite:testDefaultPrecedence()
self:assertDefaultPrecedence(suite.getDefaultArgs())
end
function suite:testDefaultPrecedenceThroughWrapper()
self:assertDefaultPrecedence(suite.getDefaultArgs{wrappers = {d.parentTitle}, parentOnly = false})
end
function suite:testDefaultPrecedenceThroughNonWrapper()
self:assertDefaultPrecedence(suite.getDefaultArgs({wrappers = d.parentTitle, frameOnly = false}, nil, nil, 'Not the parent title'))
end
function suite:assertParentFirst(args)
self:assertEquals(d.firstParentArg, args[1])
self:assertEquals(d.secondParentArg, args[2])
self:assertEquals(d.uniqueFrameArg, args[d.uniqueFrameArgKey])
self:assertEquals(d.uniqueParentArg, args[d.uniqueParentArgKey])
end
function suite:testParentFirst()
self:assertParentFirst(suite.getDefaultArgs{parentFirst = true})
end
function suite:testParentFirstThroughWrapper()
self:assertParentFirst(suite.getDefaultArgs{wrappers = {d.parentTitle}, parentOnly = false, parentFirst = true})
end
function suite:testParentFirstThroughNonWrapper()
self:assertParentFirst(suite.getDefaultArgs({wrappers = d.parentTitle, frameOnly = false, parentFirst = true}, nil, nil, 'Not the parent title'))
end
function suite:assertParentOnly(args)
self:assertEquals(d.firstParentArg, args[1])
self:assertEquals(d.secondParentArg, args[2])
self:assertEquals(nil, args[d.uniqueFrameArgKey])
self:assertEquals(d.uniqueParentArg, args[d.uniqueParentArgKey])
end
function suite:testParentOnly()
self:assertParentOnly(suite.getDefaultArgs{parentOnly = true})
end
function suite:testParentOnlyThroughWrapper()
self:assertParentOnly(suite.getDefaultArgs{wrappers = {d.parentTitle}})
end
function suite:testParentOnlyThroughSandboxWrapper()
self:assertParentOnly(suite.getDefaultArgs({wrappers = d.parentTitle}, nil, nil, d.parentTitle .. '/sandbox'))
end
function suite:assertFrameOnly(args)
self:assertEquals(d.firstFrameArg, args[1])
self:assertEquals(nil, args[2])
self:assertEquals(d.uniqueFrameArg, args[d.uniqueFrameArgKey])
self:assertEquals(nil, args[d.uniqueParentArgKey])
end
function suite:testFrameOnly()
self:assertFrameOnly(suite.getDefaultArgs{frameOnly = true})
end
function suite:testFrameOnlyThroughNonWrapper()
self:assertFrameOnly(suite.getDefaultArgs({wrappers = d.parentTitle}, nil, nil, 'Not the parent title'))
end
function suite:testDefaultPrecedenceWithWhitespace()
local frame, parent = suite.getFrames(
d.frameTitle,
{' '},
d.parentTitle,
{d.firstParentArg}
)
local args = getArgs(frame)
self:assertEquals(d.firstParentArg, args[1])
end
--------------------------------------------------------------------------
-- Test trimming and blank removal
--------------------------------------------------------------------------
function suite:testDefaultTrimmingAndBlankRemoval()
local args = suite.getDefaultArgs()
self:assertEquals(nil, args[d.blankArgKey])
self:assertEquals(nil, args[d.spacesArgKey])
self:assertEquals(d.trimmedArg, args[d.untrimmedArgKey])
end
function suite:testRemoveBlanksButNoTrimming()
local args = suite.getDefaultArgs{trim = false}
self:assertEquals(nil, args[d.blankArgKey])
self:assertEquals(nil, args[d.spacesArgKey])
self:assertEquals(d.untrimmedArg, args[d.untrimmedArgKey])
end
function suite:testTrimButNoBlankRemoval()
local args = suite.getDefaultArgs{removeBlanks = false}
self:assertEquals(d.blankArg, args[d.blankArgKey])
self:assertEquals('', args[d.spacesArgKey])
self:assertEquals(d.trimmedArg, args[d.untrimmedArgKey])
end
function suite:testNoTrimOrBlankRemoval()
local args = suite.getDefaultArgs{trim = false, removeBlanks = false}
self:assertEquals(d.blankArg, args[d.blankArgKey])
self:assertEquals(d.spacesArg, args[d.spacesArgKey])
self:assertEquals(d.untrimmedArg, args[d.untrimmedArgKey])
end
--------------------------------------------------------------------------
-- Test valueFunc
--------------------------------------------------------------------------
function suite:testValueFunc()
local args = suite.getDefaultArgs{valueFunc = d.defaultValueFunc}
self:assertEquals(d.valueFuncValue, args['some random key: sdfaliwyda'])
end
function suite:testValueFuncPrecedence()
local args = suite.getDefaultArgs{
trim = false,
removeBlanks = false,
valueFunc = d.defaultValueFunc
}
self:assertEquals(d.valueFuncValue, args[1])
self:assertEquals(d.valueFuncValue, args['some random key: gekjabawyvy'])
end
function suite:testValueFuncKey()
local args = suite.getDefaultArgs{valueFunc = function(key, value)
return 'valueFunc key: '.. key
end}
self:assertEquals('valueFunc key: foo', args.foo)
end
function suite:testValueFuncValue()
local args = suite.getDefaultArgs{valueFunc = function(key, value)
return 'valueFunc value: '.. value
end}
self:assertEquals(
'valueFunc value: ' .. d.uniqueFrameArg,
args[d.uniqueFrameArgKey]
)
end
--------------------------------------------------------------------------
-- Test adding new arguments
--------------------------------------------------------------------------
function suite:testAddingNewArgs()
local args = suite.getDefaultArgs()
self:assertEquals(nil, args.newKey)
args.newKey = 'some new key'
self:assertEquals('some new key', args.newKey)
end
function suite:testAddingNewBlankArgs()
local args = suite.getDefaultArgs()
self:assertEquals(nil, args.newKey)
args.newKey = ''
self:assertEquals('', args.newKey)
end
function suite:testAddingNewSpacesArgs()
local args = suite.getDefaultArgs()
self:assertEquals(nil, args.newKey)
args.newKey = ' '
self:assertEquals(' ', args.newKey)
end
function suite:testOverwriting()
local args = suite.getDefaultArgs()
self:assertEquals(d.firstFrameArg, args[1])
args[1] = 'a new first frame argument'
self:assertEquals('a new first frame argument', args[1])
end
function suite:testOverwritingWithNil()
local args = suite.getDefaultArgs()
self:assertEquals(d.firstFrameArg, args[1])
args[1] = nil
self:assertEquals(nil, args[1])
end
function suite:testOverwritingWithBlank()
local args = suite.getDefaultArgs()
self:assertEquals(d.firstFrameArg, args[1])
args[1] = ''
self:assertEquals('', args[1])
end
function suite:testOverwritingWithSpaces()
local args = suite.getDefaultArgs()
self:assertEquals(d.firstFrameArg, args[1])
args[1] = ' '
self:assertEquals(' ', args[1])
end
function suite:testReadOnly()
local args = suite.getDefaultArgs{readOnly = true}
local function testFunc()
args.newKey = 'some new value'
end
self:assertError(testFunc)
end
function suite:testNoOverwriteExistingKey()
local args = suite.getDefaultArgs{noOverwrite = true}
self:assertEquals(d.firstFrameArg, args[1])
local function testFunc()
args[1] = 'a new first frame argument'
end
self:assertError(testFunc)
end
function suite:testNoOverwriteNewKey()
local args = suite.getDefaultArgs{noOverwrite = true}
self:assertEquals(nil, args.newKey)
args.newKey = 'some new value'
self:assertEquals('some new value', args.newKey)
end
--------------------------------------------------------------------------
-- Test bad input
--------------------------------------------------------------------------
function suite:testBadFrameInput()
self:assertError(getArgs, 'foo')
self:assertError(getArgs, 9)
self:assertError(getArgs, true)
self:assertError(getArgs, function() return true end)
end
function suite:testBadOptionsInput()
self:assertError(getArgs, {}, 'foo')
self:assertError(getArgs, {}, 9)
self:assertError(getArgs, {}, true)
self:assertError(getArgs, {}, function() return true end)
end
function suite:testBadValueFuncInput()
self:assertError(getArgs, {}, {valueFunc = 'foo'})
self:assertError(getArgs, {}, {valueFunc = 9})
self:assertError(getArgs, {}, {valueFunc = true})
self:assertError(getArgs, {}, {valueFunc = {}})
end
--------------------------------------------------------------------------
-- Test iterator metamethods
--------------------------------------------------------------------------
function suite:testPairs()
local args = getArgs{'foo', 'bar', baz = 'qux'}
self:assertNumberOfIterations(3, pairs, args)
end
function suite:testIpairs()
local args = getArgs{'foo', 'bar', baz = 'qux'}
self:assertNumberOfIterations(2, ipairs, args)
end
function suite:testNoNilsinPairs()
-- Test that when we use pairs, we don't iterate over any nil values
-- that have been memoized.
local args = getArgs{''}
local temp = args[1] -- Memoizes the nil
self:assertNumberOfIterations(0, pairs, args)
end
function suite:testNoNilsinIpairs()
-- Test that when we use ipairs, we don't iterate over any nil values
-- that have been memoized.
local args = getArgs{''}
local temp = args[1] -- Memoizes the nil
self:assertNumberOfIterations(0, ipairs, args)
end
function suite:testDeletedArgsInPairs()
-- Test that when we use pairs, we don't iterate over any values that have
-- been explicitly set to nil.
local args = getArgs{'foo'}
args[1] = nil
self:assertNumberOfIterations(0, pairs, args)
end
function suite:testDeletedArgsInIpairs()
-- Test that when we use ipairs, we don't iterate over any values that have
-- been explicitly set to nil.
local args = getArgs{'foo'}
args[1] = nil
self:assertNumberOfIterations(0, ipairs, args)
end
function suite:testNoNilsInPairsAfterIndex()
-- Test that when we use pairs, we don't iterate over any nils that
-- might have been memoized after a value that is not present in the
-- original args table is indexed.
local args = getArgs{}
local temp = args.someRandomValue -- Memoizes the nil
self:assertNumberOfIterations(0, pairs, args)
end
function suite:testNoNilsInPairsAfterNewindex()
-- Test that when we use pairs, we don't iterate over any nils that
-- might have been memoized after a value that is not present in the
-- original args table is added to the args table.
local args = getArgs{}
args.newKey = nil -- The nil is memoized
self:assertNumberOfIterations(0, pairs, args)
end
function suite:testNoTableLengthChangeWhileIterating()
-- Test that the number of arguments doesn't change if we index the
-- args table while iterating.
-- (Note that the equivalent test is not needed for new arg table
-- indexes, as that would be a user error - doing so produces
-- undetermined behaviour in Lua's next() function.)
local args = getArgs{'foo', 'bar', baz = 'qux'}
self:assertNumberOfIterations(3, pairs, args)
for k, v in pairs(args) do
local temp = args[k .. 'foo']
end
self:assertNumberOfIterations(3, pairs, args)
end
function suite:testPairsPrecedenceWithWhitespace()
local frame, parent = suite.getFrames(
d.frameTitle,
{' '},
d.parentTitle,
{d.firstParentArg}
)
local args = getArgs(frame)
local actual
for k, v in pairs(args) do
actual = v
end
self:assertEquals(d.firstParentArg, actual)
-- Check that we have actually iterated.
self:assertNumberOfIterations(1, pairs, args)
end
function suite:testPairsPrecedenceWithNil()
local frame, parent = suite.getFrames(
d.frameTitle,
{},
d.parentTitle,
{d.firstParentArg}
)
local args = getArgs(frame)
local actual
for k, v in pairs(args) do
actual = v
end
self:assertEquals(d.firstParentArg, actual)
-- Check that we have actually iterated.
self:assertNumberOfIterations(1, pairs, args)
end
function suite:testIpairsEarlyExit()
local mt = {}
function mt.__index(t, k)
if k == 1 then
return 'foo'
elseif k == 2 then
return 'bar'
elseif k == 3 then
error('Expanded argument 3 unnecessarily')
end
end
function mt.__pairs(t)
error('Called pairs unnecessarily')
end
function mt.__ipairs(t)
-- Works just like the default ipairs, except respecting __index
return function(t, i)
local v = t[i + 1]
if v ~= nil then
return i + 1, v
end
end, t, 0
end
local args = getArgs(setmetatable({}, mt))
for k,v in ipairs(args) do
if v == 'bar' then
break
end
end
end
return suite
Content Disclaimer
Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.
- The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
- There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
- It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
- Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
- Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.
Index:
pl ar de en es fr it arz nl ja pt ceb sv uk vi war zh ru af ast az bg zh-min-nan bn be ca cs cy da et el eo eu fa gl ko hi hr id he ka la lv lt hu mk ms min no nn ce uz kk ro simple sk sl sr sh fi ta tt th tg azb tr ur zh-yue hy my ace als am an hyw ban bjn map-bms ba be-tarask bcl bpy bar bs br cv nv eml hif fo fy ga gd gu hak ha hsb io ig ilo ia ie os is jv kn ht ku ckb ky mrj lb lij li lmo mai mg ml zh-classical mr xmf mzn cdo mn nap new ne frr oc mhr or as pa pnb ps pms nds crh qu sa sah sco sq scn si sd szl su sw tl shn te bug vec vo wa wuu yi yo diq bat-smg zu lad kbd ang smn ab roa-rup frp arc gn av ay bh bi bo bxr cbk-zam co za dag ary se pdc dv dsb myv ext fur gv gag inh ki glk gan guw xal haw rw kbp pam csb kw km kv koi kg gom ks gcr lo lbe ltg lez nia ln jbo lg mt mi tw mwl mdf mnw nqo fj nah na nds-nl nrm nov om pi pag pap pfl pcd krc kaa ksh rm rue sm sat sc trv stq nso sn cu so srn kab roa-tara tet tpi to chr tum tk tyv udm ug vep fiu-vro vls wo xh zea ty ak bm ch ny ee ff got iu ik kl mad cr pih ami pwn pnt dz rmy rn sg st tn ss ti din chy ts kcg ve









