Module:Date time/testcases

-- Unit tests for [[Module:Date time]]. Click talk page to run tests.
local p = require('Module:UnitTests')

local DateTime = require('Module:Date time/sandbox')
local ERROR_MESSAGES = DateTime.ERROR_MESSAGES

local function getErrorMessage(message, template, invalid)
	if not template then
		template = "start date"
	end

	local category = "[[Category:Pages using Module:Date time with invalid values]]"
	if invalid then
		category = ""
	end

	return string.format('<strong class="error">Error: %s</strong> <small>[[:Template:%s|(help)]]</small>%s', message, template, category)
end

local function getPresentDate()
	local lang = mw.language.getContentLanguage()
	return lang:formatDate("Y-m-d")
end

function p:test_01_valid()
	self:preprocess_equals_sandbox_many('{{#invoke:Date time', 'validate_date_time', {
		{'1999', ''}, -- only year
		{'1999|2', ''}, -- year and month
		{'1999|02|1', ''}, -- year, month, and day
		{'1999|02|01|5', ''}, -- year, month, day, hour
		{'1999|02|01|5|3', ''}, -- year, month, day, hour, minute
		{'1999|02|01|5|3|2', ''}, -- year, month, day, hour, minute, second
	}, {nowiki=1})
end

function p:test_02_min_max_values()
	self:preprocess_equals_sandbox_many('{{#invoke:Date time', 'validate_date_time', {
		{'1999|1', ''}, -- month min value
		{'1999|12', ''}, -- month max value
		{'1999|02|01|00', ''}, -- hour min value
		{'1999|02|01|23', ''}, -- hour max value
		{'1999|02|01|00|00', ''}, -- minute min value
		{'1999|02|01|23|59', ''}, -- minute max value
		{'1999|02|01|00|00', ''}, -- second min value
		{'1999|02|01|23|59', ''}, -- second max value
		{'1999|1|31', ''},
		{'1999|2|28', ''},
		{'1999|3|31', ''},
		{'1999|4|30', ''},
		{'1999|5|31', ''},
		{'1999|6|30', ''},
		{'1999|7|31', ''},
		{'1999|8|31', ''},
		{'1999|9|30', ''},
		{'1999|10|31', ''},
		{'1999|11|30', ''},
		{'1999|12|31', ''},
	}, {nowiki=1})
end

function p:test_03_leap_year()
	self:preprocess_equals_sandbox_many('{{#invoke:Date time', 'validate_date_time', {
		{'2000|02|29', ''},
	}, {nowiki=1})
end

function p:test_04_leading_zeros()
	self:preprocess_equals_sandbox_many('{{#invoke:Date time', 'validate_date_time', {
		{'1999|02', ''}, -- month
		{'1999|02|01', ''}, -- day
		{'1999|02|01|05', ''}, -- hour
		{'1999|02|01|05|05', ''}, -- minute
		{'1999|02|01|05|05|05', ''}, -- second
	}, {nowiki=1})
end

function p:test_05_timezone()
	self:preprocess_equals_sandbox_many('{{#invoke:Date time', 'validate_date_time', {
		{'2000|02|01|10|||Z', ''},
		
		-- full time
		{'2000|02|01|10|||−12:00', ''}, -- Latest time zone
		{'2000|02|01|10|||−02:30', ''},
		{'2000|02|01|10|||−02:00', ''},
		{'2000|02|01|10|||−01:30', ''},
		{'2000|02|01|10|||−01:00', ''},			
		{'2000|02|01|10|||+00:00', ''},
		{'2000|02|01|10|||+01:00', ''},
		{'2000|02|01|10|||+01:30', ''},
		{'2000|02|01|10|||+14:00', ''}, -- Earliest time zone
		
		-- no minutes
		{'2000|02|01|10|||−12', ''}, -- Latest time zone
		{'2000|02|01|10|||−02', ''},
		{'2000|02|01|10|||−01', ''},	
		{'2000|02|01|10|||+00', ''},
		{'2000|02|01|10|||+01', ''},
		{'2000|02|01|10|||+14', ''}, -- Earliest time zone
		
		-- missing leading zero
		{'2000|02|01|10|||−2:30', ''},
		{'2000|02|01|10|||−2:00', ''},
		{'2000|02|01|10|||−1:30', ''},
		{'2000|02|01|10|||−1:00', ''},	
		{'2000|02|01|10|||+0:00', ''},
		{'2000|02|01|10|||+1:00', ''},

		-- ASCII hyphen	
		{'2000|02|01|10|||-12:00', ''},
		{'2000|02|01|10|||-12', ''},
		{'2000|02|01|10|||-01:30', ''},
		{'2000|02|01|10|||-1:30', ''},
		{'2000|02|01|10|||-01:00', ''},
		{'2000|02|01|10|||-1:00', ''},
	}, {nowiki=1})
end

function p:test_06_df()
	self:preprocess_equals_sandbox_many('{{#invoke:Date time', 'validate_date_time', {
		{'2000|02|29|df=yes', ''},
		{'2000|02|29|df=y', ''},
	}, {nowiki=1})
end

