local getArgs = require('Module:Arguments/sandbox').getArgslocal ScribuntoUnit = require('Module:ScribuntoUnit')local suite = ScribuntoUnit:new
---------------------------------------------------------------------------- Default values--------------------------------------------------------------------------
local d = d.frameTitle = 'Frame title'd.parentTitle = 'Parent title'
-- Precedence-testing valuesd.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 = 101d.untrimmedArg = '\n foo bar 'd.untrimmedArgKey = 102d.trimmedArg = 'foo bar'd.valueFuncValue = 'valueFuncValue'd.defaultValueFunc = function return d.valueFuncValue endd.translate =
---------------------------------------------------------------------------- Helper functions--------------------------------------------------------------------------
function suite.getFrames(frameTitle, frameArgs, parentTitle, parentArgs) frameTitle = frameTitle or d.frameTitle frameArgs = frameArgs or parentTitle = parentTitle or d.parentTitle parentArgs = parentArgs or local currentFrame = mw.getCurrentFrame local parent = currentFrame:newChild local frame = parent:newChild return frame, parentend
function suite.getDefaultArgs(options, frameTitle, frameArgs, parentTitle, parentArgs) local frame, parent = suite.getFrames(frameTitle, frameArgs, parentTitle, parentArgs) local args = getArgs(frame, options) return argsend
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)end
function suite:testDefaultPrecedenceThroughNonWrapper self:assertDefaultPrecedence(suite.getDefaultArgs(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)end
function suite:testParentFirstThroughWrapper self:assertParentFirst(suite.getDefaultArgs)end
function suite:testParentFirstThroughNonWrapper self:assertParentFirst(suite.getDefaultArgs(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)end
function suite:testParentOnlyThroughWrapper self:assertParentOnly(suite.getDefaultArgs)end
function suite:testParentOnlyThroughSandboxWrapper self:assertParentOnly(suite.getDefaultArgs(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)end
function suite:testFrameOnlyThroughNonWrapper self:assertFrameOnly(suite.getDefaultArgs(nil, nil, 'Not the parent title'))end
function suite:testDefaultPrecedenceWithWhitespace local frame, parent = suite.getFrames(d.frameTitle, , d.parentTitle, ) 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 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 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 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 self:assertEquals(d.valueFuncValue, args['some random key: sdfaliwyda'])end
function suite:testValueFuncPrecedence local args = suite.getDefaultArgs self:assertEquals(d.valueFuncValue, args[1]) self:assertEquals(d.valueFuncValue, args['some random key: gekjabawyvy'])end
function suite:testValueFuncKey local args = suite.getDefaultArgs self:assertEquals('valueFunc key: foo', args.foo)end
function suite:testValueFuncValue local args = suite.getDefaultArgs 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 local function testFunc args.newKey = 'some new value' end self:assertError(testFunc)end
function suite:testNoOverwriteExistingKey local args = suite.getDefaultArgs 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 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,,) self:assertError(getArgs,,) self:assertError(getArgs,,) self:assertError(getArgs,,)end
---------------------------------------------------------------------------- Test iterator metamethods--------------------------------------------------------------------------
function suite:testPairs local args = getArgs self:assertNumberOfIterations(3, pairs, args)end
function suite:testIpairs local args = getArgs 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 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 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 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, ) 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, ) 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
2 then return 'bar' elseif k
'bar' then break end endend
---------------------------------------------------------------------------- Test argument translation--------------------------------------------------------------------------
function suite:testTranslationIndex local args = getArgs 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 local cleanArgs = for k,v in pairs(args) do cleanArgs[k] = v end self:assertDeepEquals(cleanArgs )end
function suite:testTranslationPairsWithBacktranslate local args = getArgs local cleanArgs = for k,v in pairs(args) do cleanArgs[k] = v end self:assertDeepEquals(cleanArgs )end
function suite:testTranslationPairsWithoutBacktranslate local args = getArgs local cleanArgs = for k,v in pairs(args) do cleanArgs[k] = v end self:assertDeepEquals(cleanArgs )end
function suite:testTranslationNewindex local args = getArgs args.foo = 'changed1' args.untranslated = 'changed2' local cleanArgs = for k,v in pairs(args) do cleanArgs[k] = v end self:assertDeepEquals(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