Toggle menu
15
236
75
27.6K
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:Date table sorting



local mDts = require('Module:Date table sorting/sandbox') -- the module to be tested
local Dts = mDts._exportClasses().Dts -- the Dts class
local ScribuntoUnit = require('Module:ScribuntoUnit')
local suite = ScribuntoUnit:new()

-------------------------------------------------------------------------------
-- Helper functions and values
-------------------------------------------------------------------------------

suite.currentYear = os.date('*t').year
suite.nowrapPattern = '^<span data%-sort%-value="[^"<>]-" style="white%-space:nowrap">[^<>]-</span>$'

suite.offValues = {'off', 'no', 'NO', 'n', 'false', false}
suite.onValues = {'on', 'yes', 'YES', 'y', 'true', true}
local function makeOnOffAsserts(fragment)
	suite['assert' .. fragment .. 'WhenOn'] = function (self, first, func, ...)
		for i, on in ipairs(suite.onValues) do
			self['assert' .. fragment](self, first, func(on), ...)
		end
	end
	suite['assert' .. fragment .. 'WhenOff'] = function (self, first, func, ...)
		for i, off in ipairs(suite.offValues) do
			self['assert' .. fragment](self, first, func(off), ...)
		end
	end
end
makeOnOffAsserts('Equals')
makeOnOffAsserts('StringContains')
makeOnOffAsserts('NotStringContains')

function suite:assertErrorContains(pattern, func, plain)
	local success, msg = pcall(func)
	self:assertFalse(success)
	self:assertStringContains(pattern, msg, plain)
end

function suite:assertDateEquals(year, month, day, args)
	local dtsObj = Dts.new(args)
	self:assertEquals(year, dtsObj.year)
	self:assertEquals(month, dtsObj.month)
	self:assertEquals(day, dtsObj.day)
end

function suite:assertSortKeyEquals(expected, args)
	local dtsObj = Dts.new(args)
	self:assertEquals(expected, dtsObj:makeSortKey())
end

function suite:assertDisplayEquals(expected, args)
	local dtsObj = Dts.new(args)
	self:assertEquals(expected, dtsObj:makeDisplay())
end

-------------------------------------------------------------------------------
-- Date parameter tests
-------------------------------------------------------------------------------

function suite:testDateYMD()
	self:assertDateEquals(2000, 1, 27, {2000, 1, 27})
end

function suite:testDateYMonthD()
	self:assertDateEquals(2000, 1, 27, {2000, 'January', 27})
	self:assertDateEquals(2000, 1, 27, {2000, 'january', 27})
end

function suite:testDateYMonD()
	self:assertDateEquals(2000, 1, 27, {2000, 'Jan', 27})
	self:assertDateEquals(2000, 1, 27, {2000, 'jan', 27})
end

function suite:testDateYM()
	self:assertDateEquals(2000, 1, nil, {2000, 1})
end

function suite:testDateYD()
	self:assertDateEquals(2000, nil, 27, {2000, nil, 27})
end

function suite:testDateMD()
	self:assertDateEquals(nil, 1, 27, {nil, 1, 27})
end

function suite:testDateY()
	self:assertDateEquals(2000, nil, nil, {2000})
end

function suite:testDateM()
	self:assertDateEquals(nil, 1, nil, {nil, 1})
end

function suite:testDateD()
	self:assertDateEquals(nil, nil, 27, {nil, nil, 27})
end

function suite:testDateNegativeYear()
	self:assertDateEquals(-2000, 1, 27, {-2000, 1, 27})
end

function suite:testDateString()
	self:assertDateEquals(2000, 1, 27, {'2000', '1', '27'})
end