function p:test_09_errors()
	self:preprocess_equals_sandbox_many('{{#invoke:Date time', 'validate_date_time', {
		-- No values
		{'', getErrorMessage(ERROR_MESSAGES.missing_year)},

		 -- Year and day, no month
		{'1999|3=20', getErrorMessage(ERROR_MESSAGES.missing_month)},

		-- Month outside range
		{'1999|-1', getErrorMessage(ERROR_MESSAGES.invalid_month)},
		{'1999|13', getErrorMessage(ERROR_MESSAGES.invalid_month)},

		-- Days outside range
		{'1999|01|-1', getErrorMessage(string.format(ERROR_MESSAGES.invalid_day, "1", "31"))},

		-- More days than in a given month
		{'1999|1|32', getErrorMessage(string.format(ERROR_MESSAGES.invalid_day, "1", "31"))},
		{'1999|2|29', getErrorMessage(string.format(ERROR_MESSAGES.invalid_day, "2", "28"))},
		{'1999|3|32', getErrorMessage(string.format(ERROR_MESSAGES.invalid_day, "3", "31"))},
		{'1999|4|31', getErrorMessage(string.format(ERROR_MESSAGES.invalid_day, "4", "30"))},
		{'1999|5|32', getErrorMessage(string.format(ERROR_MESSAGES.invalid_day, "5", "31"))},
		{'1999|6|31', getErrorMessage(string.format(ERROR_MESSAGES.invalid_day, "6", "30"))},
		{'1999|7|32', getErrorMessage(string.format(ERROR_MESSAGES.invalid_day, "7", "31"))},
		{'1999|8|32', getErrorMessage(string.format(ERROR_MESSAGES.invalid_day, "8", "31"))},
		{'1999|9|31', getErrorMessage(string.format(ERROR_MESSAGES.invalid_day, "9", "30"))},
		{'1999|10|32', getErrorMessage(string.format(ERROR_MESSAGES.invalid_day, "10", "31"))},
		{'1999|11|31', getErrorMessage(string.format(ERROR_MESSAGES.invalid_day, "11", "30"))},
		{'1999|12|32', getErrorMessage(string.format(ERROR_MESSAGES.invalid_day, "12", "31"))},

		-- Too many leading zeros
		{'1999|010', getErrorMessage(ERROR_MESSAGES.has_leading_zeros)}, 
		{'1999|1|020', getErrorMessage(ERROR_MESSAGES.has_leading_zeros)},
		{'1999|1|2|010', getErrorMessage(ERROR_MESSAGES.has_leading_zeros)},
		{'1999|1|2|1|023', getErrorMessage(ERROR_MESSAGES.has_leading_zeros)},
		{'1999|1|2|1|2|033', getErrorMessage(ERROR_MESSAGES.has_leading_zeros)},
		{'1999|001', getErrorMessage(ERROR_MESSAGES.has_leading_zeros)},
		{'1999|1|002', getErrorMessage(ERROR_MESSAGES.has_leading_zeros)},
		{'1999|1|2|001', getErrorMessage(ERROR_MESSAGES.has_leading_zeros)},
		{'1999|1|2|3|002', getErrorMessage(ERROR_MESSAGES.has_leading_zeros)},
		{'1999|1|2|3|1|003', getErrorMessage(ERROR_MESSAGES.has_leading_zeros)},

		-- Time outside range
		{'1999|1|2|-1', getErrorMessage(ERROR_MESSAGES.invalid_hour)},
		{'1999|1|2|1|-2', getErrorMessage(ERROR_MESSAGES.invalid_minute)},
		{'1999|1|2|1|2|-3', getErrorMessage(ERROR_MESSAGES.invalid_second)},
		{'1999|1|2|25', getErrorMessage(ERROR_MESSAGES.invalid_hour)},
		{'1999|1|2|1|60', getErrorMessage(ERROR_MESSAGES.invalid_minute)},
		{'1999|1|2|1|2|60', getErrorMessage(ERROR_MESSAGES.invalid_second)},

		-- Time without an hour		
		{'1999|1|2||30', getErrorMessage(ERROR_MESSAGES.time_without_hour)},
		{'1999|1|2|||05', getErrorMessage(ERROR_MESSAGES.time_without_hour)},

		-- Timezone
		--- Matches "-12:00" to "+14:00"
		{'1999|1|2|1|2|59|-13:00', getErrorMessage(ERROR_MESSAGES.invalid_timezone)},
		{'1999|1|2|1|2|59|+15:00', getErrorMessage(ERROR_MESSAGES.invalid_timezone)},
		{'1999|1|2|1|2|59|-13', getErrorMessage(ERROR_MESSAGES.invalid_timezone)},
		{'1999|1|2|1|2|59|+15', getErrorMessage(ERROR_MESSAGES.invalid_timezone)},
		{'1999|1|2|1|2|59|-00:00', getErrorMessage(ERROR_MESSAGES.invalid_timezone)},
		{'1999|1|2|1|2|59|-00', getErrorMessage(ERROR_MESSAGES.invalid_timezone)},
		{'1999|1|2|1|2|59|ABC', getErrorMessage(ERROR_MESSAGES.invalid_timezone)},
		{'1999|1|2|1|2|59|05:00', getErrorMessage(ERROR_MESSAGES.invalid_timezone)},
		{'1999|1|2|1|2|59|005:00', getErrorMessage(ERROR_MESSAGES.invalid_timezone)},
		{'1999|1|2|1|2|59|05:000', getErrorMessage(ERROR_MESSAGES.invalid_timezone)},
		{'1999|1|2|1|2|59|05:00:00', getErrorMessage(ERROR_MESSAGES.invalid_timezone)},
		{'1999|1|2||||+04:00', getErrorMessage(ERROR_MESSAGES.timezone_incomplete_date)},

		-- Not integers
		{'abc|1|2', getErrorMessage(ERROR_MESSAGES.integers)},
		{'1999|abc|2', getErrorMessage(ERROR_MESSAGES.integers)},
		{'1999|2|abc', getErrorMessage(ERROR_MESSAGES.integers)},
		{'1999|2|3|abc', getErrorMessage(ERROR_MESSAGES.integers)},
		{'1999|2|3|4|abc', getErrorMessage(ERROR_MESSAGES.integers)},
		{'1999|2|3|4|5|abc', getErrorMessage(ERROR_MESSAGES.integers)},
		{'1999|1.5|2', getErrorMessage(ERROR_MESSAGES.integers)},
		{'1999|1|2.', getErrorMessage(ERROR_MESSAGES.integers)},

		-- Df validation
		{'2000|02|29|df=no', getErrorMessage(string.format(ERROR_MESSAGES.yes_value_parameter, "df"))},
		{'2000|02|29|df=Y', getErrorMessage(string.format(ERROR_MESSAGES.yes_value_parameter, "df"))},

		-- p validation
		{'2000|02|29|p=no', getErrorMessage(string.format(ERROR_MESSAGES.yes_value_parameter, "p"))},
		{'2000|02|29|p=Y', getErrorMessage(string.format(ERROR_MESSAGES.yes_value_parameter, "p"))},
		{'2000|02|29|paren=no', getErrorMessage(string.format(ERROR_MESSAGES.yes_value_parameter, "paren"))},
		{'2000|02|29|p=Y|paren=no', getErrorMessage(string.format(ERROR_MESSAGES.duplicate_parameters, "p", "paren"))},
		{'2000|02|29|p=y|paren=no', getErrorMessage(string.format(ERROR_MESSAGES.duplicate_parameters, "p", "paren"))},
		
		-- br validation
		{'2000|02|29|br=no', getErrorMessage(string.format(ERROR_MESSAGES.yes_value_parameter, "br"))},
		{'2000|02|29|br=Y', getErrorMessage(string.format(ERROR_MESSAGES.yes_value_parameter, "br"))},

	}, {nowiki=1})
