Module:Date table sorting/testcases

From blackwiki
< Module:Date table sorting
Revision as of 03:53, 4 July 2015 by blackwiki>Mr. Stradivarius (all broken dates that needed to be handled have been handled, so remove the comment)
Jump to navigation Jump to search

Documentation for this module may be created at Module:Date table sorting/testcases/doc

local mDts = require('Module:Dts') -- 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 style="white%-space:nowrap">[^<>]-</span>$'
suite.offValues = {'off', 'no', 'NO', 'n', 'false', false}
suite.onValues = {'on', 'yes', 'YES', 'y', 'true', true}
suite.methodFragments = {'Equals', 'StringContains', 'NotStringContains'}

for i, fragment in ipairs(suite.methodFragments) do
	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

function suite:assertErrorContains(pattern, func, plain)
	local success, msg = pcall(func)
	self:assertStringContains(pattern, msg, plain)
	self:assertFalse(success)
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 -9999',
		function ()
			Dts.new{-10000}
		end,
		true -- plain match
	)
end

function suite:testYearHighRangeError()
	self:assertErrorContains('years cannot be greater than 9999', function ()
		Dts.new{10000}
	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('02000-05-27-0000', {2000, 5, 27})
	suite:assertSortKeyEquals('02000-01-27-0000', {2000, 1, 27})
	suite:assertSortKeyEquals('02000-01-01-0000', {2000, 1, 1})
	suite:assertSortKeyEquals('00001-01-01-0000', {1, 1, 1})
end

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

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

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

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

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

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

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

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

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

function suite:testAddkey()
	suite:assertSortKeyEquals('02000-05-27-0003', {2000, 5, 27, addkey = 3})
	suite:assertSortKeyEquals('02000-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

-------------------------------------------------------------------------------
-- BC year tests
-------------------------------------------------------------------------------

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

-------------------------------------------------------------------------------
-- Format 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

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

function suite:testBlank()
	self:assertStringContains(
		'^<span class="sortkey" style="display:none;speak:none">[^<>]-</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 class="sortkey" style="display:none;speak:none">.-</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:Dts%]%]: .-</strong>' ..
		'%[%[Category:Dts templates with errors%]%]$'
	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