function suite:testDateAllMonths()
	self:assertDateEquals(nil, 1, nil, {nil, 'January', nil})
	self:assertDateEquals(nil, 2, nil, {nil, 'February', nil})
	self:assertDateEquals(nil, 3, nil, {nil, 'March', nil})
	self:assertDateEquals(nil, 4, nil, {nil, 'April', nil})
	self:assertDateEquals(nil, 5, nil, {nil, 'May', nil})
	self:assertDateEquals(nil, 6, nil, {nil, 'June', nil})
	self:assertDateEquals(nil, 7, nil, {nil, 'July', nil})
	self:assertDateEquals(nil, 8, nil, {nil, 'August', nil})
	self:assertDateEquals(nil, 9, nil, {nil, 'September', nil})
	self:assertDateEquals(nil, 10, nil, {nil, 'October', nil})
	self:assertDateEquals(nil, 11, nil, {nil, 'November', nil})
	self:assertDateEquals(nil, 12, nil, {nil, 'December', nil})
end

function suite:testDateAllMons()
	self:assertDateEquals(nil, 1, nil, {nil, 'Jan', nil})
	self:assertDateEquals(nil, 2, nil, {nil, 'Feb', nil})
	self:assertDateEquals(nil, 3, nil, {nil, 'Mar', nil})
	self:assertDateEquals(nil, 4, nil, {nil, 'Apr', nil})
	self:assertDateEquals(nil, 5, nil, {nil, 'May', nil})
	self:assertDateEquals(nil, 6, nil, {nil, 'Jun', nil})
	self:assertDateEquals(nil, 7, nil, {nil, 'Jul', nil})
	self:assertDateEquals(nil, 8, nil, {nil, 'Aug', nil})
	self:assertDateEquals(nil, 9, nil, {nil, 'Sep', nil})
	self:assertDateEquals(nil, 10, nil, {nil, 'Oct', nil})
	self:assertDateEquals(nil, 11, nil, {nil, 'Nov', nil})
	self:assertDateEquals(nil, 12, nil, {nil, 'Dec', nil})
end

-------------------------------------------------------------------------------
-- parseDate tests
-------------------------------------------------------------------------------

function suite:testParseYear()
	self:assertDateEquals(2000, nil, nil, {'2000'})
end

function suite:testParseNegativeYear()
	self:assertDateEquals(-2000, nil, nil, {'-2000'})
end

function suite:testParseSmallYear()
	self:assertDateEquals(12, nil, nil, {'12'})
end

function suite:testParseYYYYMMDD()
	self:assertDateEquals(2000, 1, 27, {'2000-01-27'})
	self:assertDateEquals(2000, 1, 27, {'2000-1-27'})
	self:assertDateEquals(2000, 1, 6, {'2000-01-06'})
	self:assertDateEquals(2000, 1, 6, {'2000-01-06'})
end

function suite:testParseDDMMYYYY()
	self:assertDateEquals(2000, 1, 27, {'27-01-2000'})
	self:assertDateEquals(2000, 1, 27, {'27-1-2000'})
	self:assertDateEquals(2000, 1, 6, {'06-01-2000'})
end

function suite:testParseYYYYMM()
	self:assertDateEquals(2000, 1, nil, {'2000-01'})
	self:assertDateEquals(2000, 1, nil, {'2000-1'})
end

function suite:testParseMonthYYYY()
	self:assertDateEquals(1418, 2, nil, {'February 1418'})
end

function suite:testParseMonYYYY()
	self:assertDateEquals(1418, 2, nil, {'Feb 1418'})
end

function suite:testParseDDMonthYYYY()
	self:assertDateEquals(1975, 4, 24, {'24 April 1975'})
end

function suite:testParseDDMonYYYY()
	self:assertDateEquals(1975, 4, 24, {'24 Apr 1975'})
end

function suite:testParseMonthDDYYYY()
	self:assertDateEquals(1975, 4, 24, {'April 24, 1975'})
	self:assertDateEquals(1975, 4, 24, {'April 24 1975'})
end

function suite:testParseMonDDYYYY()
	self:assertDateEquals(1975, 4, 24, {'Apr 24, 1975'})
	self:assertDateEquals(1975, 4, 24, {'Apr 24 1975'})
end

function suite:testParseMonth()
	self:assertDateEquals(nil, 4, nil, {'April'})
	self:assertDateEquals(nil, 4, nil, {'april'})
end

