Module:Mock title/testcases

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 = {

'prefixedText',

'id',

'exists',

'isRedirect',

'redirectTarget',

'contentModel',

}

for _, prop in ipairs(properties) do

self:assertEquals(

expected[prop],

actual[prop],

string.format('mismatch in property "%s"', prop)

)

end

local deepProperties = {'protectionLevels', 'cascadingProtection'}

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 = {

'exists',

'width',

'height',

'size',

'mimeType',

'length',

}

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)

))

end

end

--------------------------------------------------------------------------------

-- 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 = {

'Example',

'fr:Example',

'Module:Sandbox',

'Module:Sandbox/subpage',

'mw:Test',

'fr:b:Example',

}

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({title = pageName}).prefixedText)

end

end

local simplePropertyTestData = {

{

property = 'id',

title = 'Example',

value = 123456,

},

{

property = 'isRedirect',

title = 'Main Page',

value = true,

},

{

property = 'exists',

title = 'Main Page',

value = false,

},

{

property = 'contentModel',

title = 'Main Page',

value = 'foo',

},

}

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({title = testData.title, [testData.property] = testData.value})

self:assertEquals(testData.value, title[testData.property])

end

end

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({title = 'Example', redirectTarget = 'User:Example'})

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({title = 'Example', redirectTarget = mainPageId})

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({title = 'Example', redirectTarget = {title = 'User:Example/common.js', contentModel = 'wikitext'}})

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({title = 'User:Example/common.js', contentModel = 'wikitext'})

local title = mMockTitle.MockTitle({title = 'Example', redirectTarget = mockRedirectTarget})

self:assertEquals('User:Example/common.js', title.redirectTarget.prefixedText)

self:assertEquals('wikitext', title.redirectTarget.contentModel)

end

local protectionLevelTestData = {

{

optionName = 'editProtection',

optionValue = 'sysop',

expectedProtectionAction = 'edit',

},

{

optionName = 'moveProtection',

optionValue = 'sysop',

expectedProtectionAction = 'move',

},

{

optionName = 'createProtection',

optionValue = 'sysop',

expectedProtectionAction = 'create',

},

{

optionName = 'uploadProtection',

optionValue = 'sysop',

expectedProtectionAction = 'upload',

},

}

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{title = 'Example', [testData.optionName] = testData.optionValue}

self:assertEquals(testData.optionValue, title.protectionLevels[testData.expectedProtectionAction][1])

end

end

local cascadingProtectionLevelTestData = {

{

optionName = 'cascadingEditProtection',

optionValue = 'sysop',

expectedProtectionAction = 'edit',

},

{

optionName = 'cascadingMoveProtection',

optionValue = 'sysop',

expectedProtectionAction = 'move',

},

{

optionName = 'cascadingCreateProtection',

optionValue = 'sysop',

expectedProtectionAction = 'create',

},

{

optionName = 'cascadingUploadProtection',

optionValue = 'sysop',

expectedProtectionAction = 'upload',

},

}

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{

title = 'Example',

[testData.optionName] = testData.optionValue,

cascadingProtectionSources = {'Example', 'Example 2'},

}

self:assertEquals(

testData.optionValue,

title.cascadingProtection.restrictions[testData.expectedProtectionAction][1]

)

self:assertDeepEquals(

{'Example', 'Example 2'},

title.cascadingProtection.sources

)

end

end

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{title = 'Example', cascadingEditProtection = 'sysop'} 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{title = 'Example', cascadingEditProtection = 'sysop', cascadingProtectionSources = {}} 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{title = 'Example', cascadingProtectionSources = {'Example 2', 'Example 3'}} 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{title = 'Non-existent page 29dh12yxm', content = 'some wikitext content'}

self:assertEquals('some wikitext content', title:getContent())

end

