Toggle menu
15
236
70
27.5K
Kenshi Wiki
Toggle preferences menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.
Refer to
Module:Redirect hatnote



local mRedirectHatnote = require('Module:Redirect hatnote/sandbox')
local _redirect = mRedirectHatnote._redirect
local ScribuntoUnit = require('Module:ScribuntoUnit')
local suite = ScribuntoUnit:new()

--------------------------------------------------------------------------------
-- Helper functions
--------------------------------------------------------------------------------

function suite.runRedirect(args, childArgs)
	-- Runs the "redirect" function with an args table passed from a
	-- parent frame.
	local frame = mw.getCurrentFrame()
	local parent = frame:newChild{args = args}
	local child = parent:newChild{args = childArgs}
	return mRedirectHatnote.redirect(child)
end

--------------------------------------------------------------------------------
-- Test #invoke function basic
--------------------------------------------------------------------------------

function suite:testBlank()
	local result = suite.runRedirect({},{})
	self:assertStringContains('missing redirect parameter', result, true)
	self:assertStringContains('Template:Redirect#Errors', result, true)
end

function suite:testRedirectOnly()
	local result = suite.runRedirect({'REDIRECT'},{1})
	self:assertStringContains('"REDIRECT" redirects here. For other uses, see [[:REDIRECT (disambiguation)]].', result, true)
end

function suite:testUse1()
	local result = suite.runRedirect({'REDIRECT', 'USE1'},{1})
	self:assertStringContains('"REDIRECT" redirects here. For USE1, see [[:REDIRECT (disambiguation)]].', result, true)
end

function suite:testPage1()
	local result = suite.runRedirect({'REDIRECT', 'USE1', 'PAGE1'},{1})
	self:assertStringContains('"REDIRECT" redirects here. For USE1, see [[:PAGE1]].', result, true)
end

function suite:testUse2()
	local result = suite.runRedirect({'REDIRECT', 'USE1', 'PAGE1', 'USE2'},{1})
	self:assertStringContains('"REDIRECT" redirects here. For USE1, see [[:PAGE1]]. For USE2, see [[:REDIRECT (disambiguation)]].', result, true)
end

function suite:testPage2()
	local result = suite.runRedirect({'REDIRECT', 'USE1', 'PAGE1', 'USE2', 'PAGE2'},{1})
	self:assertStringContains('"REDIRECT" redirects here. For USE1, see [[:PAGE1]]. For USE2, see [[:PAGE2]].', result, true)
end

function suite:testUse3()
	local result = suite.runRedirect({'REDIRECT', 'USE1', 'PAGE1', 'USE2', 'PAGE2', 'USE3'},{1})
	self:assertStringContains('"REDIRECT" redirects here. For USE1, see [[:PAGE1]]. For USE2, see [[:PAGE2]]. For USE3, see [[:REDIRECT (disambiguation)]].', result, true)
end

function suite:testPage3()
	local result = suite.runRedirect({'REDIRECT', 'USE1', 'PAGE1', 'USE2', 'PAGE2', 'USE3', 'PAGE3'},{1})
	self:assertStringContains('"REDIRECT" redirects here. For USE1, see [[:PAGE1]]. For USE2, see [[:PAGE2]]. For USE3, see [[:PAGE3]].', result, true)
end

function suite:testUse4()
	local result = suite.runRedirect({'REDIRECT', 'USE1', 'PAGE1', 'USE2', 'PAGE2', 'USE3', 'PAGE3', 'USE4'},{1})
	self:assertStringContains('"REDIRECT" redirects here. For USE1, see [[:PAGE1]]. For USE2, see [[:PAGE2]]. For USE3, see [[:PAGE3]]. For USE4, see [[:REDIRECT (disambiguation)]].', result, true)
end

function suite:testPage4()
	local result = suite.runRedirect({'REDIRECT', 'USE1', 'PAGE1', 'USE2', 'PAGE2', 'USE3', 'PAGE3', 'USE4', 'PAGE4'},{1})
	self:assertStringContains('"REDIRECT" redirects here. For USE1, see [[:PAGE1]]. For USE2, see [[:PAGE2]]. For USE3, see [[:PAGE3]]. For USE4, see [[:PAGE4]].', result, true)
end