function suite:testParseMon()
	self:assertDateEquals(nil, 4, nil, {'Apr'})
	self:assertDateEquals(nil, 4, nil, {'apr'})
end

function suite:testParseDDMonth()
	self:assertDateEquals(nil, 11, 12, {'12 November'})
end

function suite:testParseDDMon()
	self:assertDateEquals(nil, 11, 12, {'12 Nov'})
end

function suite:testParseMonthDD()
	self:assertDateEquals(nil, 11, 12, {'November 12'})
end

function suite:testParseMonDD()
	self:assertDateEquals(nil, 11, 12, {'Nov 12'})
end

function suite:testParseDDMonthYYY()
	self:assertDateEquals(100, 1, 27, {'27 January 100'})
end

function suite:testParseDDMonth0YYY()
	self:assertDateEquals(100, 1, 27, {'27 January 0100'})
end

function suite:testParseDDMonth000Y()
	self:assertDateEquals(3, 1, 27, {'27 January 0003'})
end

function suite:testParseAllMonths()
	self:assertDateEquals(nil, 1, nil, {'January'})
	self:assertDateEquals(nil, 2, nil, {'February'})
	self:assertDateEquals(nil, 3, nil, {'March'})
	self:assertDateEquals(nil, 4, nil, {'April'})
	self:assertDateEquals(nil, 5, nil, {'May'})
	self:assertDateEquals(nil, 6, nil, {'June'})
	self:assertDateEquals(nil, 7, nil, {'July'})
	self:assertDateEquals(nil, 8, nil, {'August'})
	self:assertDateEquals(nil, 9, nil, {'September'})
	self:assertDateEquals(nil, 10, nil, {'October'})
	self:assertDateEquals(nil, 11, nil, {'November'})
	self:assertDateEquals(nil, 12, nil, {'December'})
end

function suite:testParseAllMons()
	self:assertDateEquals(nil, 1, nil, {'Jan'})
	self:assertDateEquals(nil, 2, nil, {'Feb'})
	self:assertDateEquals(nil, 3, nil, {'Mar'})
	self:assertDateEquals(nil, 4, nil, {'Apr'})
	self:assertDateEquals(nil, 5, nil, {'May'})
	self:assertDateEquals(nil, 6, nil, {'Jun'})
	self:assertDateEquals(nil, 7, nil, {'Jul'})
	self:assertDateEquals(nil, 8, nil, {'Aug'})
	self:assertDateEquals(nil, 9, nil, {'Sep'})
	self:assertDateEquals(nil, 10, nil, {'Oct'})
	self:assertDateEquals(nil, 11, nil, {'Nov'})
	self:assertDateEquals(nil, 12, nil, {'Dec'})
end

function suite:testParseSept()
	self:assertDateEquals(nil, 9, nil, {'Sept'})
	self:assertDateEquals(nil, 9, nil, {'sept'})
	self:assertDateEquals(2012, 9, 1, {'1 Sept 2012'})
	self:assertDateEquals(2012, 9, 1, {2012, 'Sept', 1})
end

-------------------------------------------------------------------------------
-- Date error tests
-------------------------------------------------------------------------------

function suite:testInvalidDateError()
	self:assertErrorContains("'foo' is an invalid date", function ()
		Dts.new{'foo'}
	end)
end

function suite:testZeroYearError()
	self:assertErrorContains('years cannot be zero', function ()
		Dts.new{0}
	end)
end

function suite:testYearNonIntegerError()
	self:assertErrorContains('years must be an integer', function ()
		Dts.new{2015.5}
	end)
end

function suite:testYearLowRangeError()
	self:assertErrorContains(
		'years cannot be less than −999,999,999,999',
		function ()
			Dts.new{-1000000000000}
		end,
		true -- plain match
	)
end

function suite:testYearHighRangeError()
	self:assertErrorContains('years cannot be greater than 999,999,999,999', function ()
		Dts.new{1000000000000}
	end)
end

