local mMockTitle = require('Module:Mock title/sandbox')local ScribuntoUnit = require('Module:ScribuntoUnit')
local suite = ScribuntoUnit:new
---------------------------------------------------------------------------------- Custom assertion methods--------------------------------------------------------------------------------
function suite:assertTitlesAreEqual(expected, actual) local properties = for _, prop in ipairs(properties) do self:assertEquals(expected[prop], actual[prop], string.format('mismatch in property "%s"', prop) ) end local deepProperties = for _, prop in ipairs(deepProperties) do self:assertDeepEquals(expected[prop], actual[prop], string.format('mismatch in property "%s"', prop) ) end self:assertEquals(not not expected.file, not not actual.file, string.format('expected %s file property; actual %s file property', expected.file and 'has' or 'has no', actual.file and 'has' or 'has no' ) ) if expected.file and actual.file then local fileProperties = for _, prop in ipairs(fileProperties) do self:assertEquals(expected.file[prop], actual.file[prop], string.format('mismatch in property "file.%s"', prop) ) end self:assertDeepEquals(expected.file.pages, actual.file.pages, string.format('mismatch in property "%s"', prop) ) end self:assertEquals(expected:getContent, actual:getContent, 'mismatch in getContent' )end
function suite:assertTitlesAreNotEqual(expected, actual) local success, result = pcall(self.assertTitlesAreEqual, self, expected, actual) if success then self:fail(string.format('Failed to assert that the specified titles are not equal (title: %s)', tostring(expected) )) endend
---------------------------------------------------------------------------------- MockTitle tests--------------------------------------------------------------------------------
suite['test MockTitle: when no argument table is supplied, an error is raised'] = function (self) self:assertThrows(function mMockTitle.MockTitle end, "bad argument #1 to 'MockTitle' (table expected, got nil)" )end
suite['test MockTitle: when no title argument is supplied, an error is raised'] = function (self) self:assertThrows(function mMockTitle.MockTitle end, "bad named argument title to 'MockTitle' (string or number expected, got nil)" )end
local pageNames =
for _, pageName in ipairs(pageNames) do suite[string.format('test MockTitle: when using page name "%s", the prefixedText property equals the page name', pageName ) ] = function (self) self:assertEquals(pageName, mMockTitle.MockTitle.prefixedText) endend
local simplePropertyTestData =
for _, testData in ipairs(simplePropertyTestData) do suite[string.format('test MockTitle: property %s is mocked using the %s option', testData.property, testData.property)] = function (self) local title = mMockTitle.MockTitle self:assertEquals(testData.value, title[testData.property]) endend
suite['test MockTitle: passing a page name to the redirectTarget option causes redirectTarget to be a MockTitle object with that page name'] = function (self) local title = mMockTitle.MockTitle self:assertEquals('User:Example', title.redirectTarget.prefixedText)end
suite['test MockTitle: passing an ID to the redirectTarget option causes redirectTarget to be a MockTitle object with that ID'] = function (self) local mainPageId = 15580374 local title = mMockTitle.MockTitle self:assertEquals(mainPageId, title.redirectTarget.id)end
suite['test MockTitle: passing an options table to the redirectTarget option causes redirectTarget to be a MockTitle object with those options'] = function (self) local title = mMockTitle.MockTitle self:assertEquals('User:Example/common.js', title.redirectTarget.prefixedText) self:assertEquals('wikitext', title.redirectTarget.contentModel)end
suite['test MockTitle: passing a MockTitle object to the redirectTarget option causes redirectTarget to be that MockTitle object'] = function (self) local mockRedirectTarget = mMockTitle.MockTitle local title = mMockTitle.MockTitle self:assertEquals('User:Example/common.js', title.redirectTarget.prefixedText) self:assertEquals('wikitext', title.redirectTarget.contentModel)end
local protectionLevelTestData =
for _, testData in ipairs(protectionLevelTestData) do suite[string.format('test MockTitle: when setting option %s to "%s", the protectionLevels table is updated accordingly', testData.optionName, testData.optionValue ) ] = function (self) local title = mMockTitle.MockTitle self:assertEquals(testData.optionValue, title.protectionLevels[testData.expectedProtectionAction][1]) endend
local cascadingProtectionLevelTestData =
for _, testData in ipairs(cascadingProtectionLevelTestData) do suite[string.format('test MockTitle: when setting option %s to "%s", ' .. 'and when setting the cascadingProtectionSources option, ' .. 'the cascadingProtection table is updated accordingly', testData.optionName, testData.optionValue ) ] = function (self) local title = mMockTitle.MockTitle self:assertEquals(testData.optionValue, title.cascadingProtection.restrictions[testData.expectedProtectionAction][1] ) self:assertDeepEquals(title.cascadingProtection.sources ) endend
suite['test MockTitle: when a cascading protection argument is given, but no cascading protection sources are given, an error is raised'] = function (self) self:assertThrows(function mMockTitle.MockTitle end, 'a cascading protection argument was given but the cascadingProtectionSources argument was missing or empty' )end
suite['test MockTitle: when a cascading protection argument is given, but the cascading protection sources table is empty, an error is raised'] = function (self) self:assertThrows(function mMockTitle.MockTitle end, 'a cascading protection argument was given but the cascadingProtectionSources argument was missing or empty' )end
suite['test MockTitle: when cascading protection sources are given, but no cascading protection argument is given, an error is raised'] = function (self) self:assertThrows(function mMockTitle.MockTitle end, 'the cascadingProtectionSources argument was given, but no cascading protection argument was given' )end
suite['test MockTitle: if the content option is provided, getContent returns the specified string'] = function (self) local title = mMockTitle.MockTitle self:assertEquals('some wikitext content', title:getContent)end
local filePropertyTestData =
for _, testData in ipairs(filePropertyTestData) do suite[string.format('test MockTitle: when setting option %s to "%s", the file table is updated accordingly', testData.optionName, tostring(testData.optionValue) )] = function(self) local title = mMockTitle.MockTitle self:assertEquals(testData.optionValue, title.file[testData.property]) endend
suite['test MockTitle: when setting fileExists in a non-file namespace, no file table is set'] = function(self) local title = mMockTitle.MockTitle self:assertEquals(nil, title.file)end
local fileExistsTestData =
for _, testData in ipairs(fileExistsTestData) do suite[string.format('test MockTitle: when using page "%s", the fileExists property is %s', testData.title, testData.expected and 'set' or 'not set' ) ] = function (self) local title = mMockTitle.MockTitle self:assertEquals(testData.expected, title.fileExists) endend
local fallbackPropertyTestData =
for _, testData in ipairs(fallbackPropertyTestData) do suite[string.format('test MockTitle: if no %s option is specified, the real %s value is used', testData.option, testData.property)] = function (self) suite:assertDeepEquals(mw.title.new(testData.title)[testData.property], mMockTitle.MockTitle[testData.property] ) endend
suite['test MockTitle: if no content option is specified, getContent returns the the real content'] = function (self) suite:assertEquals(mw.title.new('Main Page'):getContent, mMockTitle.MockTitle:getContent )end
suite['test MockTitle: the content property is not shared between mock objects'] = function (self) suite:assertNotEquals(mMockTitle.MockTitle:getContent, mMockTitle.MockTitle:getContent )end
---------------------------------------------------------------------------------- patchTitleObject tests--------------------------------------------------------------------------------
suite['test patchTitleObject: patchTitleObject returns an equivalent object to MockTitle when used on the same title'] = function (self) suite:assertTitlesAreEqual(mMockTitle.MockTitle, mMockTitle.patchTitleObject(mw.title.new('Main Page'), ) )end
suite['test patchTitleObject: title arguments are ignored'] = function (self) self:assertEquals('User:Example', mMockTitle.patchTitleObject(mw.title.new('User:Example'), ).prefixedText )end
---------------------------------------------------------------------------------- Tests for registering/deregistering mock titles--------------------------------------------------------------------------------
local MOCK_WP_SANDBOX_ARGS = local MOCK_WP_SANDBOX = mMockTitle.MockTitle(MOCK_WP_SANDBOX_ARGS)
local MOCK_MAIN_PAGE_ARGS = local MOCK_MAIN_PAGE = mMockTitle.MockTitle(MOCK_MAIN_PAGE_ARGS)
function suite:tearDownRegistrationTests mMockTitle.clearAllMockTitlesend
suite['test registerMockTitle: real titles are used during patching when no mocks are registered'] = function (self) -- Setup local realTitle = mw.title.new('Wikipedia:Sandbox')
-- Test mMockTitle.patchTitleConstructors(function self:assertTitlesAreEqual(mw.title.new(MOCK_WP_SANDBOX_ARGS.title), realTitle ) end) -- Teardown self:tearDownRegistrationTestsend
local registerMockTitleTestData =
for _, testData in ipairs(registerMockTitleTestData) do suite[string.format('test registerMockTitle: mocks are registered when specified using %s', testData.argType )] = function (self) -- Setup mMockTitle.registerMockTitle(testData.arg)
-- Test mMockTitle.patchTitleConstructors(function self:assertTitlesAreEqual(mw.title.new(MOCK_WP_SANDBOX_ARGS.title), MOCK_WP_SANDBOX ) end) -- Teardown self:tearDownRegistrationTests endend
for _, testData in ipairs(registerMockTitleTestData) do suite[string.format('test registerMockCurrentTitle: mocks are registered when specified using %s', testData.argType )] = function (self) -- Setup mMockTitle.registerMockCurrentTitle(testData.arg)
-- Test mMockTitle.patchTitleConstructors(function self:assertTitlesAreEqual(mw.title.getCurrentTitle, MOCK_WP_SANDBOX ) end) -- Teardown self:tearDownRegistrationTests endend
function suite:setUpDeregistrationTests mMockTitle.registerMockTitles(MOCK_WP_SANDBOX_ARGS, MOCK_MAIN_PAGE_ARGS) mMockTitle.registerMockCurrentTitle(MOCK_WP_SANDBOX_ARGS)end
suite['test deregisterMockTitle: previously registered titles are not deregistered if a deregistration function is not called'] = function (self) -- Setup self:setUpDeregistrationTests
-- Test mMockTitle.patchTitleConstructors(function self:assertTitlesAreEqual(mw.title.new(MOCK_WP_SANDBOX_ARGS.title), MOCK_WP_SANDBOX ) end)
-- Teardown self:tearDownRegistrationTestsend
local deregisterMockTitleTestData =
for _, testData in ipairs(deregisterMockTitleTestData) do suite[string.format('test deregisterMockTitle: previously registered titles are deregistered when specified by %s', testData.argType ) ] = function (self) -- Setup self:setUpDeregistrationTests local realTitle = mw.title.new(MOCK_WP_SANDBOX_ARGS.title) mMockTitle.deregisterMockTitle(testData.arg)
-- Test mMockTitle.patchTitleConstructors(function self:assertTitlesAreEqual(mw.title.new(MOCK_WP_SANDBOX_ARGS.title), realTitle ) end)
-- Teardown self:tearDownRegistrationTests endend
suite['test deregisterMockCurrentTitle: the previously registered current title is not deregistered if a deregistration function is not called'] = function (self) -- Setup self:setUpDeregistrationTests
-- Test mMockTitle.patchTitleConstructors(function self:assertTitlesAreEqual(mw.title.getCurrentTitle, MOCK_WP_SANDBOX) end)
-- Teardown self:tearDownRegistrationTestsend
suite['test deregisterMockCurrentTitle: the previously registered current title is deregistered if deregisterMockCurrentTitle is called'] = function (self) -- Setup self:setUpDeregistrationTests local realTitle = mw.title.getCurrentTitle mMockTitle.deregisterMockCurrentTitle
-- Test mMockTitle.patchTitleConstructors(function self:assertTitlesAreEqual(mw.title.getCurrentTitle, realTitle) end)
-- Teardown self:tearDownRegistrationTestsend
local registerMockTitlesTestData =
for _, testData in ipairs(registerMockTitlesTestData) do suite[string.format('test registerMockTitles: mocks are registered when specified using %s', testData.argType )] = function (self) -- Setup mMockTitle.registerMockTitles(unpack(testData.args))
-- Test mMockTitle.patchTitleConstructors(function self:assertTitlesAreEqual(mw.title.new(MOCK_WP_SANDBOX_ARGS.title), MOCK_WP_SANDBOX ) self:assertTitlesAreEqual(mw.title.new(MOCK_MAIN_PAGE_ARGS.title), MOCK_MAIN_PAGE ) end) -- Teardown self:tearDownRegistrationTests endend
local deregisterMockTitlesTestData =
for _, testData in ipairs(deregisterMockTitlesTestData) do suite[string.format('test deregisterMockTitle: previously registered titles are deregistered when specified by %s', testData.argType ) ] = function (self) -- Setup self:setUpDeregistrationTests local realSandboxTitle = mw.title.new(MOCK_WP_SANDBOX_ARGS.title) local realMainPageTitle = mw.title.new(MOCK_MAIN_PAGE_ARGS.title) mMockTitle.deregisterMockTitles(unpack(testData.args))
-- Test mMockTitle.patchTitleConstructors(function self:assertTitlesAreEqual(mw.title.new(MOCK_WP_SANDBOX_ARGS.title), realSandboxTitle ) self:assertTitlesAreEqual(mw.title.new(MOCK_MAIN_PAGE_ARGS.title), realMainPageTitle ) end)
-- Teardown self:tearDownRegistrationTests endend
suite['test clearMockTitleRegistry: all mock titles are cleared'] = function (self) -- Setup self:setUpDeregistrationTests local realSandboxTitle = mw.title.new(MOCK_WP_SANDBOX_ARGS.title) local realMainPageTitle = mw.title.new(MOCK_MAIN_PAGE_ARGS.title) mMockTitle.clearMockTitleRegistry
-- Test mMockTitle.patchTitleConstructors(function self:assertTitlesAreEqual(mw.title.new(MOCK_WP_SANDBOX_ARGS.title), realSandboxTitle ) self:assertTitlesAreEqual(mw.title.new(MOCK_MAIN_PAGE_ARGS.title), realMainPageTitle ) end)
-- Teardown self:tearDownRegistrationTestsend
suite['test clearAllMockTitles: all registered titles are deregistered when clearAllMockTitles is called'] = function (self) -- Setup self:setUpDeregistrationTests local realSandboxTitle = mw.title.new(MOCK_WP_SANDBOX_ARGS.title) local realMainPageTitle = mw.title.new(MOCK_MAIN_PAGE_ARGS.title) local realCurrentTitle = mw.title.getCurrentTitle mMockTitle.clearAllMockTitles
-- Test mMockTitle.patchTitleConstructors(function self:assertTitlesAreEqual(mw.title.new(MOCK_WP_SANDBOX_ARGS.title), realSandboxTitle ) self:assertTitlesAreEqual(mw.title.new(MOCK_MAIN_PAGE_ARGS.title), realMainPageTitle ) self:assertTitlesAreEqual(mw.title.getCurrentTitle, realCurrentTitle) end)
-- Teardown self:tearDownRegistrationTestsend
suite['test registered mocks do not share content with standalone mocks when title constructors are patched'] = function (self) mMockTitle.registerMockTitle mMockTitle.patchTitleConstructors(function self:assertTitlesAreNotEqual(mw.title.new('Wikipedia:Sandbox'), mMockTitle.MockTitle ) end) self:tearDownRegistrationTestsend
---------------------------------------------------------------------------------- Tests for patching functions--------------------------------------------------------------------------------
local patchingFunctionTestArgs =
for _, testData in ipairs(patchingFunctionTestArgs) do suite[string.format('test %s: %s is patched when the func parameter is run', testData.patchFuncName, testData.constructorName ) ] = function (self) self:setUpDeregistrationTests mMockTitle[testData.patchFuncName](function self:assertTitlesAreEqual(mw.title[testData.constructorName](unpack(testData.constructorArgs)), testData.expectedMockTitle ) end) self:tearDownRegistrationTests end
suite[string.format('test %s: %s is not patched before the function is run', testData.patchFuncName, testData.constructorName ) ] = function (self) -- Setup self:setUpDeregistrationTests local realSandboxTitle = mw.title.new('Wikipedia:Sandbox') self:assertTitlesAreEqual(mw.title[testData.constructorName](unpack(testData.constructorArgs)), testData.expectedRealTitle ) self:tearDownRegistrationTests end
suite[string.format('test %s: %s is not patched after the function is run', testData.patchFuncName, testData.constructorName ) ] = function (self) -- Setup self:setUpDeregistrationTests local realSandboxTitle = mw.title.new('Wikipedia:Sandbox') mMockTitle[testData.patchFuncName](function end) -- Test self:assertTitlesAreEqual(mw.title[testData.constructorName](unpack(testData.constructorArgs)), testData.expectedRealTitle ) -- Teardown self:tearDownRegistrationTests endend
suite['test patchTitleConstructors: all title constructors are patched when the func parameter is run'] = function (self) self:setUpDeregistrationTests mMockTitle.patchTitleConstructors(function self:assertTitlesAreEqual(mw.title.new(MOCK_WP_SANDBOX_ARGS.title), MOCK_WP_SANDBOX ) self:assertTitlesAreEqual(mw.title.new(MOCK_MAIN_PAGE_ARGS.title), MOCK_MAIN_PAGE ) self:assertTitlesAreEqual(mw.title.getCurrentTitle, MOCK_WP_SANDBOX) end) self:tearDownRegistrationTestsend
suite['test patchTitleConstructors: title constructors are not patched after the function is run'] = function (self) -- Setup self:setUpDeregistrationTests local realSandboxTitle = mw.title.new('Wikipedia:Sandbox') local realCurrentTitle = mw.title.getCurrentTitle mMockTitle.patchTitleConstructors(function end)
-- Test self:assertTitlesAreEqual(mw.title.new('Wikipedia:Sandbox'), realSandboxTitle ) self:assertTitlesAreEqual(mw.title.makeTitle(4, 'Sandbox'), realSandboxTitle ) self:assertTitlesAreEqual(mw.title.getCurrentTitle, realCurrentTitle)
-- Teardown self:tearDownRegistrationTestsend
local patchingFuncNames =
for _, patchFuncName in ipairs(patchingFuncNames) do suite[string.format('test %s: varargs are passed as arguments to the func parameter', patchFuncName)] = function (self) mMockTitle[patchFuncName](function (a, b, c) self:assertEquals('foo', a) self:assertEquals('bar', b) self:assertEquals('baz', c) end, 'foo', 'bar', 'baz' ) end suite[string.format('test %s: the result of func is returned', patchFuncName)] = function (self) local result = mMockTitle[patchFuncName](function return 'some value' end) self:assertEquals('some value', result) endend
return suite