function suite:testPipeInput()
	local result = suite.runRedirect({'REDIRECT', 'USE1', 'PAGE1 (disambiguation)|PAGE1', 'USE2', 'PAGE2 (disambiguation)|PAGE2', 'USE3', 'PAGE3 (disambiguation)|PAGE3', 'USE4', 'PAGE4 (disambiguation)|PAGE4'},{1})
	self:assertStringContains('"REDIRECT" redirects here. For USE1, see [[:PAGE1 (disambiguation)|PAGE1]]. For USE2, see [[:PAGE2 (disambiguation)|PAGE2]]. For USE3, see [[:PAGE3 (disambiguation)|PAGE3]]. For USE4, see [[:PAGE4 (disambiguation)|PAGE4]].', result, true)
end

--------------------------------------------------------------------------------
-- Test "and"
--------------------------------------------------------------------------------

function suite:testPage1AndPage2()
	local result = suite.runRedirect({'REDIRECT', 'USE1', 'PAGE1', 'and', 'PAGE2'},{1})
	self:assertStringContains('"REDIRECT" redirects here. For USE1, see [[:PAGE1]] and [[:PAGE2]].', result, true)
end

function suite:testPage2AndPage3()
	local result = suite.runRedirect({'REDIRECT', 'USE1', 'PAGE1', 'USE2', 'PAGE2', 'and', 'PAGE3'},{1})
	self:assertStringContains('"REDIRECT" redirects here. For USE1, see [[:PAGE1]]. For USE2, see [[:PAGE2]] and [[:PAGE3]].', result, true)
end

function suite:testPage1AndPage2Page3AndPage4()
	local result = suite.runRedirect({'REDIRECT', 'USE1', 'PAGE1', 'and', 'PAGE2', 'USE2', 'PAGE3', 'and', 'PAGE4'},{1})
	self:assertStringContains('"REDIRECT" redirects here. For USE1, see [[:PAGE1]] and [[:PAGE2]]. For USE2, see [[:PAGE3]] and [[:PAGE4]].', result, true)
end

function suite:testTwoAnds()
	local result = suite.runRedirect({'REDIRECT', 'USE1', 'PAGE1', 'and', 'PAGE2', 'and', 'PAGE3'},{1})
	self:assertStringContains('"REDIRECT" redirects here. For USE1, see [[:PAGE1]], [[:PAGE2]], and [[:PAGE3]].', result, true)
end

function suite:testThreeAnds()
	local result = suite.runRedirect({'REDIRECT', 'USE1', 'PAGE1', 'and', 'PAGE2', 'and', 'PAGE3', 'and', 'PAGE4'},{1})
	self:assertStringContains('"REDIRECT" redirects here. For USE1, see [[:PAGE1]], [[:PAGE2]], [[:PAGE3]], and [[:PAGE4]].', result, true)
end

function suite:testTwoAndsUse2()
	local result = suite.runRedirect({'REDIRECT', 'USE1', 'PAGE1', 'and', 'PAGE2', 'and', 'PAGE3', 'USE2', 'PAGE4'},{1})
	self:assertStringContains('"REDIRECT" redirects here. For USE1, see [[:PAGE1]], [[:PAGE2]], and [[:PAGE3]]. For USE2, see [[:PAGE4]].', result, true)
end

--------------------------------------------------------------------------------
-- Test skipping parameters
--------------------------------------------------------------------------------

function suite:testUse1Skipped()
	local result = suite.runRedirect({'REDIRECT', '', 'PAGE1'},{1})
	self:assertStringContains('"REDIRECT" redirects here. For other uses, see [[:PAGE1]].', result, true)
end

function suite:testPage1Skipped()
	local result = suite.runRedirect({'REDIRECT', 'USE1', '', 'USE2'},{1})
	self:assertStringContains('"REDIRECT" redirects here. For USE1, see [[:REDIRECT (disambiguation)]]. For USE2, see [[:REDIRECT (disambiguation)]].', result, true)
end

function suite:testUse2Skipped()
	local result = suite.runRedirect({'REDIRECT', 'USE1', 'PAGE1', '', 'PAGE2'},{1})
	self:assertStringContains('"REDIRECT" redirects here. For USE1, see [[:PAGE1]].', result, true)
end

function suite:testPage2Skipped()
	local result = suite.runRedirect({'REDIRECT', 'USE1', 'PAGE1', 'USE2', '', 'USE3'},{1})
	self:assertStringContains('"REDIRECT" redirects here. For USE1, see [[:PAGE1]]. For USE2, see [[:REDIRECT (disambiguation)]]. For USE3, see [[:REDIRECT (disambiguation)]].', result, true)
end