function suite:testMonthError()
	self:assertErrorContains('months must be an integer between 1 and 12', function ()
		Dts.new{2000, 0}
	end)
	self:assertErrorContains('months must be an integer between 1 and 12', function ()
		Dts.new{2000, 13}
	end)
end

function suite:testDayError()
	self:assertErrorContains('days must be an integer between 1 and 31', function ()
		Dts.new{2000, 1, 0}
	end)
	self:assertErrorContains('days must be an integer between 1 and 31', function ()
		Dts.new{2000, 1, 32}
	end)
end

function suite:testBCError()
	self:assertErrorContains(
		"'foo' is not a valid era code (expected 'BC', 'BCE', 'AD' or 'CE')",
		function ()
			Dts.new{2000, 1, 27, 'foo'}
		end,
		true -- plain match
	)
end

-------------------------------------------------------------------------------
-- Sort key tests
-------------------------------------------------------------------------------

function suite:testSortKeyYMD()
	suite:assertSortKeyEquals('000000002000-05-27-0000', {2000, 5, 27})
	suite:assertSortKeyEquals('000000002000-01-27-0000', {2000, 1, 27})
	suite:assertSortKeyEquals('000000002000-01-01-0000', {2000, 1, 1})
	suite:assertSortKeyEquals('000000000001-01-01-0000', {1, 1, 1})
end

function suite:testSortKeyYM()
	suite:assertSortKeyEquals('000000002000-05-01-0000', {2000, 5, nil})
end

function suite:testSortKeyYD()
	suite:assertSortKeyEquals('000000002000-01-27-0000', {2000, nil, 27})
end

function suite:testSortKeyMD()
	suite:assertSortKeyEquals('00000000' .. suite.currentYear .. '-05-27-0000', {nil, 5, 27})
end

function suite:testSortKeyY()
	suite:assertSortKeyEquals('000000002000-01-01-0000', {2000, nil, nil})
end

function suite:testSortKeyM()
	suite:assertSortKeyEquals('00000000' .. suite.currentYear .. '-05-01-0000', {nil, 5, nil})
end

function suite:testSortKeyD()
	suite:assertSortKeyEquals('00000000' .. suite.currentYear .. '-01-27-0000', {nil, nil, 27})
end

function suite:testSortKeyNegative()
	suite:assertSortKeyEquals('-999999999955-05-27-0000', {-45, 5, 27})
end

function suite:testSortKeyMaxYear()
	suite:assertSortKeyEquals('999999999999-01-01-0000', {999999999999})
end

function suite:testSortKeyMinYear()
	suite:assertSortKeyEquals('-000000000001-01-01-0000', {-999999999999})
end

function suite:testSortKeyBlank()
	suite:assertSortKeyEquals('999999999999-99-99-0000', {})
end

-------------------------------------------------------------------------------
-- addkey tests
-------------------------------------------------------------------------------

function suite:testAddkey()
	suite:assertSortKeyEquals('000000002000-05-27-0003', {2000, 5, 27, addkey = 3})
	suite:assertSortKeyEquals('000000002000-05-27-0003', {2000, 5, 27, addkey = '3'})
end

function suite:testAddkeyError()
	local msg = "the 'addkey' parameter must be an integer between 0 and 9999"
	self:assertErrorContains(msg, function ()
		Dts.new{2000, 5, 27, addkey = 3.5}
	end)
	self:assertErrorContains(msg, function ()
		Dts.new{2000, 5, 27, addkey = -1}
	end)
	self:assertErrorContains(msg, function ()
		Dts.new{2000, 5, 27, addkey = 10000}
	end)
end

-------------------------------------------------------------------------------
-- Display tests
-------------------------------------------------------------------------------

function suite:testFormatDefault()
	suite:assertDisplayEquals('January 27, 2000', {2000, 1, 27})
end

function suite:testFormatDMY()
	suite:assertDisplayEquals('27 January 2000', {2000, 1, 27, format = 'dmy'})
end

function suite:testFormatMDY()
	suite:assertDisplayEquals('January 27, 2000', {2000, 1, 27, format = 'mdy'})
end

