Module:Mock title/doc: Difference between revisions
document another function, and add empty sections for the others |
finish first draft of documentation |
||
Line 1: | Line 1: | ||
This module allows you to easily [[mock object|mock]] Scribunto [[mw: |
This module allows you to easily [[mock object|mock]] Scribunto [[mw:LUAREF#Title objects|title objects]]. This can be useful when writing unit tests for modules which depend on whether a certain page exists, or whether a certain page is a redirect, etc. If you don't use mock title objects, then you run the risk of some editor changing a page that your test cases relied on (e.g. redirecting it or deleting it), thus breaking your tests. By using mock objects, you get to specify things like existence status and redirect status in your tests, making them more resilient against changes to real pages. |
||
== Usage == |
== Usage == |
||
Line 23: | Line 23: | ||
<syntaxhighlight lang="lua"> |
<syntaxhighlight lang="lua"> |
||
mMockTitle.registerMockTitles( |
mMockTitle.registerMockTitles( |
||
{title = "File:Example.png", height = 250, width = 200}, |
|||
{title = "Template:3x", editProtection = "templateeditor"} |
|||
) |
) |
||
</syntaxhighlight> |
</syntaxhighlight> |
||
Line 36: | Line 36: | ||
=== Patching title constructors === |
=== Patching title constructors === |
||
During tests, you can use the <code>patchTitleConstructors</code> function to temporarily replace the title constructors [[mw: |
During tests, you can use the <code>patchTitleConstructors</code> function to temporarily replace the title constructors [[mw:LUAREF#mw.title.new|mw.title.new]], [[mw:LUAREF#mw.title.makeTitle|mw.title.makeTitle]] and [[mw:LUAREF#mw.title.getCurrentTitle|mw.title.getCurrentTitle]] with functions that return the mock titles that you registered. You pass <code>patchTitleConstructors</code> your own function containing your test code; while the function is running the title constructors will return mock titles, but after it finishes running they will be restored to their original versions. |
||
<syntaxhighlight lang="lua"> |
<syntaxhighlight lang="lua"> |
||
local function logCurrentTitle() |
local function logCurrentTitle() |
||
mw.log(mw.title.getCurrentTitle().prefixedText) |
|||
end |
end |
||
Line 48: | Line 47: | ||
logCurrentTitle() -- Logs "Module:Mock title" |
logCurrentTitle() -- Logs "Module:Mock title" |
||
</syntaxhighlight> |
</syntaxhighlight> |
||
== Sample test code == |
|||
Let's say you want to test [[Module:Pagetype]]. This module displays a page type such as "article" for pages in mainspace, and "file" for pages in the File namespace. It also displays "redirect" for redirects in any namespace. Because of its ability to detect redirects, the module's output depends on the content of pages on the wiki. If we just used regular pages, then this would mean that people could break our tests just by redirecting certain pages. Not good! |
|||
To protect against this eventuality, we can use mock titles. |
|||
This example uses [[Module:ScribuntoUnit]] as the test runner. The /testcases module would include code like this: |
|||
<syntaxhighlight lang="lua"> |
|||
local mPageType = require('Module:Pagetype') |
|||
local ScribuntoUnit = require('Module:ScribuntoUnit') |
|||
local mMockTitle = require('Module:Mock title') |
|||
local suite = ScribuntoUnit:new() |
|||
mMockTitle.registerMockTitles( |
|||
{title = 'United Kingdom', isRedirect = false}, |
|||
{title = 'UK', isRedirect = true} |
|||
) |
|||
function suite:testMainspacePages() |
|||
local actual = mMockTitle.patchTitleConstructors(mPageType.main, {page = 'United Kingdom'}) |
|||
suite:assertEquals('article', actual) |
|||
end |
|||
function suite:testMainspaceRedirects() |
|||
local actual = mMockTitle.patchTitleConstructors(mPageType.main, {page = 'UK'}) |
|||
suite:assertEquals('redirect', actual) |
|||
end |
|||
return suite |
|||
</syntaxhighlight> |
|||
Note that in these tests we make use of [[#patchTitleConstructors|patchTitleConstructors]]' ability to return the value of the function it runs. This means that we can store the result of <code>mPageType.main</code> in the <code>actual</code> variable and compare it with the expected result outside of the patched function. |
|||
== API documentation == |
== API documentation == |
||
Line 69: | Line 102: | ||
This function takes a table of options. The possible options are as follows: |
This function takes a table of options. The possible options are as follows: |
||
* '''title''' - the page title. If this is a string, it is the page title as used with [[mw: |
* '''title''' - the page title. If this is a string, it is the page title as used with [[mw:LUAREF#mw.title.new|mw.title.new]]. If it is a number, it is the page ID. (required) |
||
* '''id''' - the page ID. (int, optional) |
* '''id''' - the page ID. (int, optional) |
||
* '''contentModel''' - the content model. (string, optional) |
* '''contentModel''' - the content model. (string, optional) |
||
Line 87: | Line 120: | ||
* '''fileWidth''' - the file width in pixels (not used for non-file titles). (int, optional) |
* '''fileWidth''' - the file width in pixels (not used for non-file titles). (int, optional) |
||
* '''fileHeight''' - the file height in pixels (not used for non-file titles). (int, optional) |
* '''fileHeight''' - the file height in pixels (not used for non-file titles). (int, optional) |
||
* '''filePages''' - pages in the file (not used for non-file titles). See [[mw: |
* '''filePages''' - pages in the file (not used for non-file titles). See [[mw:LUAREF#File metadata|the Scribunto documentation]] of the title object <code>pages</code> parameter for the correct format. (table, optional) |
||
* '''fileSize''' - the file size in bytes (not used for non-file titles). (int, optional) |
* '''fileSize''' - the file size in bytes (not used for non-file titles). (int, optional) |
||
* '''fileMimeType''' - the [[MIME type]] of the file (not used for non-file titles). (int, optional) |
* '''fileMimeType''' - the [[MIME type]] of the file (not used for non-file titles). (int, optional) |
||
Line 96: | Line 129: | ||
<syntaxhighlight lang="lua"> |
<syntaxhighlight lang="lua"> |
||
local protectedFileMock = mMockTitle.MockTitle{ |
local protectedFileMock = mMockTitle.MockTitle{ |
||
title = "File:Example.png", |
|||
editProtection = "sysop", |
|||
moveProtection = "sysop", |
|||
} |
} |
||
</syntaxhighlight> |
</syntaxhighlight> |
||
Line 106: | Line 139: | ||
<syntaxhighlight lang="lua"> |
<syntaxhighlight lang="lua"> |
||
local circularRedirectMock = mMockTitle.MockTitle{ |
local circularRedirectMock = mMockTitle.MockTitle{ |
||
title = "Original page", |
|||
isRedirect = true, |
|||
redirectTarget = { |
|||
title = "Redirect target", |
|||
isRedirect = true, |
|||
redirectTarget = "Original page", |
|||
}, |
|||
} |
} |
||
</syntaxhighlight> |
</syntaxhighlight> |
||
Line 131: | Line 164: | ||
* '''title''' - the title object to patch. (table, required) |
* '''title''' - the title object to patch. (table, required) |
||
* '''options''' - options specifying data in the title object to be mocked (table, required). The possible options are the same as for [[#MockTitle|MockTitle]], except that the <code>title</code> |
* '''options''' - options specifying data in the title object to be mocked (table, required). The possible options are the same as for [[#MockTitle|MockTitle]], except that the <code>title</code> option is not required, and is ignored if specified. |
||
Example |
Example: patch a title object for the Main Page. |
||
<syntaxhighlight lang="lua"> |
<syntaxhighlight lang="lua"> |
||
Line 142: | Line 175: | ||
=== Registration functions === |
=== Registration functions === |
||
These functions allow you to register mock titles in the module's internal mock title registry. When title constructors are patched with one of the [[#Patching functions|patching functions]], the title constructors return mock titles registered with these functions instead of normal title objects. |
|||
==== registerMockTitle ==== |
==== registerMockTitle ==== |
||
Register a single mock title. |
|||
Usage: |
|||
<syntaxhighlight lang="lua"> |
|||
mMockTitle.registerMockTitle(titleOrOptions) |
|||
</syntaxhighlight> |
|||
Parameters: |
|||
* '''titleOrOptions''' - a [[#MockTitle|MockTitle]] object, or a table of MockTitle object options. (table, required) |
|||
==== regsiterMockTitles ==== |
==== regsiterMockTitles ==== |
||
Register multiple mock titles. |
|||
Usage: |
|||
<syntaxhighlight lang="lua"> |
|||
mMockTitle.registerMockTitles(...) |
|||
</syntaxhighlight> |
|||
Parameters: |
|||
This function takes a variable number of parameters, each of which must be either a [[#MockTitle|MockTitle]] object, or a table of MockTitle object options. (table, required) |
|||
==== registerMockCurrentTitle ==== |
==== registerMockCurrentTitle ==== |
||
Register a mock title as the current title. If mw.title.getCurrentTitle is patched with a [[#Patching functions|patching function]], it will return the mock title registered with this function. |
|||
Usage: |
|||
<syntaxhighlight lang="lua"> |
|||
mMockTitle.registerMockCurrentTitle(titleOrOptions) |
|||
</syntaxhighlight> |
|||
Parameters: |
|||
* '''titleOrOptions''' - a [[#MockTitle|MockTitle]] object, or a table of MockTitle object options. (table, required) |
|||
=== Deregistration functions === |
=== Deregistration functions === |
||
These functions remove mock titles registered with one of the [[#Registration functions|registration functions]]. |
|||
==== deregisterMockTitle ==== |
==== deregisterMockTitle ==== |
||
Remove a single title from the mock title registry. |
|||
<syntaxhighlight lang="lua"> |
|||
mMockTitle.deregisterMockTitle(titleOrOptions) |
|||
</syntaxhighlight> |
|||
Parameters: |
|||
* '''titleOrOptions''' - the title to be removed (required). Must be one of the following: |
|||
** A page name (string) |
|||
** A page ID (number) |
|||
** A [[#MockTitle|MockTitle]] object (table) |
|||
** A table of MockTitle object options (table) |
|||
==== deregsiterMockTitles ==== |
==== deregsiterMockTitles ==== |
||
Remove multiple titles from the mock title registry. |
|||
Usage: |
|||
<syntaxhighlight lang="lua"> |
|||
mMockTitle.deregisterMockTitles(...) |
|||
</syntaxhighlight> |
|||
Parameters: |
|||
This function takes a variable number of parameters, each of which must be one of the following: |
|||
* A page name (string) |
|||
* A page ID (number) |
|||
* A [[#MockTitle|MockTitle]] object (table) |
|||
* A table of MockTitle object options (table) |
|||
==== deregsiterMockCurrentTitle ==== |
==== deregsiterMockCurrentTitle ==== |
||
Remove the mock title registered as the current title. |
|||
<syntaxhighlight lang="lua"> |
|||
mMockTitle.deregisterMockCurrentTitle() |
|||
</syntaxhighlight> |
|||
==== clearMockTitleRegistry ==== |
==== clearMockTitleRegistry ==== |
||
Remove all titles from the mock title registry. This removes titles added with [[#registerMockTitle|registerMockTitle]] or [[#registerMockTitles|registerMockTitles]], but does not remove the registered mock current title. |
|||
<syntaxhighlight lang="lua"> |
|||
mMockTitle.clearMockTitleRegistry() |
|||
</syntaxhighlight> |
|||
==== clearAllMockTitles ==== |
==== clearAllMockTitles ==== |
||
Remove all mock titles. This removes titles from the mock title registry that were added with [[#registerMockTitle|registerMockTitle]] or [[#registerMockTitles|registerMockTitles]], and also removes the registered mock current title. |
|||
<syntaxhighlight lang="lua"> |
|||
mMockTitle.clearMockTitleRegistry() |
|||
</syntaxhighlight> |
|||
=== Patching functions === |
=== Patching functions === |
||
These functions patch one or more of the Scribunto functions that create [[mw:LUAREF#Title objects|title objects]]. When these functions are patched, the patched versions will return mock titles registered with one of the [[#Registration functions|registration functions]]. |
|||
==== patchTitleNew ==== |
==== patchTitleNew ==== |
||
Patch [[mw:LUAREF#mw.title.new|mw.title.new]]. |
|||
<syntaxhighlight lang="lua"> |
|||
mMockTitle.patchTitleNew(func, ...) |
|||
</syntaxhighlight> |
|||
Parameters: |
|||
* '''func''': a function to be run while mw.title.new is patched. The original mw.title.new will be restored after the function is run. |
|||
* Other positional parameters: arguments to be passed to the ''func'' parameter. |
|||
Returns: the result of the ''func'' parameter. |
|||
==== patchMakeTitle ==== |
==== patchMakeTitle ==== |
||
Patch [[mw:LUAREF#mw.title.makeTitle|mw.title.makeTitle]]. |
|||
<syntaxhighlight lang="lua"> |
|||
mMockTitle.patchTitleNew(func, ...) |
|||
</syntaxhighlight> |
|||
Parameters: |
|||
* '''func''': a function to be run while mw.title.makeTitle is patched. The original mw.title.makeTitle will be restored after the function is run. |
|||
* Other positional parameters: arguments to be passed to the ''func'' parameter. |
|||
Returns: the result of the ''func'' parameter. |
|||
==== patchGetCurrentTitle ==== |
==== patchGetCurrentTitle ==== |
||
Patch [[mw:LUAREF#mw.title.getCurrentTitle|mw.title.getCurrentTitle]]. |
|||
<syntaxhighlight lang="lua"> |
|||
mMockTitle.patchTitleNew(func, ...) |
|||
</syntaxhighlight> |
|||
Parameters: |
|||
* '''func''': a function to be run while mw.title.getCurrentTitle is patched. The original mw.title.getCurrentTitle will be restored after the function is run. |
|||
* Other positional parameters: arguments to be passed to the ''func'' parameter. |
|||
Returns: the result of the ''func'' parameter. |
|||
==== patchTitleConstructors ==== |
==== patchTitleConstructors ==== |
||
Patch all title constructors: [[mw:LUAREF#mw.title.new|mw.title.new]], [[mw:LUAREF#mw.title.makeTitle|mw.title.makeTitle]], and [[mw:LUAREF#mw.title.getCurrentTitle|mw.title.getCurrentTitle]]. |
|||
<syntaxhighlight lang="lua"> |
|||
mMockTitle.patchTitleNew(func, ...) |
|||
</syntaxhighlight> |
|||
Parameters: |
|||
* '''func''': a function to be run while the title constructors are patched. The original title constructors will be restored after the function is run. |
|||
* Other positional parameters: arguments to be passed to the ''func'' parameter. |
|||
Returns: the result of the ''func'' parameter. |
|||
<includeonly>{{Sandbox other|| |
<includeonly>{{Sandbox other|| |
Revision as of 13:51, 22 August 2023
This module allows you to easily mock Scribunto title objects. This can be useful when writing unit tests for modules which depend on whether a certain page exists, or whether a certain page is a redirect, etc. If you don't use mock title objects, then you run the risk of some editor changing a page that your test cases relied on (e.g. redirecting it or deleting it), thus breaking your tests. By using mock objects, you get to specify things like existence status and redirect status in your tests, making them more resilient against changes to real pages.
Usage
Loading the module
Load the module using require
:
local mMockTitle = require('Module:Mock title')
Registering titles to mock
You can register a title to be mocked with the registerMockTitle
function.
mMockTitle.registerMockTitle({title = "Main Page", isRedirect = true, redirectTarget = "Wikipedia:Village stocks"})
Or you can register multiple titles at once using registerMockTitles
.
mMockTitle.registerMockTitles(
{title = "File:Example.png", height = 250, width = 200},
{title = "Template:3x", editProtection = "templateeditor"}
)
You can also register a mock for the current page with registerMockCurrentTitle
.
mMockTitle.registerMockCurrentTitle({title = "User:Example"})
Patching title constructors
During tests, you can use the patchTitleConstructors
function to temporarily replace the title constructors mw.title.new, mw.title.makeTitle and mw.title.getCurrentTitle with functions that return the mock titles that you registered. You pass patchTitleConstructors
your own function containing your test code; while the function is running the title constructors will return mock titles, but after it finishes running they will be restored to their original versions.
local function logCurrentTitle()
mw.log(mw.title.getCurrentTitle().prefixedText)
end
logCurrentTitle() -- Logs "Module:Mock title"
mMockTitle.patchTitleConstructors(logCurrentTitle) -- Logs "User:Example"
logCurrentTitle() -- Logs "Module:Mock title"
Sample test code
Let's say you want to test Module:Pagetype. This module displays a page type such as "article" for pages in mainspace, and "file" for pages in the File namespace. It also displays "redirect" for redirects in any namespace. Because of its ability to detect redirects, the module's output depends on the content of pages on the wiki. If we just used regular pages, then this would mean that people could break our tests just by redirecting certain pages. Not good!
To protect against this eventuality, we can use mock titles.
This example uses Module:ScribuntoUnit as the test runner. The /testcases module would include code like this:
local mPageType = require('Module:Pagetype')
local ScribuntoUnit = require('Module:ScribuntoUnit')
local mMockTitle = require('Module:Mock title')
local suite = ScribuntoUnit:new()
mMockTitle.registerMockTitles(
{title = 'United Kingdom', isRedirect = false},
{title = 'UK', isRedirect = true}
)
function suite:testMainspacePages()
local actual = mMockTitle.patchTitleConstructors(mPageType.main, {page = 'United Kingdom'})
suite:assertEquals('article', actual)
end
function suite:testMainspaceRedirects()
local actual = mMockTitle.patchTitleConstructors(mPageType.main, {page = 'UK'})
suite:assertEquals('redirect', actual)
end
return suite
Note that in these tests we make use of patchTitleConstructors' ability to return the value of the function it runs. This means that we can store the result of mPageType.main
in the actual
variable and compare it with the expected result outside of the patched function.
API documentation
Mock title constructors
MockTitle
Creates a mock title object.
Mock title objects function like normal title objects, but values you specify when creating them are used instead of the real values taken from the wiki.
Usage:
mMockTitle.MockTitle(options)
Parameters:
This function takes a table of options. The possible options are as follows:
- title - the page title. If this is a string, it is the page title as used with mw.title.new. If it is a number, it is the page ID. (required)
- id - the page ID. (int, optional)
- contentModel - the content model. (string, optional)
- exists - whether the page exists. (bool, optional)
- isRedirect - whether the page is a redirect. (bool, optional)
- redirectTarget - the redirect target of the page. This can be a string (the page title as used with mw.title.new), a number (the page ID), a table of options for
MockTitle
, or a title object (mock or otherwise). - content - the page's content. (string, optional)
- editProtection - the edit protection level, e.g. "sysop" or "editsemiprotected". (string, optional)
- moveProtection - the move protection level, e.g. "sysop" or "extendedconfirmed". (string, optional)
- createProtection - the create protection level, e.g. "sysop". (string, optional)
- uploadProtection - the upload protection level, e.g. "sysop". (string, optional)
- cascadingEditProtection - the edit protection level for cascading protection, e.g. "sysop" or "editsemiprotected". (string, optional)
- cascadingMoveProtection - the move protection level for cascading protection, e.g. "sysop" or "extendedconfirmed". (string, optional)
- cascadingCreateProtection - the create protection level for cascading protection, e.g. "sysop". (string, optional)
- cascadingUploadProtection - the upload protection level for cascading protection, e.g. "sysop". (string, optional)
- fileExists - whether the file exists (not used for non-file titles). (bool, optional)
- fileWidth - the file width in pixels (not used for non-file titles). (int, optional)
- fileHeight - the file height in pixels (not used for non-file titles). (int, optional)
- filePages - pages in the file (not used for non-file titles). See the Scribunto documentation of the title object
pages
parameter for the correct format. (table, optional) - fileSize - the file size in bytes (not used for non-file titles). (int, optional)
- fileMimeType - the MIME type of the file (not used for non-file titles). (int, optional)
- fileLength - the file length (duration) in seconds (not used for non-file titles). (int, optional)
Example 1: create a mock title of a fully protected file.
local protectedFileMock = mMockTitle.MockTitle{
title = "File:Example.png",
editProtection = "sysop",
moveProtection = "sysop",
}
Example 2: create a mock circular redirect.
local circularRedirectMock = mMockTitle.MockTitle{
title = "Original page",
isRedirect = true,
redirectTarget = {
title = "Redirect target",
isRedirect = true,
redirectTarget = "Original page",
},
}
patchTitleObject
Create a mock title object by patching an existing title object with the specified options.
Usage:
mMockTitle.patchTitleObject(title, options)
Parameters:
This function takes two parameters:
- title - the title object to patch. (table, required)
- options - options specifying data in the title object to be mocked (table, required). The possible options are the same as for MockTitle, except that the
title
option is not required, and is ignored if specified.
Example: patch a title object for the Main Page.
local title = mw.title.new('Main Page')
local mock = mMockTitle.patchTitleObject(title, {content = "Mock content"})
mw.log(mock:getContent()) -- logs "Mock content"
Registration functions
These functions allow you to register mock titles in the module's internal mock title registry. When title constructors are patched with one of the patching functions, the title constructors return mock titles registered with these functions instead of normal title objects.
registerMockTitle
Register a single mock title.
Usage:
mMockTitle.registerMockTitle(titleOrOptions)
Parameters:
- titleOrOptions - a MockTitle object, or a table of MockTitle object options. (table, required)
regsiterMockTitles
Register multiple mock titles.
Usage:
mMockTitle.registerMockTitles(...)
Parameters:
This function takes a variable number of parameters, each of which must be either a MockTitle object, or a table of MockTitle object options. (table, required)
registerMockCurrentTitle
Register a mock title as the current title. If mw.title.getCurrentTitle is patched with a patching function, it will return the mock title registered with this function.
Usage:
mMockTitle.registerMockCurrentTitle(titleOrOptions)
Parameters:
- titleOrOptions - a MockTitle object, or a table of MockTitle object options. (table, required)
Deregistration functions
These functions remove mock titles registered with one of the registration functions.
deregisterMockTitle
Remove a single title from the mock title registry.
mMockTitle.deregisterMockTitle(titleOrOptions)
Parameters:
- titleOrOptions - the title to be removed (required). Must be one of the following:
- A page name (string)
- A page ID (number)
- A MockTitle object (table)
- A table of MockTitle object options (table)
deregsiterMockTitles
Remove multiple titles from the mock title registry.
Usage:
mMockTitle.deregisterMockTitles(...)
Parameters:
This function takes a variable number of parameters, each of which must be one of the following:
- A page name (string)
- A page ID (number)
- A MockTitle object (table)
- A table of MockTitle object options (table)
deregsiterMockCurrentTitle
Remove the mock title registered as the current title.
mMockTitle.deregisterMockCurrentTitle()
clearMockTitleRegistry
Remove all titles from the mock title registry. This removes titles added with registerMockTitle or registerMockTitles, but does not remove the registered mock current title.
mMockTitle.clearMockTitleRegistry()
clearAllMockTitles
Remove all mock titles. This removes titles from the mock title registry that were added with registerMockTitle or registerMockTitles, and also removes the registered mock current title.
mMockTitle.clearMockTitleRegistry()
Patching functions
These functions patch one or more of the Scribunto functions that create title objects. When these functions are patched, the patched versions will return mock titles registered with one of the registration functions.
patchTitleNew
Patch mw.title.new.
mMockTitle.patchTitleNew(func, ...)
Parameters:
- func: a function to be run while mw.title.new is patched. The original mw.title.new will be restored after the function is run.
- Other positional parameters: arguments to be passed to the func parameter.
Returns: the result of the func parameter.
patchMakeTitle
Patch mw.title.makeTitle.
mMockTitle.patchTitleNew(func, ...)
Parameters:
- func: a function to be run while mw.title.makeTitle is patched. The original mw.title.makeTitle will be restored after the function is run.
- Other positional parameters: arguments to be passed to the func parameter.
Returns: the result of the func parameter.
patchGetCurrentTitle
Patch mw.title.getCurrentTitle.
mMockTitle.patchTitleNew(func, ...)
Parameters:
- func: a function to be run while mw.title.getCurrentTitle is patched. The original mw.title.getCurrentTitle will be restored after the function is run.
- Other positional parameters: arguments to be passed to the func parameter.
Returns: the result of the func parameter.
patchTitleConstructors
Patch all title constructors: mw.title.new, mw.title.makeTitle, and mw.title.getCurrentTitle.
mMockTitle.patchTitleNew(func, ...)
Parameters:
- func: a function to be run while the title constructors are patched. The original title constructors will be restored after the function is run.
- Other positional parameters: arguments to be passed to the func parameter.
Returns: the result of the func parameter.