local filePropertyTestData = {

{

property = 'exists',

optionName = 'fileExists',

optionValue = true,

},

{

property = 'width',

optionName = 'fileWidth',

optionValue = 123,

},

{

property = 'height',

optionName = 'fileHeight',

optionValue = 456,

},

{

property = 'pages',

optionName = 'filePages',

optionValue = {{height = 800, width = 600}, {height = 800, width = 600}},

},

{

property = 'size',

optionName = 'fileSize',

optionValue = 1024,

},

{

property = 'mimeType',

optionName = 'fileMimeType',

optionValue = 'image/png',

},

{

property = 'length',

optionName = 'fileLength',

optionValue = 60,

},

}

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{title = 'File:Non-existent hf893bc0.png', [testData.optionName] = testData.optionValue}

self:assertEquals(testData.optionValue, title.file[testData.property])

end

end

suite['test MockTitle: when setting fileExists in a non-file namespace, no file table is set'] = function(self)

local title = mMockTitle.MockTitle{title = 'Non-existent page 34u8wg90bfr', fileExists = true}

self:assertEquals(nil, title.file)

end

local fileExistsTestData = {

{

title = 'Non-existent article tr9w78ebna0',

expected = nil,

},

{

title = 'Talk:Non-existent talk page 34hdbe0pafj',

expected = nil,

},

{

title = 'File:Non-existent file 341gh87fgg8',

expected = true,

},

{

title = 'Media:Non-existent file pbfhrw3v8d',

expected = true,

},

}

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({title = testData.title, fileExists = true})

self:assertEquals(testData.expected, title.fileExists)

end

end

local fallbackPropertyTestData = {

{

property = 'id',

option = 'id',

title = 'Example',

},

{

property = 'isRedirect',

option = 'isRedirect',

title = 'WP:ANI',

},

{

property = 'exists',

option = 'exists',

title = 'Non-existent title f292umz0tyi',

},

{

property = 'contentModel',

option = 'contentModel',

title = 'User:Example/common.js',

},

{

property = 'redirectTarget',

option = 'redirectTarget',

title = 'WP:ANI',

},

{

property = 'protectionLevels',

option = 'editProtection',

title = 'Main Page',

},

{

property = 'redirectTarget',

option = 'redirectTarget',

title = 'WP:ANI',

},

{

property = 'cascadingProtection',

option = 'cascadingEditProtection',

title = 'Main Page',

},

{

property = 'cascadingProtection',

option = 'cascadingProtectionSources',

title = 'Main Page',

},

}

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{title = testData.title}[testData.property]

)

end

end

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{title = 'Main Page'}:getContent()

)

end

suite['test MockTitle: the content property is not shared between mock objects'] = function (self)

suite:assertNotEquals(

mMockTitle.MockTitle{title = 'Foo', content = 'Bar'}:getContent(),

mMockTitle.MockTitle{title = 'Foo', content = 'Baz'}: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{

title = 'Main Page',

isRedirect = true,

redirectTarget = 'Wikipedia:Village stocks',

content = '#REDIRECT: Wikipedia:Village stocks',

},

mMockTitle.patchTitleObject(

mw.title.new('Main Page'),

{

isRedirect = true,

redirectTarget = 'Wikipedia:Village stocks',

content = '#REDIRECT: Wikipedia:Village stocks',

}

)

)

end

suite['test patchTitleObject: title arguments are ignored'] = function (self)

self:assertEquals(

'User:Example',

mMockTitle.patchTitleObject(

mw.title.new('User:Example'),

{title = 'Wikipedia:Sandbox'}

).prefixedText

)

end

--------------------------------------------------------------------------------

-- Tests for registering/deregistering mock titles

--------------------------------------------------------------------------------

local MOCK_WP_SANDBOX_ARGS = {

title = 'Wikipedia:Sandbox',

content = 'Some random content: zbS8mJ31l8eY',

isRedirect = true -- Cannot be true for a real page with the above content, so we can prove it's a mock

}

local MOCK_WP_SANDBOX = mMockTitle.MockTitle(MOCK_WP_SANDBOX_ARGS)

local MOCK_MAIN_PAGE_ARGS = {

title = 'Main Page',

content = 'Mock main page content: 38fgbhqwu8adb',

}