function suite:testFormatDM()
	suite:assertDisplayEquals('27 January', {2000, 1, 27, format = 'dm'})
end

function suite:testFormatMD()
	suite:assertDisplayEquals('January 27', {2000, 1, 27, format = 'md'})
end

function suite:testFormatMY()
	suite:assertDisplayEquals('January 2000', {2000, 1, 27, format = 'my'})
end

function suite:testFormatY()
	suite:assertDisplayEquals('2000', {2000, 1, 27, format = 'y'})
end

function suite:testFormatM()
	suite:assertDisplayEquals('January', {2000, 1, 27, format = 'm'})
end

function suite:testFormatD()
	suite:assertDisplayEquals('27', {2000, 1, 27, format = 'd'})
end

function suite:testFormatHide()
	suite:assertDisplayEquals('', {2000, 1, 27, format = 'hide'})
end

function suite:testBCParam()
	local result = 'January 27, 2000&nbsp;BC'
	suite:assertDisplayEquals(result, {2000, 1, 27, 'BC'})
	suite:assertDisplayEquals(result, {2000, 1, 27, 'BCE'})
	suite:assertDisplayEquals(result, {2000, 1, 27, 'bc'})
	suite:assertDisplayEquals(result, {2000, 1, 27, 'bce'})
end

function suite:testBCNegativeYear()
	suite:assertDisplayEquals('January 27, 2000&nbsp;BC', {-2000, 1, 27})
end

function suite:testLargeYearDisplay()
	suite:assertDisplayEquals('1,000,000', {1000000})
end

function suite:testLargeNegativeYearDisplay()
	suite:assertDisplayEquals('1,000,000&nbsp;BC', {-1000000})
end

-------------------------------------------------------------------------------
-- Blank tests
-------------------------------------------------------------------------------

function suite:testBlank()
	self:assertStringContains(
		'^<span data%-sort%-value="[^"<>]-"></span>$',
		mDts._main{}
	)
end

-------------------------------------------------------------------------------
-- Nowrap tests
-------------------------------------------------------------------------------

function suite:testNoWrapDefault()
	self:assertStringContains(
		self.nowrapPattern,		
		mDts._main{2000, 1, 1}
	)
end

function suite:testNoWrapOff()
	self:assertStringContainsWhenOff(
		'^<span data%-sort%-value="[^"<>]-">[^>]-</span>$',
		function (off)
			return mDts._main{2000, 1, 1, nowrap = off}
		end
	)
	self:assertNotStringContainsWhenOff(
		'white%-space%s*:%s*nowrap',
		function (off)
			return mDts._main{2000, 1, 1, nowrap = off}
		end
	)
end

function suite:testNoWrapOn()
	self:assertStringContainsWhenOn(
		self.nowrapPattern,
		function (on)
			return mDts._main{2000, 1, 1, nowrap = on}
		end
	)
end

-------------------------------------------------------------------------------
-- Abbr tests
-------------------------------------------------------------------------------

function suite:testAbbrDefault()
	self:assertStringContains(
		'January 1, 2000',
		mDts._main{2000, 1, 1}
	)
end

function suite:testAbbrOn()
	self:assertStringContainsWhenOn(
		'Jan 1, 2000',
		function (on)
			return mDts._main{2000, 1, 1, abbr = on}
		end
	)
end

function suite:testAbbrOff()
	self:assertStringContainsWhenOff(
		'January 1, 2000',
		function (off)
			return mDts._main{2000, 1, 1, abbr = off}
		end
	)
end

-------------------------------------------------------------------------------
-- Main tests
-------------------------------------------------------------------------------

function suite:testMain()
	local errorPattern = '^<strong class="error">Error in %[%[Template:Date table sorting%]%]: .-</strong>'
	self:assertStringContains(errorPattern, mDts.main{'foo'})
	self:assertNotStringContains(errorPattern, mDts.main{2000})
	self:assertStringContains(errorPattern, mDts._main{'foo'})
	self:assertNotStringContains(errorPattern, mDts._main{2000})
end

return suite