function suite:testUse3Skipped()
	local result = suite.runRedirect({'REDIRECT', 'USE1', 'PAGE1', 'USE2', 'PAGE2', '', 'PAGE3'},{1})
	self:assertStringContains('"REDIRECT" redirects here. For USE1, see [[:PAGE1]]. For USE2, see [[:PAGE2]].', result, true)
end

function suite:testMiddleUseSkipped()
	local result = suite.runRedirect({'REDIRECT', 'USE1', 'PAGE1', '', 'PAGE2', 'USE3', 'PAGE3'},{1})
	self:assertStringContains('"REDIRECT" redirects here. For USE1, see [[:PAGE1]].', result, true)
end

function suite:testMiddlePageSkipped()
	local result = suite.runRedirect({'REDIRECT', 'USE1', 'PAGE1', 'USE2', '', 'USE3', 'PAGE3'},{1})
	self:assertStringContains('"REDIRECT" redirects here. For USE1, see [[:PAGE1]]. For USE2, see [[:REDIRECT (disambiguation)]]. For USE3, see [[:PAGE3]].', result, true)
end

--------------------------------------------------------------------------------
-- Test other uses
--------------------------------------------------------------------------------

function suite:testUse2Skipped()
	local result = suite.runRedirect({'REDIRECT', 'USE1', 'PAGE1', '', 'PAGE2'},{1})
	self:assertStringContains('"REDIRECT" redirects here. For USE1, see [[:PAGE1]].', result, true)
end

function suite:testOtherUsesIsNotFinal()
	local result = suite.runRedirect({'REDIRECT', 'USE1', 'PAGE1', 'other uses', 'PAGE2', 'USE3', 'PAGE3'},{1})
	self:assertStringContains('"REDIRECT" redirects here. For USE1, see [[:PAGE1]]. For other uses, see [[:PAGE2]]. For USE3, see [[:PAGE3]].', result, true)
end

--------------------------------------------------------------------------------
-- Test options
--------------------------------------------------------------------------------

function suite:testSelfRef()
	local result = suite.runRedirect({'REDIRECT', selfref = 'yes'},{1})
	self:assertStringContains('class=".-selfref.-"', result, false)
end

--------------------------------------------------------------------------------
-- Test Lua interface
--------------------------------------------------------------------------------

function suite:assertError(...)
	local success, result = pcall(_redirect, ...)
	self:assertFalse(success)
end

function suite:testInvalidInput()
	self:assertError()
	self:assertError(9)
	self:assertError(true)
	self:assertError('REDIRECT', 'invalid')
	self:assertError('REDIRECT', 'invalid', {})
	self:assertError('REDIRECT', nil, 'invalid')
	self:assertError('REDIRECT', {}, 'invalid')
end

function suite:testLuaRedirectOnly()
	local result = _redirect({'REDIRECT'})
	self:assertStringContains('"REDIRECT" redirects here. For other uses, see [[:REDIRECT (disambiguation)]].', result, true)
end

function suite:testLuaPage1()
	local result = _redirect(
		{'REDIRECT', 'USE1', 'PAGE1'},
		1
	)
	self:assertStringContains('"REDIRECT" redirects here. For USE1, see [[:PAGE1]].', result, true)
end

function suite:testLuaPage3()
	local result = _redirect(
		{'REDIRECT', 'USE1', 'PAGE1', 'USE2', 'PAGE2', 'USE3', 'PAGE3'},
		1
	)
	self:assertStringContains('"REDIRECT" redirects here. For USE1, see [[:PAGE1]]. For USE2, see [[:PAGE2]]. For USE3, see [[:PAGE3]].', result, true)
end

function suite:testLuaMultiplePages()
	local result = _redirect(
		{'REDIRECT', 'USE1', 'PAGE1', 'and', 'PAGE2', 'and', 'PAGE3', 'USE2', 'PAGE4', 'and', 'PAGE5'},
		1
	)
	self:assertStringContains('"REDIRECT" redirects here. For USE1, see [[:PAGE1]], [[:PAGE2]], and [[:PAGE3]]. For USE2, see [[:PAGE4]] and [[:PAGE5]].', result, true)
end

function suite:testLuaSelfref()
	local result = _redirect({'REDIRECT'}, 1, {selfref = true})
	self:assertStringContains('class=".-selfref.-"', result, false)
end

--------------------------------------------------------------------------------
-- Test tracking category
--------------------------------------------------------------------------------