end

function p:test_10_generate_date_valid_start_date()
	self:preprocess_equals_sandbox_many('{{#invoke:Date time', 'generate_date', {
		{'2000', '2000<span style="display: none;">&nbsp;(<span class="bday dtstart published updated itvstart">2000</span>)</span>'},
		{'2000|02', 'February&nbsp;2000<span style="display: none;">&nbsp;(<span class="bday dtstart published updated itvstart">2000-02</span>)</span>'},
		{'2000|02|29', 'February&nbsp;29,&nbsp;2000<span style="display: none;">&nbsp;(<span class="bday dtstart published updated itvstart">2000-02-29</span>)</span>'},
		{'2000|02|df=yes', 'February&nbsp;2000<span style="display: none;">&nbsp;(<span class="bday dtstart published updated itvstart">2000-02</span>)</span>'},
		{'2000|02|29|df=y', '29&nbsp;February&nbsp;2000<span style="display: none;">&nbsp;(<span class="bday dtstart published updated itvstart">2000-02-29</span>)</span>'},
		{'2000|02|29|11', '11:00,&#32;February&nbsp;29,&nbsp;2000<span style="display: none;">&nbsp;(<span class="bday dtstart published updated itvstart">2000-02-29T11:00:00</span>)</span>'},
		{'2000|02|29|11|5', '11:05,&#32;February&nbsp;29,&nbsp;2000<span style="display: none;">&nbsp;(<span class="bday dtstart published updated itvstart">2000-02-29T11:05:00</span>)</span>'},
		{'2000|02|29|11|5|29', '11:05:29,&#32;February&nbsp;29,&nbsp;2000<span style="display: none;">&nbsp;(<span class="bday dtstart published updated itvstart">2000-02-29T11:05:29</span>)</span>'},
		{'2000|02|29|11|5|29|Z', '11:05:29,&#32;February&nbsp;29,&nbsp;2000&#32;(UTC)<span style="display: none;">&nbsp;(<span class="bday dtstart published updated itvstart">2000-02-29T11:05:29Z</span>)</span>'},
		{'2000|02|29|11|5|29|+5:00', '11:05:29,&#32;February&nbsp;29,&nbsp;2000&#32;(+05:00)<span style="display: none;">&nbsp;(<span class="bday dtstart published updated itvstart">2000-02-29T11:05:29+05:00</span>)</span>'},
		{'2000|02|29|11|df=y', '11:00,&#32;29&nbsp;February&nbsp;2000<span style="display: none;">&nbsp;(<span class="bday dtstart published updated itvstart">2000-02-29T11:00:00</span>)</span>'},
		{'2000|02|29|11|5|df=y', '11:05,&#32;29&nbsp;February&nbsp;2000<span style="display: none;">&nbsp;(<span class="bday dtstart published updated itvstart">2000-02-29T11:05:00</span>)</span>'},
		{'2000|02|29|11|5|29|df=y', '11:05:29,&#32;29&nbsp;February&nbsp;2000<span style="display: none;">&nbsp;(<span class="bday dtstart published updated itvstart">2000-02-29T11:05:29</span>)</span>'},
		{'2000|02|29|11|5|29|Z|df=y', '11:05:29,&#32;29&nbsp;February&nbsp;2000&#32;(UTC)<span style="display: none;">&nbsp;(<span class="bday dtstart published updated itvstart">2000-02-29T11:05:29Z</span>)</span>'},
		{'2000|02|29|11|5|29|+5:00|df=y', '11:05:29,&#32;29&nbsp;February&nbsp;2000&#32;(+05:00)<span style="display: none;">&nbsp;(<span class="bday dtstart published updated itvstart">2000-02-29T11:05:29+05:00</span>)</span>'},
		{'2000|02|29|5|2|3|+5:00|df=y', '05:02:03,&#32;29&nbsp;February&nbsp;2000&#32;(+05:00)<span style="display: none;">&nbsp;(<span class="bday dtstart published updated itvstart">2000-02-29T05:02:03+05:00</span>)</span>'},
		{'2000|02|01|5|2|3|+5:00', '05:02:03,&#32;February&nbsp;1,&nbsp;2000&#32;(+05:00)<span style="display: none;">&nbsp;(<span class="bday dtstart published updated itvstart">2000-02-01T05:02:03+05:00</span>)</span>'},
		{'2000|02|01|5|2|3|+5:00|df=y', '05:02:03,&#32;1&nbsp;February&nbsp;2000&#32;(+05:00)<span style="display: none;">&nbsp;(<span class="bday dtstart published updated itvstart">2000-02-01T05:02:03+05:00</span>)</span>'},
		
		-- No padding zero
		{'2000|2', 'February&nbsp;2000<span style="display: none;">&nbsp;(<span class="bday dtstart published updated itvstart">2000-02</span>)</span>'},
		{'2000|2|1', 'February&nbsp;1,&nbsp;2000<span style="display: none;">&nbsp;(<span class="bday dtstart published updated itvstart">2000-02-01</span>)</span>'},
		{'2000|11', 'November&nbsp;2000<span style="display: none;">&nbsp;(<span class="bday dtstart published updated itvstart">2000-11</span>)</span>'},
		{'2000|11|30', 'November&nbsp;30,&nbsp;2000<span style="display: none;">&nbsp;(<span class="bday dtstart published updated itvstart">2000-11-30</span>)</span>'},
	}, {nowiki=1})
