From Wikipedia, the free encyclopedia

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