function suite.makeFakeTitleObject(page, vals)
	local title
	if page then
		title = mw.title.new(page)
	else
		title = mw.title.getCurrentTitle()
	end
	for k, v in pairs(vals or {}) do
		rawset(title, k, v)
	end
	return title
end

local d = {}

-- Categories
d.missingCat = 'Missing redirects'
d.invalidCat = 'Articles with redirect hatnotes needing review'

function suite:assertContainsTrackingCategory(category, result)
	category = string.format('[[Category:%s]]', category)
	self:assertStringContains(category, result, true)
end

function suite:assertNotContainsTrackingCategory(result)
	self:assertNotStringContains('%[%[Category:[^%]]+%]%]', result)
end

function suite:testTrackingCategoryNonMainspace()
	local currentTitle = suite.makeFakeTitleObject('Wikipedia:Namespaces')
	suite:assertNotContainsTrackingCategory(_redirect({'Example'}, nil, nil, currentTitle))
end

function suite:testTrackingCategoryExceptions()
	local currentTitle = suite.makeFakeTitleObject('Example')
	for _, s in ipairs{'REDIRECT', 'REDIRECT1', 'REDIRECT1678', 'TERM'} do
		self:assertNotContainsTrackingCategory(_redirect({s}, nil, nil, currentTitle))
	end
end

function suite:testTrackingCategoryInvalidTitle()
	local currentTitle = suite.makeFakeTitleObject('Example')
	self:assertContainsTrackingCategory(d.missingCat, _redirect({'Exam<>ple 2'}, nil, nil, currentTitle))
end

function suite:testTrackingCategoryNonexistent()
	local currentTitle = suite.makeFakeTitleObject('Example')
	local redirectTitle = suite.makeFakeTitleObject('Example 2', {exists = false, isRedirect = false})
	self:assertContainsTrackingCategory(d.missingCat, _redirect({redirectTitle.prefixedText}, nil, nil, currentTitle, redirectTitle))
end

function suite:testTrackingCategoryNotRedirect()
	local currentTitle = suite.makeFakeTitleObject('Example')
	local redirectTitle = suite.makeFakeTitleObject('Example 2', {exists = true, isRedirect = false, getContent = function ()
		return 'Not a redirect!'
	end})
	self:assertContainsTrackingCategory(d.invalidCat, _redirect({redirectTitle.prefixedText}, nil, nil, currentTitle, redirectTitle))
end

function suite:testTrackingCategoryRfDRedirect()
	local currentTitle = suite.makeFakeTitleObject('Example')
	local redirectTitle = suite.makeFakeTitleObject('Example 2', {exists = true, isRedirect = false, getContent = function ()
		return [====[
{{<includeonly>safesubst:</includeonly>#invoke:RfD||
|month = April
|day = 14
|year = 2021
|time = 15:27
|timestamp = 20210414152704
<!-- The above content is generated by {{subst:rfd}}. -->
<!-- End of RFD message. Don't edit anything above here, but feel free to edit below here. -->|content=
#REDIRECT [[Example]]
<!-- Don't add anything after this line unless you're drafting a disambiguation page or article to replace the redirect. -->
}}
	]====] end})
	self:assertNotContainsTrackingCategory(d.invalidCat, _redirect({redirectTitle.prefixedText}, nil, nil, currentTitle, redirectTitle))
end

function suite:testTrackingCategoryWrongTarget()
	local currentTitle = suite.makeFakeTitleObject('Example')
	local redirectTitle = suite.makeFakeTitleObject('Example 2', {exists = true, isRedirect = true, getContent = function ()
		return '#REDIRECT [[Example 3]]' -- This is to fool Module:Redirect.
	end})
	local targetTitle = suite.makeFakeTitleObject('Example 3')
	self:assertContainsTrackingCategory(d.invalidCat, _redirect({redirectTitle.prefixedText}, nil, nil, currentTitle, redirectTitle, targetTitle))
end

function suite:testTrackingCategoryCorrectTarget()
	local currentTitle = suite.makeFakeTitleObject('Example')
	local redirectTitle = suite.makeFakeTitleObject('Example 2', {exists = true, isRedirect = true, getContent = function ()
		return '#REDIRECT [[Example]]' -- This is to fool Module:Redirect.
	end})
	local targetTitle = suite.makeFakeTitleObject('Example')
	self:assertNotContainsTrackingCategory(_redirect({redirectTitle.prefixedText}, nil, nil, currentTitle, redirectTitle, targetTitle))
end

return suite