end

function p:test_11_generate_date_valid_end_date()
	self:preprocess_equals_sandbox_many('{{#invoke:Date time', 'generate_date|template=end date', {
		{'2000|02|29|11|5|29|+5:00', '11:05:29,&#32;February&nbsp;29,&nbsp;2000&#32;(+05:00)<span style="display: none;">&nbsp;(<span class="dtend itvend">2000-02-29T11:05:29+05:00</span>)</span>'},
		{'2000|02|29|11|5|29|+5:00|df=y', '11:05:29,&#32;29&nbsp;February&nbsp;2000&#32;(+05:00)<span style="display: none;">&nbsp;(<span class="dtend itvend">2000-02-29T11:05:29+05:00</span>)</span>'},
	}, {nowiki=1})
end

function p:test_12_generate_date_valid_date_display()
	self:preprocess_equals_sandbox_many('{{#invoke:Date time', 'generate_date', {
		{'2000|02|01|5|2|3|+5:00', '05:02:03,&#32;February&nbsp;1,&nbsp;2000&#32;(+05:00)<span style="display: none;">&nbsp;(<span class="bday dtstart published updated itvstart">2000-02-01T05:02:03+05:00</span>)</span>'},
		{'2000|02|01|5|2|3|+5:00|df=y', '05:02:03,&#32;1&nbsp;February&nbsp;2000&#32;(+05:00)<span style="display: none;">&nbsp;(<span class="bday dtstart published updated itvstart">2000-02-01T05:02:03+05:00</span>)</span>'},
		{'template=end date|2000|02|01|5|2|3|+5:00', '05:02:03,&#32;February&nbsp;1,&nbsp;2000&#32;(+05:00)<span style="display: none;">&nbsp;(<span class="dtend itvend">2000-02-01T05:02:03+05:00</span>)</span>'},
		{'template=end date|2000|02|01|5|2|3|+5:00|df=y', '05:02:03,&#32;1&nbsp;February&nbsp;2000&#32;(+05:00)<span style="display: none;">&nbsp;(<span class="dtend itvend">2000-02-01T05:02:03+05:00</span>)</span>'},
	})
end

function p:test_15_generate_date_invalid()
	self:preprocess_equals_sandbox_many('{{#invoke:Date time', 'generate_date', {
		-- Year required
		{'', getErrorMessage(ERROR_MESSAGES.missing_year)},
		{'|02', getErrorMessage(ERROR_MESSAGES.missing_year)},
		{'|02|29', getErrorMessage(ERROR_MESSAGES.missing_year)},
		{'|||11', getErrorMessage(ERROR_MESSAGES.missing_year)},
		{'|||11|5', getErrorMessage(ERROR_MESSAGES.missing_year)},
		{'|||11|5|29', getErrorMessage(ERROR_MESSAGES.missing_year)},
		{'|||11|5|29|Z', getErrorMessage(ERROR_MESSAGES.missing_year)},
		{'||||||Z', getErrorMessage(ERROR_MESSAGES.missing_year)},
		
		-- Timezone without a day and hour
		{'2000||||||Z', getErrorMessage(ERROR_MESSAGES.timezone_incomplete_date)},
		{'2000|5|||||Z', getErrorMessage(ERROR_MESSAGES.timezone_incomplete_date)},
		{'2000|5|6||||Z', getErrorMessage(ERROR_MESSAGES.timezone_incomplete_date)},
		{'2000|5|6||5||Z', getErrorMessage(ERROR_MESSAGES.time_without_hour)},
		{'2000|5|6||5|3|Z', getErrorMessage(ERROR_MESSAGES.time_without_hour)},
		
		-- Template not supported
		{'template=start date text|2000|02|29|11|5|29|+5:00|df=y', getErrorMessage("Template not supported", "start date text", true)},

	}, {nowiki=1})