local MOCK_MAIN_PAGE = mMockTitle.MockTitle(MOCK_MAIN_PAGE_ARGS)

function suite:tearDownRegistrationTests()

mMockTitle.clearAllMockTitles()

end

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:tearDownRegistrationTests()

end

local registerMockTitleTestData = {

{argType = 'option table', arg = MOCK_WP_SANDBOX_ARGS},

{argType = 'mock title', arg = MOCK_WP_SANDBOX},

}

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()

end

end

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()

end

end

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:tearDownRegistrationTests()

end

local deregisterMockTitleTestData = {

{argType = 'title', arg = MOCK_WP_SANDBOX_ARGS.title},

{argType = 'args table', arg = MOCK_WP_SANDBOX_ARGS},

{argType = 'ID', arg = MOCK_WP_SANDBOX.id},

{argType = 'title object', arg = mw.title.new(MOCK_WP_SANDBOX_ARGS.title)},

{argType = 'mock title object', arg = MOCK_WP_SANDBOX},

}

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()

end

end

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:tearDownRegistrationTests()

end

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:tearDownRegistrationTests()

end

local registerMockTitlesTestData = {

{argType = 'option table', args = {MOCK_WP_SANDBOX_ARGS, MOCK_MAIN_PAGE_ARGS}},

{argType = 'mock title', args = {MOCK_WP_SANDBOX, MOCK_MAIN_PAGE}},

}

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()

end

end

local deregisterMockTitlesTestData = {

{

argType = 'title',

args = {MOCK_WP_SANDBOX_ARGS.title, MOCK_MAIN_PAGE_ARGS.title},

},

{argType = 'args table', args = {MOCK_WP_SANDBOX_ARGS, MOCK_MAIN_PAGE_ARGS}},

{argType = 'ID', args = {MOCK_WP_SANDBOX.id, MOCK_MAIN_PAGE.id}},

{

argType = 'title object',

args = {

mw.title.new(MOCK_WP_SANDBOX_ARGS.title),

mw.title.new(MOCK_MAIN_PAGE_ARGS.title),

},

},

{argType = 'mock title object', args = {MOCK_WP_SANDBOX, MOCK_MAIN_PAGE}},

}

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()

end

end

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:tearDownRegistrationTests()

end

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:tearDownRegistrationTests()

end

suite['test registered mocks do not share content with standalone mocks when title constructors are patched'] = function (self)

mMockTitle.registerMockTitle{title = 'Wikipedia:Sandbox', content = 'Foo'}

mMockTitle.patchTitleConstructors(function ()

self:assertTitlesAreNotEqual(

mw.title.new('Wikipedia:Sandbox'),

mMockTitle.MockTitle{title = 'Wikipedia:Sandbox', content = 'Bar'}

)

end)

self:tearDownRegistrationTests()

end

--------------------------------------------------------------------------------

-- Tests for patching functions

--------------------------------------------------------------------------------

local patchingFunctionTestArgs = {

{

patchFuncName = 'patchTitleNew',

constructorName = 'new',

constructorArgs = {'Wikipedia:Sandbox'},

expectedMockTitle = MOCK_WP_SANDBOX,

expectedRealTitle = mw.title.new('Wikipedia:Sandbox'),

},

{

patchFuncName = 'patchMakeTitle',

constructorName = 'makeTitle',

constructorArgs = {4, 'Sandbox'},

expectedMockTitle = MOCK_WP_SANDBOX,

expectedRealTitle = mw.title.new('Wikipedia:Sandbox'),

},

{

patchFuncName = 'patchGetCurrentTitle',

constructorName = 'getCurrentTitle',

constructorArgs = {},

expectedMockTitle = MOCK_WP_SANDBOX,

expectedRealTitle = mw.title.getCurrentTitle(),

},

}

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()

end

end

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:tearDownRegistrationTests()

end

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:tearDownRegistrationTests()

end

local patchingFuncNames = {

'patchTitleNew',

'patchMakeTitle',

'patchGetCurrentTitle',

'patchTitleConstructors',

}

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)

end

end

return suite