Module:Arguments/testcases
| This is the test cases page for the module Module:Arguments. Results of the test cases. |
local getArgs = require('Module:Arguments/sandbox').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
d.translate = {
foo = 'F00',
bar = '8@r',
baz = '8@z',
qux = 'qUx'
}
--------------------------------------------------------------------------
-- 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:assertNumberOfIterations(expected, iterator, t)
local noIterations = 0
for k, v in iterator(t) do
noIterations = noIterations + 1
end
self:assertEquals(expected, noIterations, "Unexpected number of iterations occurred;", 1)
end
--------------------------------------------------------------------------
-- Test precedence
--------------------------------------------------------------------------
function suite:assertDefaultPrecedence(args)
self:assertEquals(d.firstFrameArg, args[1], nil, 1)
self:assertEquals(d.secondParentArg, args[2], nil, 1)
self:assertEquals(d.uniqueFrameArg, args[d.uniqueFrameArgKey], nil, 1)
self:assertEquals(d.uniqueParentArg, args[d.uniqueParentArgKey], nil, 1)
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], nil, 1)
self:assertEquals(d.secondParentArg, args[2])
self:assertEquals(d.uniqueFrameArg, args[d.uniqueFrameArgKey], nil, 1)
self:assertEquals(d.uniqueParentArg, args[d.uniqueParentArgKey], nil, 1)
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], nil, 1)
self:assertEquals(d.secondParentArg, args[2], nil, 1)
self:assertEquals(nil, args[d.uniqueFrameArgKey], nil, 1)
self:assertEquals(d.uniqueParentArg, args[d.uniqueParentArgKey], nil, 1)
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], nil, 1)
self:assertEquals(nil, args[2], nil, 1)
self:assertEquals(d.uniqueFrameArg, args[d.uniqueFrameArgKey], nil, 1)
self:assertEquals(nil, args[d.uniqueParentArgKey], nil, 1)
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:assertThrows(testFunc, 'could not write to argument table key "newKey"; the table is read-only')
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:assertThrows(testFunc, 'could not write to argument table key "1"; overwriting existing arguments is not permitted')
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:assertThrows(getArgs, "bad argument #1 to 'getArgs' (table expected, got string)", nil, 'foo')
self:assertThrows(getArgs, "bad argument #1 to 'getArgs' (table expected, got number)", nil, 9)
self:assertThrows(getArgs, "bad argument #1 to 'getArgs' (table expected, got boolean)", nil, true)
self:assertThrows(getArgs, "bad argument #1 to 'getArgs' (table expected, got function)", nil, function() return true end)
end
function suite:testBadOptionsInput()
self:assertThrows(getArgs, "bad argument #2 to 'getArgs' (table expected, got string)", nil, {}, 'foo')
self:assertThrows(getArgs, "bad argument #2 to 'getArgs' (table expected, got number)", nil, {}, 9)
self:assertThrows(getArgs, "bad argument #2 to 'getArgs' (table expected, got boolean)", nil, {}, true)
self:assertThrows(getArgs, "bad argument #2 to 'getArgs' (table expected, got function)", nil, {}, function() return true end)
end
function suite:testBadValueFuncInput()
self:assertThrows(getArgs, "bad value assigned to option 'valueFunc'(function expected, got string)", nil, {}, {valueFunc = 'foo'})
self:assertThrows(getArgs, "bad value assigned to option 'valueFunc'(function expected, got number)", nil, {}, {valueFunc = 9})
self:assertThrows(getArgs, "bad value assigned to option 'valueFunc'(function expected, got boolean)", nil, {}, {valueFunc = true})
self:assertThrows(getArgs, "bad value assigned to option 'valueFunc'(function expected, got table)", nil, {}, {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
--------------------------------------------------------------------------
-- Test argument translation
--------------------------------------------------------------------------
function suite:testTranslationIndex()
local args = getArgs({F00 = 'one', ['8@r'] = 'two', ['8@z'] = 'three', qUx = 'four', foo = 'nope', untranslated = 'yep'}, {translate = d.translate})
self:assertEquals('one', args.foo)
self:assertEquals('two', args.bar)
self:assertEquals('three', args.baz)
self:assertEquals('four', args.qux)
self:assertEquals('yep', args.untranslated)
end
function suite:testTranslationPairsWithAutoBacktranslate()
local args = getArgs({F00 = 'one', ['8@r'] = 'two', ['8@z'] = 'three', qUx = 'four', foo = 'nope', untranslated = 'yep'}, {translate = d.translate})
local cleanArgs = {}
for k,v in pairs(args) do
cleanArgs[k] = v
end
self:assertDeepEquals(
{
foo = 'one',
bar = 'two',
baz = 'three',
qux = 'four',
untranslated = 'yep'
},
cleanArgs
)
end
function suite:testTranslationPairsWithBacktranslate()
local args = getArgs({F00 = 'one', ['8@r'] = 'two', ['8@z'] = 'three', qUx = 'four', foo = 'nope', untranslated = 'yep'}, {translate = d.translate, backtranslate = {F00 = 'foo'}})
local cleanArgs = {}
for k,v in pairs(args) do
cleanArgs[k] = v
end
self:assertDeepEquals(
{
foo = 'one',
['8@r'] = 'two',
['8@z'] = 'three',
qUx = 'four',
untranslated = 'yep'
},
cleanArgs
)
end
function suite:testTranslationPairsWithoutBacktranslate()
local args = getArgs({F00 = 'one', ['8@r'] = 'two', ['8@z'] = 'three', qUx = 'four', foo = 'nope', untranslated = 'yep'}, {translate = d.translate, backtranslate = false})
local cleanArgs = {}
for k,v in pairs(args) do
cleanArgs[k] = v
end
self:assertDeepEquals(
{
F00 = 'one',
['8@r'] = 'two',
['8@z'] = 'three',
qUx = 'four',
foo = 'nope',
untranslated = 'yep'
},
cleanArgs
)
end
function suite:testTranslationNewindex()
local args = getArgs({F00 = 'one', ['8@r'] = 'two', ['8@z'] = 'three', qUx = 'four', foo = 'nope', untranslated = 'yep'}, {translate = d.translate, backtranslate = false})
args.foo = 'changed1'
args.untranslated = 'changed2'
local cleanArgs = {}
for k,v in pairs(args) do
cleanArgs[k] = v
end
self:assertDeepEquals(
{
F00 = 'changed1',
['8@r'] = 'two',
['8@z'] = 'three',
qUx = 'four',
foo = 'nope',
untranslated = 'changed2'
},
cleanArgs
)
end
function suite:test_argument()
local currentFrame = mw.getCurrentFrame()
currentFrame.args[5] = 555;
local args = getArgs(currentFrame)
self:assertEquals('nil', type(args.foo))
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.