end

function p:test_20_generate_start_date_age_valid()
	local yearsSince1999 = mw.language.getContentLanguage():formatDate("Y") - 1999
	self:preprocess_equals_sandbox_many('{{#invoke:Date time', 'generate_date|template=start date and age', {
		-- Standard
		{'1999', '1999<span class="noprint">;&#32;' .. yearsSince1999 .. ' years ago</span><span style="display: none;">&nbsp;(<span class="bday dtstart published updated">1999</span>)</span>'},
		{'1999|2', 'February&nbsp;1999<span class="noprint">;&#32;' .. yearsSince1999 .. ' years ago</span><span style="display: none;">&nbsp;(<span class="bday dtstart published updated">1999-02</span>)</span>'},
		{'1999|2|1', 'February&nbsp;1,&nbsp;1999<span class="noprint">;&#32;' .. yearsSince1999 .. ' years ago</span><span style="display: none;">&nbsp;(<span class="bday dtstart published updated">1999-02-01</span>)</span>'},

		-- Line break
		{'1999|br=y', '1999<span class="noprint">;<br/>' .. yearsSince1999 .. ' years ago</span><span style="display: none;">&nbsp;(<span class="bday dtstart published updated">1999</span>)</span>'},
		{'1999|2|br=y', 'February&nbsp;1999<span class="noprint">;<br/>' .. yearsSince1999 .. ' years ago</span><span style="display: none;">&nbsp;(<span class="bday dtstart published updated">1999-02</span>)</span>'},
		{'1999|2|1|br=y', 'February&nbsp;1,&nbsp;1999<span class="noprint">;<br/>' .. yearsSince1999 .. ' years ago</span><span style="display: none;">&nbsp;(<span class="bday dtstart published updated">1999-02-01</span>)</span>'},
		
		-- Parenthesis
		{'1999|p=y', '1999<span class="noprint">&#32;(' .. yearsSince1999 .. ' years ago)</span><span style="display: none;">&nbsp;(<span class="bday dtstart published updated">1999</span>)</span>'},
		{'1999|2|p=y', 'February&nbsp;1999<span class="noprint">&#32;(' .. yearsSince1999 .. ' years ago)</span><span style="display: none;">&nbsp;(<span class="bday dtstart published updated">1999-02</span>)</span>'},
		{'1999|2|1|p=y', 'February&nbsp;1,&nbsp;1999<span class="noprint">&#32;(' .. yearsSince1999 .. ' years ago)</span><span style="display: none;">&nbsp;(<span class="bday dtstart published updated">1999-02-01</span>)</span>'},
		
		-- Line break and parenthesis
		{'1999|p=y|br=y', '1999<span class="noprint"><br/>(' .. yearsSince1999 .. ' years ago)</span><span style="display: none;">&nbsp;(<span class="bday dtstart published updated">1999</span>)</span>'},
		{'1999|2|p=y|br=y', 'February&nbsp;1999<span class="noprint"><br/>(' .. yearsSince1999 .. ' years ago)</span><span style="display: none;">&nbsp;(<span class="bday dtstart published updated">1999-02</span>)</span>'},
		{'1999|2|1|p=y|br=y', 'February&nbsp;1,&nbsp;1999<span class="noprint"><br/>(' .. yearsSince1999 .. ' years ago)</span><span style="display: none;">&nbsp;(<span class="bday dtstart published updated">1999-02-01</span>)</span>'},
		
		-- Today values
		{mw.language.getContentLanguage():formatDate("Y"), mw.language.getContentLanguage():formatDate("Y") .. '<span class="noprint">;&#32;0 years ago</span><span style="display: none;">&nbsp;(<span class="bday dtstart published updated">' .. mw.language.getContentLanguage():formatDate("Y") .. '</span>)</span>'},
		{mw.language.getContentLanguage():formatDate("Y") .. '|' .. mw.language.getContentLanguage():formatDate("m"), mw.language.getContentLanguage():formatDate("F") .. '&nbsp;' .. mw.language.getContentLanguage():formatDate("Y") .. '<span class="noprint">;&#32;0 months ago</span><span style="display: none;">&nbsp;(<span class="bday dtstart published updated">' .. mw.language.getContentLanguage():formatDate("Y") .. '-' .. mw.language.getContentLanguage():formatDate("m") .. '</span>)</span>'},
		{mw.language.getContentLanguage():formatDate("Y") .. '|' .. mw.language.getContentLanguage():formatDate("m") .. "|" .. mw.language.getContentLanguage():formatDate("d"), mw.language.getContentLanguage():formatDate("F") .. '&nbsp;' .. mw.language.getContentLanguage():formatDate("j") .. ',&nbsp;' .. mw.language.getContentLanguage():formatDate("Y") .. '<span class="noprint">;&#32;0 days ago</span><span style="display: none;">&nbsp;(<span class="bday dtstart published updated">' .. mw.language.getContentLanguage():formatDate("Y") .. '-' .. mw.language.getContentLanguage():formatDate("m") .. '-' .. mw.language.getContentLanguage():formatDate("d") .. '</span>)</span>'},

	}, {nowiki=1})
end

