Module:Date table sorting/testcases

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 = '^]-" style="white%-space:nowrap">[^<>]- $'

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 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 BC', {-2000, 1, 27}) end

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

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

--- -- Blank tests ---

function suite:testBlank self:assertStringContains(		'^]-"> $',		mDts._main{}	) end

--- -- Nowrap tests ---

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

function suite:testNoWrapOff self:assertStringContainsWhenOff(		'^]-">[^>]- $',		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 = '^ Error in %[%[Template:Date table sorting%]%]: .- ' 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