function p:test_21_generate_end_date_age_valid()
	local yearsSince1999 = mw.language.getContentLanguage():formatDate("Y") - 1999
	self:preprocess_equals_sandbox_many('{{#invoke:Date time', 'generate_date|template=end date and age', {
		-- Standard
		{'1999', '1999<span class="noprint">;&#32;' .. yearsSince1999 .. ' years ago</span><span style="display: none;">&nbsp;(<span class="dtend">1999</span>)</span>'},
		{'1999|2', 'February&nbsp;1999<span class="noprint">;&#32;' .. yearsSince1999 .. ' years ago</span><span style="display: none;">&nbsp;(<span class="dtend">1999-02</span>)</span>'},
		{'1999|2|1', 'February&nbsp;1,&nbsp;1999<span class="noprint">;&#32;' .. yearsSince1999 .. ' years ago</span><span style="display: none;">&nbsp;(<span class="dtend">1999-02-01</span>)</span>'},
		
		-- Line break
		{'1999|br=y', '1999<span class="noprint">;<br/>' .. yearsSince1999 .. ' years ago</span><span style="display: none;">&nbsp;(<span class="dtend">1999</span>)</span>'},
		{'1999|2|br=y', 'February&nbsp;1999<span class="noprint">;<br/>' .. yearsSince1999 .. ' years ago</span><span style="display: none;">&nbsp;(<span class="dtend">1999-02</span>)</span>'},
		{'1999|2|1|br=y', 'February&nbsp;1,&nbsp;1999<span class="noprint">;<br/>' .. yearsSince1999 .. ' years ago</span><span style="display: none;">&nbsp;(<span class="dtend">1999-02-01</span>)</span>'},
		
		-- Parenthesis
		{'1999|p=y', '1999<span class="noprint">&#32;(' .. yearsSince1999 .. ' years ago)</span><span style="display: none;">&nbsp;(<span class="dtend">1999</span>)</span>'},
		{'1999|2|p=y', 'February&nbsp;1999<span class="noprint">&#32;(' .. yearsSince1999 .. ' years ago)</span><span style="display: none;">&nbsp;(<span class="dtend">1999-02</span>)</span>'},
		{'1999|2|1|p=y', 'February&nbsp;1,&nbsp;1999<span class="noprint">&#32;(' .. yearsSince1999 .. ' years ago)</span><span style="display: none;">&nbsp;(<span class="dtend">1999-02-01</span>)</span>'},
		
		-- Line break and parenthesis
		{'1999|p=y|br=y', '1999<span class="noprint"><br/>(' .. yearsSince1999 .. ' years ago)</span><span style="display: none;">&nbsp;(<span class="dtend">1999</span>)</span>'},
		{'1999|2|p=y|br=y', 'February&nbsp;1999<span class="noprint"><br/>(' .. yearsSince1999 .. ' years ago)</span><span style="display: none;">&nbsp;(<span class="dtend">1999-02</span>)</span>'},
		{'1999|2|1|p=y|br=y', 'February&nbsp;1,&nbsp;1999<span class="noprint"><br/>(' .. yearsSince1999 .. ' years ago)</span><span style="display: none;">&nbsp;(<span class="dtend">1999-02-01</span>)</span>'},
		
		-- Today values
		{mw.language.getContentLanguage():formatDate("Y"), mw.language.getContentLanguage():formatDate("Y") .. '<span class="noprint">;&#32;0 years ago</span><span style="display: none;">&nbsp;(<span class="dtend">' .. mw.language.getContentLanguage():formatDate("Y") .. '</span>)</span>'},
		{mw.language.getContentLanguage():formatDate("Y") .. '|' .. mw.language.getContentLanguage():formatDate("m"), mw.language.getContentLanguage():formatDate("F") .. '&nbsp;' .. mw.language.getContentLanguage():formatDate("Y") .. '<span class="noprint">;&#32;0 months ago</span><span style="display: none;">&nbsp;(<span class="dtend">' .. mw.language.getContentLanguage():formatDate("Y") .. '-' .. mw.language.getContentLanguage():formatDate("m") .. '</span>)</span>'},
		{mw.language.getContentLanguage():formatDate("Y") .. '|' .. mw.language.getContentLanguage():formatDate("m") .. "|" .. mw.language.getContentLanguage():formatDate("d"), mw.language.getContentLanguage():formatDate("F") .. '&nbsp;' .. mw.language.getContentLanguage():formatDate("j") .. ',&nbsp;' .. mw.language.getContentLanguage():formatDate("Y") .. '<span class="noprint">;&#32;0 days ago</span><span style="display: none;">&nbsp;(<span class="dtend">' .. getPresentDate() .. '</span>)</span>'},

	}, {nowiki=1})
end

function p:test_22_generate_date_range_valid()
	self:preprocess_equals_sandbox_many('{{#invoke:Date time', 'generate_date_range', {
	-- Full dates
	-- Same year, same month (November 12–27, 2008; 12–27 November 2008)
	{'2008|11|12|2008|11|27', 'November&nbsp;12–27,&nbsp;2008<span style="display: none;">&nbsp;(<span class="dtstart">2008-11-12</span>)</span><span style="display: none;">&nbsp;(<span class="dtend">2008-11-27</span>)</span>'},
	{'2008|11|12|2008|11|27|df=yes', '12–27&nbsp;November&nbsp;2008<span style="display: none;">&nbsp;(<span class="dtstart">2008-11-12</span>)</span><span style="display: none;">&nbsp;(<span class="dtend">2008-11-27</span>)</span>'},

	-- Same year, different month (November 12 – December 27, 2008; 12 November – 27 December 2008)
	{'2008|11|12|2008|12|27', 'November&nbsp;12&#32;–&#32;December&nbsp;27,&nbsp;2008<span style="display: none;">&nbsp;(<span class="dtstart">2008-11-12</span>)</span><span style="display: none;">&nbsp;(<span class="dtend">2008-12-27</span>)</span>'},
	{'2008|11|12|2008|12|27|df=yes', '12&nbsp;November&#32;–&#32;27&nbsp;December&nbsp;2008<span style="display: none;">&nbsp;(<span class="dtstart">2008-11-12</span>)</span><span style="display: none;">&nbsp;(<span class="dtend">2008-12-27</span>)</span>'},

	-- Different years (November 12, 2008 – December 27, 2010; 12 November 2008 – 27 December 2010)
	{'2008|11|12|2010|12|27', 'November&nbsp;12,&nbsp;2008&#32;–&#32;December&nbsp;27,&nbsp;2010<span style="display: none;">&nbsp;(<span class="dtstart">2008-11-12</span>)</span><span style="display: none;">&nbsp;(<span class="dtend">2010-12-27</span>)</span>'},
	{'2008|11|12|2010|12|27|df=yes', '12&nbsp;November&nbsp;2008&#32;–&#32;27&nbsp;December&nbsp;2010<span style="display: none;">&nbsp;(<span class="dtstart">2008-11-12</span>)</span><span style="display: none;">&nbsp;(<span class="dtend">2010-12-27</span>)</span>'},

	-- To present
	-- Full date (November 12, 2008 – present; 12–27 November 2008 – present)
	{'2008|11|12|present', 'November&nbsp;12,&nbsp;2008&#32;–&#32;present<span style="display: none;">&nbsp;(<span class="dtstart">2008-11-12</span>)</span><span style="display: none;">&nbsp;(<span class="dtend">' .. getPresentDate() .. '</span>)</span>'},
	{'2008|11|12|present|df=yes', '12&nbsp;November&nbsp;2008&#32;–&#32;present<span style="display: none;">&nbsp;(<span class="dtstart">2008-11-12</span>)</span><span style="display: none;">&nbsp;(<span class="dtend">' .. getPresentDate() .. '</span>)</span>'},

	-- No day (November 2008 – present; November 2008 – present)
	{'2008|11||present', 'November&nbsp;2008&#32;–&#32;present<span style="display: none;">&nbsp;(<span class="dtstart">2008-11</span>)</span><span style="display: none;">&nbsp;(<span class="dtend">' .. getPresentDate() .. '</span>)</span>'},
	{'2008|11||present|df=yes', 'November&nbsp;2008&#32;–&#32;present<span style="display: none;">&nbsp;(<span class="dtstart">2008-11</span>)</span><span style="display: none;">&nbsp;(<span class="dtend">' .. getPresentDate() .. '</span>)</span>'},

	-- No day and month (2008–present; 2008–present)
	{'2008|||present', '2008–present<span style="display: none;">&nbsp;(<span class="dtstart">2008</span>)</span><span style="display: none;">&nbsp;(<span class="dtend">' .. getPresentDate() .. '</span>)</span>'},
	{'2008|||present|df=yes', '2008–present<span style="display: none;">&nbsp;(<span class="dtstart">2008</span>)</span><span style="display: none;">&nbsp;(<span class="dtend">' .. getPresentDate() .. '</span>)</span>'},
	}, {nowiki=1})
end

function p:test_23_generate_date_range_partial_dates()
	self:preprocess_equals_sandbox_many('{{#invoke:Date time', 'generate_date_range', {
	-- Full date and partial date
	-- No end month and day: different year
	{'2008|11|12|2009|', 'November&nbsp;12,&nbsp;2008&#32;–&#32;2009<span style="display: none;">&nbsp;(<span class="dtstart">2008-11-12</span>)</span><span style="display: none;">&nbsp;(<span class="dtend">2009</span>)</span>'},
	{'2008|11|12|2009||df=yes', '12&nbsp;November&nbsp;2008&#32;–&#32;2009<span style="display: none;">&nbsp;(<span class="dtstart">2008-11-12</span>)</span><span style="display: none;">&nbsp;(<span class="dtend">2009</span>)</span>'},

	-- No end month and day: Same year
	{'2008|11|12|2008|', ''},
	{'2008|11|12|2008||df=yes', ''},

	-- No end day: different year, same month
	{'2008|11|12|2009|11', 'November&nbsp;12,&nbsp;2008&#32;–&#32;November&nbsp;2009<span style="display: none;">&nbsp;(<span class="dtstart">2008-11-12</span>)</span><span style="display: none;">&nbsp;(<span class="dtend">2009-11</span>)</span>'},
	{'2008|11|12|2009|11|df=yes', '12&nbsp;November&nbsp;2008&#32;–&#32;November&nbsp;2009<span style="display: none;">&nbsp;(<span class="dtstart">2008-11-12</span>)</span><span style="display: none;">&nbsp;(<span class="dtend">2009-11</span>)</span>'},

	-- No end day: Same year, same month
	{'2008|11|12|2008|11', ''},
	{'2008|11|12|2008|11|df=yes', ''},

	-- No end day: Same year, different month (November 12 – December 2008; 12 November – December 2008)
	{'2008|11|12|2008|12', 'November&nbsp;12,&nbsp;2008&#32;–&#32;December&nbsp;2008<span style="display: none;">&nbsp;(<span class="dtstart">2008-11-12</span>)</span><span style="display: none;">&nbsp;(<span class="dtend">2008-12</span>)</span>'},
	{'2008|11|12|2008|12|df=yes', '12&nbsp;November&nbsp;2008&#32;–&#32;December&nbsp;2008<span style="display: none;">&nbsp;(<span class="dtstart">2008-11-12</span>)</span><span style="display: none;">&nbsp;(<span class="dtend">2008-12</span>)</span>'},
	
	-- Partial date and full date
	-- No start month and day: different year
	{'2008|||2009|11|27', '2008&#32;–&#32;November&nbsp;27,&nbsp;2009<span style="display: none;">&nbsp;(<span class="dtstart">2008</span>)</span><span style="display: none;">&nbsp;(<span class="dtend">2009-11-27</span>)</span>'},
	{'2008|||2009|11|27|df=yes', '2008&#32;–&#32;27&nbsp;November&nbsp;2009<span style="display: none;">&nbsp;(<span class="dtstart">2008</span>)</span><span style="display: none;">&nbsp;(<span class="dtend">2009-11-27</span>)</span>'},	

	-- No start month and day: same year
	{'2008|||2008|11|27', '2008&#32;–&#32;November&nbsp;27,&nbsp;2008<span style="display: none;">&nbsp;(<span class="dtstart">2008</span>)</span><span style="display: none;">&nbsp;(<span class="dtend">2008-11-27</span>)</span>'},
	{'2008|||2008|11|27|df=yes', '2008&#32;–&#32;27&nbsp;November&nbsp;2008<span style="display: none;">&nbsp;(<span class="dtstart">2008</span>)</span><span style="display: none;">&nbsp;(<span class="dtend">2008-11-27</span>)</span>'},	

	-- No start day: Same year, same month (November 2008 – November 27, 2008; November 2008 – 27 November 2008)
	{'2008|11||2008|11|27', 'November&nbsp;2008&#32;–&#32;November&nbsp;27,&nbsp;2008<span style="display: none;">&nbsp;(<span class="dtstart">2008-11</span>)</span><span style="display: none;">&nbsp;(<span class="dtend">2008-11-27</span>)</span>'},
	{'2008|11||2008|11|27|df=yes', 'November&nbsp;2008&#32;–&#32;27&nbsp;November&nbsp;2008<span style="display: none;">&nbsp;(<span class="dtstart">2008-11</span>)</span><span style="display: none;">&nbsp;(<span class="dtend">2008-11-27</span>)</span>'},
	
	-- No start day: Same year, different month (November 2008 – December 27, 2008; November 2008 – 27 December 2008)
	{'2008|11||2008|12|27', 'November&nbsp;2008&#32;–&#32;December&nbsp;27,&nbsp;2008<span style="display: none;">&nbsp;(<span class="dtstart">2008-11</span>)</span><span style="display: none;">&nbsp;(<span class="dtend">2008-12-27</span>)</span>'},
	{'2008|11||2008|12|27|df=yes', 'November&nbsp;2008&#32;–&#32;27&nbsp;December&nbsp;2008<span style="display: none;">&nbsp;(<span class="dtstart">2008-11</span>)</span><span style="display: none;">&nbsp;(<span class="dtend">2008-12-27</span>)</span>'},

	-- Partial dates both
	-- No days: Same year, same month (November–November 2008; November–November 2008)
	{'2008|11||2008|11', 'November–November&nbsp;2008<span style="display: none;">&nbsp;(<span class="dtstart">2008-11</span>)</span><span style="display: none;">&nbsp;(<span class="dtend">2008-11</span>)</span>'},
	{'2008|11||2008|11|df=yes', 'November–November&nbsp;2008<span style="display: none;">&nbsp;(<span class="dtstart">2008-11</span>)</span><span style="display: none;">&nbsp;(<span class="dtend">2008-11</span>)</span>'},

	-- No days: Same year, different month (November–December 2008; November–December 2008)
	{'2008|11||2008|12', 'November–December&nbsp;2008<span style="display: none;">&nbsp;(<span class="dtstart">2008-11</span>)</span><span style="display: none;">&nbsp;(<span class="dtend">2008-12</span>)</span>'},
	{'2008|11||2008|12|df=yes', 'November–December&nbsp;2008<span style="display: none;">&nbsp;(<span class="dtstart">2008-11</span>)</span><span style="display: none;">&nbsp;(<span class="dtend">2008-12</span>)</span>'},

	}, {nowiki=1})
end
function p:test_24_generate_date_range_invalid()
	self:preprocess_equals_sandbox_many('{{#invoke:Date time', 'generate_date_range', {
	-- Empty
	{'', getErrorMessage(ERROR_MESSAGES.missing_year)},
	
	-- No end date
	{'2000', getErrorMessage(ERROR_MESSAGES.missing_year)},
	{'2000|2', getErrorMessage(ERROR_MESSAGES.missing_year)},
	{'2000|2|1', getErrorMessage(ERROR_MESSAGES.missing_year)},

	-- No start date
	{'|||2000', getErrorMessage(ERROR_MESSAGES.missing_year)},
	{'|||2000|2', getErrorMessage(ERROR_MESSAGES.missing_year)},
	{'|||2000|2|1', getErrorMessage(ERROR_MESSAGES.missing_year)},

	-- End date before start date
	{'2008|11|27|2008|11|12', getErrorMessage(ERROR_MESSAGES.end_date_before_start_date)},
	{'2008|11|27|2008|11|12|df=yes', getErrorMessage(ERROR_MESSAGES.end_date_before_start_date)},
	}, {nowiki=1})
end

return p

Content Disclaimer

Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.

  1. The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
  2. There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
  3. It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
  4. Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
  5. Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.