blob: 37b28188f814206733d1716e2f5d21183a8b3180 [file] [log] [blame]
Fred Draked077ca12001-12-12 05:38:08 +00001import calendar
2import unittest
3
Benjamin Petersonee8712c2008-05-20 21:35:26 +00004from test import support
Senthil Kumaran962fed92011-08-11 09:22:52 +08005from test.script_helper import assert_python_ok
Alexander Belopolsky43ca7102010-06-14 17:32:03 +00006import time
Georg Brandl7004bd12010-10-19 18:54:25 +00007import locale
Ezio Melotti85710a42012-09-21 17:26:35 +03008import datetime
Fred Draked077ca12001-12-12 05:38:08 +00009
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010result_2004_text = """
11 2004
12
13 January February March
14Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su
15 1 2 3 4 1 1 2 3 4 5 6 7
16 5 6 7 8 9 10 11 2 3 4 5 6 7 8 8 9 10 11 12 13 14
1712 13 14 15 16 17 18 9 10 11 12 13 14 15 15 16 17 18 19 20 21
1819 20 21 22 23 24 25 16 17 18 19 20 21 22 22 23 24 25 26 27 28
1926 27 28 29 30 31 23 24 25 26 27 28 29 29 30 31
20
21 April May June
22Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su
23 1 2 3 4 1 2 1 2 3 4 5 6
24 5 6 7 8 9 10 11 3 4 5 6 7 8 9 7 8 9 10 11 12 13
2512 13 14 15 16 17 18 10 11 12 13 14 15 16 14 15 16 17 18 19 20
2619 20 21 22 23 24 25 17 18 19 20 21 22 23 21 22 23 24 25 26 27
2726 27 28 29 30 24 25 26 27 28 29 30 28 29 30
28 31
29
30 July August September
31Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su
32 1 2 3 4 1 1 2 3 4 5
33 5 6 7 8 9 10 11 2 3 4 5 6 7 8 6 7 8 9 10 11 12
3412 13 14 15 16 17 18 9 10 11 12 13 14 15 13 14 15 16 17 18 19
3519 20 21 22 23 24 25 16 17 18 19 20 21 22 20 21 22 23 24 25 26
3626 27 28 29 30 31 23 24 25 26 27 28 29 27 28 29 30
37 30 31
38
39 October November December
40Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su
41 1 2 3 1 2 3 4 5 6 7 1 2 3 4 5
42 4 5 6 7 8 9 10 8 9 10 11 12 13 14 6 7 8 9 10 11 12
4311 12 13 14 15 16 17 15 16 17 18 19 20 21 13 14 15 16 17 18 19
4418 19 20 21 22 23 24 22 23 24 25 26 27 28 20 21 22 23 24 25 26
4525 26 27 28 29 30 31 29 30 27 28 29 30 31
46"""
47
48result_2004_html = """
49<?xml version="1.0" encoding="ascii"?>
50<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
51<html>
52<head>
53<meta http-equiv="Content-Type" content="text/html; charset=ascii" />
54<link rel="stylesheet" type="text/css" href="calendar.css" />
Thomas Wouters47b49bf2007-08-30 22:15:33 +000055<title>Calendar for 2004</title>
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000056</head>
57<body>
58<table border="0" cellpadding="0" cellspacing="0" class="year">
59<tr><th colspan="3" class="year">2004</th></tr><tr><td><table border="0" cellpadding="0" cellspacing="0" class="month">
60<tr><th colspan="7" class="month">January</th></tr>
61<tr><th class="mon">Mon</th><th class="tue">Tue</th><th class="wed">Wed</th><th class="thu">Thu</th><th class="fri">Fri</th><th class="sat">Sat</th><th class="sun">Sun</th></tr>
62<tr><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="thu">1</td><td class="fri">2</td><td class="sat">3</td><td class="sun">4</td></tr>
63<tr><td class="mon">5</td><td class="tue">6</td><td class="wed">7</td><td class="thu">8</td><td class="fri">9</td><td class="sat">10</td><td class="sun">11</td></tr>
64<tr><td class="mon">12</td><td class="tue">13</td><td class="wed">14</td><td class="thu">15</td><td class="fri">16</td><td class="sat">17</td><td class="sun">18</td></tr>
65<tr><td class="mon">19</td><td class="tue">20</td><td class="wed">21</td><td class="thu">22</td><td class="fri">23</td><td class="sat">24</td><td class="sun">25</td></tr>
66<tr><td class="mon">26</td><td class="tue">27</td><td class="wed">28</td><td class="thu">29</td><td class="fri">30</td><td class="sat">31</td><td class="noday">&nbsp;</td></tr>
67</table>
68</td><td><table border="0" cellpadding="0" cellspacing="0" class="month">
69<tr><th colspan="7" class="month">February</th></tr>
70<tr><th class="mon">Mon</th><th class="tue">Tue</th><th class="wed">Wed</th><th class="thu">Thu</th><th class="fri">Fri</th><th class="sat">Sat</th><th class="sun">Sun</th></tr>
71<tr><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="sun">1</td></tr>
72<tr><td class="mon">2</td><td class="tue">3</td><td class="wed">4</td><td class="thu">5</td><td class="fri">6</td><td class="sat">7</td><td class="sun">8</td></tr>
73<tr><td class="mon">9</td><td class="tue">10</td><td class="wed">11</td><td class="thu">12</td><td class="fri">13</td><td class="sat">14</td><td class="sun">15</td></tr>
74<tr><td class="mon">16</td><td class="tue">17</td><td class="wed">18</td><td class="thu">19</td><td class="fri">20</td><td class="sat">21</td><td class="sun">22</td></tr>
75<tr><td class="mon">23</td><td class="tue">24</td><td class="wed">25</td><td class="thu">26</td><td class="fri">27</td><td class="sat">28</td><td class="sun">29</td></tr>
76</table>
77</td><td><table border="0" cellpadding="0" cellspacing="0" class="month">
78<tr><th colspan="7" class="month">March</th></tr>
79<tr><th class="mon">Mon</th><th class="tue">Tue</th><th class="wed">Wed</th><th class="thu">Thu</th><th class="fri">Fri</th><th class="sat">Sat</th><th class="sun">Sun</th></tr>
80<tr><td class="mon">1</td><td class="tue">2</td><td class="wed">3</td><td class="thu">4</td><td class="fri">5</td><td class="sat">6</td><td class="sun">7</td></tr>
81<tr><td class="mon">8</td><td class="tue">9</td><td class="wed">10</td><td class="thu">11</td><td class="fri">12</td><td class="sat">13</td><td class="sun">14</td></tr>
82<tr><td class="mon">15</td><td class="tue">16</td><td class="wed">17</td><td class="thu">18</td><td class="fri">19</td><td class="sat">20</td><td class="sun">21</td></tr>
83<tr><td class="mon">22</td><td class="tue">23</td><td class="wed">24</td><td class="thu">25</td><td class="fri">26</td><td class="sat">27</td><td class="sun">28</td></tr>
84<tr><td class="mon">29</td><td class="tue">30</td><td class="wed">31</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td></tr>
85</table>
86</td></tr><tr><td><table border="0" cellpadding="0" cellspacing="0" class="month">
87<tr><th colspan="7" class="month">April</th></tr>
88<tr><th class="mon">Mon</th><th class="tue">Tue</th><th class="wed">Wed</th><th class="thu">Thu</th><th class="fri">Fri</th><th class="sat">Sat</th><th class="sun">Sun</th></tr>
89<tr><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="thu">1</td><td class="fri">2</td><td class="sat">3</td><td class="sun">4</td></tr>
90<tr><td class="mon">5</td><td class="tue">6</td><td class="wed">7</td><td class="thu">8</td><td class="fri">9</td><td class="sat">10</td><td class="sun">11</td></tr>
91<tr><td class="mon">12</td><td class="tue">13</td><td class="wed">14</td><td class="thu">15</td><td class="fri">16</td><td class="sat">17</td><td class="sun">18</td></tr>
92<tr><td class="mon">19</td><td class="tue">20</td><td class="wed">21</td><td class="thu">22</td><td class="fri">23</td><td class="sat">24</td><td class="sun">25</td></tr>
93<tr><td class="mon">26</td><td class="tue">27</td><td class="wed">28</td><td class="thu">29</td><td class="fri">30</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td></tr>
94</table>
95</td><td><table border="0" cellpadding="0" cellspacing="0" class="month">
96<tr><th colspan="7" class="month">May</th></tr>
97<tr><th class="mon">Mon</th><th class="tue">Tue</th><th class="wed">Wed</th><th class="thu">Thu</th><th class="fri">Fri</th><th class="sat">Sat</th><th class="sun">Sun</th></tr>
98<tr><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="sat">1</td><td class="sun">2</td></tr>
99<tr><td class="mon">3</td><td class="tue">4</td><td class="wed">5</td><td class="thu">6</td><td class="fri">7</td><td class="sat">8</td><td class="sun">9</td></tr>
100<tr><td class="mon">10</td><td class="tue">11</td><td class="wed">12</td><td class="thu">13</td><td class="fri">14</td><td class="sat">15</td><td class="sun">16</td></tr>
101<tr><td class="mon">17</td><td class="tue">18</td><td class="wed">19</td><td class="thu">20</td><td class="fri">21</td><td class="sat">22</td><td class="sun">23</td></tr>
102<tr><td class="mon">24</td><td class="tue">25</td><td class="wed">26</td><td class="thu">27</td><td class="fri">28</td><td class="sat">29</td><td class="sun">30</td></tr>
103<tr><td class="mon">31</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td></tr>
104</table>
105</td><td><table border="0" cellpadding="0" cellspacing="0" class="month">
106<tr><th colspan="7" class="month">June</th></tr>
107<tr><th class="mon">Mon</th><th class="tue">Tue</th><th class="wed">Wed</th><th class="thu">Thu</th><th class="fri">Fri</th><th class="sat">Sat</th><th class="sun">Sun</th></tr>
108<tr><td class="noday">&nbsp;</td><td class="tue">1</td><td class="wed">2</td><td class="thu">3</td><td class="fri">4</td><td class="sat">5</td><td class="sun">6</td></tr>
109<tr><td class="mon">7</td><td class="tue">8</td><td class="wed">9</td><td class="thu">10</td><td class="fri">11</td><td class="sat">12</td><td class="sun">13</td></tr>
110<tr><td class="mon">14</td><td class="tue">15</td><td class="wed">16</td><td class="thu">17</td><td class="fri">18</td><td class="sat">19</td><td class="sun">20</td></tr>
111<tr><td class="mon">21</td><td class="tue">22</td><td class="wed">23</td><td class="thu">24</td><td class="fri">25</td><td class="sat">26</td><td class="sun">27</td></tr>
112<tr><td class="mon">28</td><td class="tue">29</td><td class="wed">30</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td></tr>
113</table>
114</td></tr><tr><td><table border="0" cellpadding="0" cellspacing="0" class="month">
115<tr><th colspan="7" class="month">July</th></tr>
116<tr><th class="mon">Mon</th><th class="tue">Tue</th><th class="wed">Wed</th><th class="thu">Thu</th><th class="fri">Fri</th><th class="sat">Sat</th><th class="sun">Sun</th></tr>
117<tr><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="thu">1</td><td class="fri">2</td><td class="sat">3</td><td class="sun">4</td></tr>
118<tr><td class="mon">5</td><td class="tue">6</td><td class="wed">7</td><td class="thu">8</td><td class="fri">9</td><td class="sat">10</td><td class="sun">11</td></tr>
119<tr><td class="mon">12</td><td class="tue">13</td><td class="wed">14</td><td class="thu">15</td><td class="fri">16</td><td class="sat">17</td><td class="sun">18</td></tr>
120<tr><td class="mon">19</td><td class="tue">20</td><td class="wed">21</td><td class="thu">22</td><td class="fri">23</td><td class="sat">24</td><td class="sun">25</td></tr>
121<tr><td class="mon">26</td><td class="tue">27</td><td class="wed">28</td><td class="thu">29</td><td class="fri">30</td><td class="sat">31</td><td class="noday">&nbsp;</td></tr>
122</table>
123</td><td><table border="0" cellpadding="0" cellspacing="0" class="month">
124<tr><th colspan="7" class="month">August</th></tr>
125<tr><th class="mon">Mon</th><th class="tue">Tue</th><th class="wed">Wed</th><th class="thu">Thu</th><th class="fri">Fri</th><th class="sat">Sat</th><th class="sun">Sun</th></tr>
126<tr><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="sun">1</td></tr>
127<tr><td class="mon">2</td><td class="tue">3</td><td class="wed">4</td><td class="thu">5</td><td class="fri">6</td><td class="sat">7</td><td class="sun">8</td></tr>
128<tr><td class="mon">9</td><td class="tue">10</td><td class="wed">11</td><td class="thu">12</td><td class="fri">13</td><td class="sat">14</td><td class="sun">15</td></tr>
129<tr><td class="mon">16</td><td class="tue">17</td><td class="wed">18</td><td class="thu">19</td><td class="fri">20</td><td class="sat">21</td><td class="sun">22</td></tr>
130<tr><td class="mon">23</td><td class="tue">24</td><td class="wed">25</td><td class="thu">26</td><td class="fri">27</td><td class="sat">28</td><td class="sun">29</td></tr>
131<tr><td class="mon">30</td><td class="tue">31</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td></tr>
132</table>
133</td><td><table border="0" cellpadding="0" cellspacing="0" class="month">
134<tr><th colspan="7" class="month">September</th></tr>
135<tr><th class="mon">Mon</th><th class="tue">Tue</th><th class="wed">Wed</th><th class="thu">Thu</th><th class="fri">Fri</th><th class="sat">Sat</th><th class="sun">Sun</th></tr>
136<tr><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="wed">1</td><td class="thu">2</td><td class="fri">3</td><td class="sat">4</td><td class="sun">5</td></tr>
137<tr><td class="mon">6</td><td class="tue">7</td><td class="wed">8</td><td class="thu">9</td><td class="fri">10</td><td class="sat">11</td><td class="sun">12</td></tr>
138<tr><td class="mon">13</td><td class="tue">14</td><td class="wed">15</td><td class="thu">16</td><td class="fri">17</td><td class="sat">18</td><td class="sun">19</td></tr>
139<tr><td class="mon">20</td><td class="tue">21</td><td class="wed">22</td><td class="thu">23</td><td class="fri">24</td><td class="sat">25</td><td class="sun">26</td></tr>
140<tr><td class="mon">27</td><td class="tue">28</td><td class="wed">29</td><td class="thu">30</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td></tr>
141</table>
142</td></tr><tr><td><table border="0" cellpadding="0" cellspacing="0" class="month">
143<tr><th colspan="7" class="month">October</th></tr>
144<tr><th class="mon">Mon</th><th class="tue">Tue</th><th class="wed">Wed</th><th class="thu">Thu</th><th class="fri">Fri</th><th class="sat">Sat</th><th class="sun">Sun</th></tr>
145<tr><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="fri">1</td><td class="sat">2</td><td class="sun">3</td></tr>
146<tr><td class="mon">4</td><td class="tue">5</td><td class="wed">6</td><td class="thu">7</td><td class="fri">8</td><td class="sat">9</td><td class="sun">10</td></tr>
147<tr><td class="mon">11</td><td class="tue">12</td><td class="wed">13</td><td class="thu">14</td><td class="fri">15</td><td class="sat">16</td><td class="sun">17</td></tr>
148<tr><td class="mon">18</td><td class="tue">19</td><td class="wed">20</td><td class="thu">21</td><td class="fri">22</td><td class="sat">23</td><td class="sun">24</td></tr>
149<tr><td class="mon">25</td><td class="tue">26</td><td class="wed">27</td><td class="thu">28</td><td class="fri">29</td><td class="sat">30</td><td class="sun">31</td></tr>
150</table>
151</td><td><table border="0" cellpadding="0" cellspacing="0" class="month">
152<tr><th colspan="7" class="month">November</th></tr>
153<tr><th class="mon">Mon</th><th class="tue">Tue</th><th class="wed">Wed</th><th class="thu">Thu</th><th class="fri">Fri</th><th class="sat">Sat</th><th class="sun">Sun</th></tr>
154<tr><td class="mon">1</td><td class="tue">2</td><td class="wed">3</td><td class="thu">4</td><td class="fri">5</td><td class="sat">6</td><td class="sun">7</td></tr>
155<tr><td class="mon">8</td><td class="tue">9</td><td class="wed">10</td><td class="thu">11</td><td class="fri">12</td><td class="sat">13</td><td class="sun">14</td></tr>
156<tr><td class="mon">15</td><td class="tue">16</td><td class="wed">17</td><td class="thu">18</td><td class="fri">19</td><td class="sat">20</td><td class="sun">21</td></tr>
157<tr><td class="mon">22</td><td class="tue">23</td><td class="wed">24</td><td class="thu">25</td><td class="fri">26</td><td class="sat">27</td><td class="sun">28</td></tr>
158<tr><td class="mon">29</td><td class="tue">30</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td></tr>
159</table>
160</td><td><table border="0" cellpadding="0" cellspacing="0" class="month">
161<tr><th colspan="7" class="month">December</th></tr>
162<tr><th class="mon">Mon</th><th class="tue">Tue</th><th class="wed">Wed</th><th class="thu">Thu</th><th class="fri">Fri</th><th class="sat">Sat</th><th class="sun">Sun</th></tr>
163<tr><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="wed">1</td><td class="thu">2</td><td class="fri">3</td><td class="sat">4</td><td class="sun">5</td></tr>
164<tr><td class="mon">6</td><td class="tue">7</td><td class="wed">8</td><td class="thu">9</td><td class="fri">10</td><td class="sat">11</td><td class="sun">12</td></tr>
165<tr><td class="mon">13</td><td class="tue">14</td><td class="wed">15</td><td class="thu">16</td><td class="fri">17</td><td class="sat">18</td><td class="sun">19</td></tr>
166<tr><td class="mon">20</td><td class="tue">21</td><td class="wed">22</td><td class="thu">23</td><td class="fri">24</td><td class="sat">25</td><td class="sun">26</td></tr>
167<tr><td class="mon">27</td><td class="tue">28</td><td class="wed">29</td><td class="thu">30</td><td class="fri">31</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td></tr>
168</table>
169</td></tr></table></body>
170</html>
171"""
172
173
174class OutputTestCase(unittest.TestCase):
175 def normalize_calendar(self, s):
Mark Dickinson934896d2009-02-21 20:59:32 +0000176 # Filters out locale dependent strings
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000177 def neitherspacenordigit(c):
178 return not c.isspace() and not c.isdigit()
179
180 lines = []
181 for line in s.splitlines(False):
182 # Drop texts, as they are locale dependent
183 if line and not filter(neitherspacenordigit, line):
184 lines.append(line)
185 return lines
186
187 def test_output(self):
188 self.assertEqual(
189 self.normalize_calendar(calendar.calendar(2004)),
190 self.normalize_calendar(result_2004_text)
191 )
192
193 def test_output_textcalendar(self):
194 self.assertEqual(
195 calendar.TextCalendar().formatyear(2004).strip(),
196 result_2004_text.strip()
197 )
198
199 def test_output_htmlcalendar(self):
Walter Dörwaldc49ebc02007-05-22 17:03:39 +0000200 encoding = 'ascii'
201 cal = calendar.HTMLCalendar()
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000202 self.assertEqual(
Walter Dörwaldc49ebc02007-05-22 17:03:39 +0000203 cal.formatyearpage(2004, encoding=encoding).strip(b' \t\n'),
204 result_2004_html.strip(' \t\n').encode(encoding)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000205 )
206
207
Fred Draked077ca12001-12-12 05:38:08 +0000208class CalendarTestCase(unittest.TestCase):
209 def test_isleap(self):
210 # Make sure that the return is right for a few years, and
211 # ensure that the return values are 1 or 0, not just true or
212 # false (see SF bug #485794). Specific additional tests may
213 # be appropriate; this tests a single "cycle".
214 self.assertEqual(calendar.isleap(2000), 1)
215 self.assertEqual(calendar.isleap(2001), 0)
216 self.assertEqual(calendar.isleap(2002), 0)
217 self.assertEqual(calendar.isleap(2003), 0)
218
219 def test_setfirstweekday(self):
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000220 self.assertRaises(TypeError, calendar.setfirstweekday, 'flabber')
Fred Draked077ca12001-12-12 05:38:08 +0000221 self.assertRaises(ValueError, calendar.setfirstweekday, -1)
222 self.assertRaises(ValueError, calendar.setfirstweekday, 200)
223 orig = calendar.firstweekday()
224 calendar.setfirstweekday(calendar.SUNDAY)
225 self.assertEqual(calendar.firstweekday(), calendar.SUNDAY)
226 calendar.setfirstweekday(calendar.MONDAY)
227 self.assertEqual(calendar.firstweekday(), calendar.MONDAY)
228 calendar.setfirstweekday(orig)
229
Skip Montanaro693c6c42002-03-15 03:57:04 +0000230 def test_enumerateweekdays(self):
231 self.assertRaises(IndexError, calendar.day_abbr.__getitem__, -10)
232 self.assertRaises(IndexError, calendar.day_name.__getitem__, 10)
233 self.assertEqual(len([d for d in calendar.day_abbr]), 7)
Fred Draked077ca12001-12-12 05:38:08 +0000234
Tim Peters0c2c8e72002-03-23 03:26:53 +0000235 def test_days(self):
236 for attr in "day_name", "day_abbr":
237 value = getattr(calendar, attr)
238 self.assertEqual(len(value), 7)
239 self.assertEqual(len(value[:]), 7)
240 # ensure they're all unique
Tim Petersbbc0d442004-11-13 16:18:32 +0000241 self.assertEqual(len(set(value)), 7)
242 # verify it "acts like a sequence" in two forms of iteration
243 self.assertEqual(value[::-1], list(reversed(value)))
Tim Peters0c2c8e72002-03-23 03:26:53 +0000244
245 def test_months(self):
246 for attr in "month_name", "month_abbr":
247 value = getattr(calendar, attr)
248 self.assertEqual(len(value), 13)
249 self.assertEqual(len(value[:]), 13)
250 self.assertEqual(value[0], "")
251 # ensure they're all unique
Tim Petersbbc0d442004-11-13 16:18:32 +0000252 self.assertEqual(len(set(value)), 13)
253 # verify it "acts like a sequence" in two forms of iteration
254 self.assertEqual(value[::-1], list(reversed(value)))
Tim Peters0c2c8e72002-03-23 03:26:53 +0000255
Georg Brandl7004bd12010-10-19 18:54:25 +0000256 def test_localecalendars(self):
257 # ensure that Locale{Text,HTML}Calendar resets the locale properly
258 # (it is still not thread-safe though)
Georg Brandl7004bd12010-10-19 18:54:25 +0000259 old_october = calendar.TextCalendar().formatmonthname(2010, 10, 10)
Georg Brandl9450cc02010-10-20 06:50:19 +0000260 try:
Serhiy Storchakaf9fcdb72013-01-31 16:00:42 +0200261 cal = calendar.LocaleTextCalendar(locale='')
262 local_weekday = cal.formatweekday(1, 10)
263 local_month = cal.formatmonthname(2010, 10, 10)
Georg Brandl9450cc02010-10-20 06:50:19 +0000264 except locale.Error:
265 # cannot set the system default locale -- skip rest of test
Serhiy Storchakaf9fcdb72013-01-31 16:00:42 +0200266 raise unittest.SkipTest('cannot set the system default locale')
267 self.assertIsInstance(local_weekday, str)
268 self.assertIsInstance(local_month, str)
269 self.assertEqual(len(local_weekday), 10)
270 self.assertGreaterEqual(len(local_month), 10)
271 cal = calendar.LocaleHTMLCalendar(locale='')
272 local_weekday = cal.formatweekday(1)
273 local_month = cal.formatmonthname(2010, 10)
274 self.assertIsInstance(local_weekday, str)
275 self.assertIsInstance(local_month, str)
Georg Brandl7004bd12010-10-19 18:54:25 +0000276 new_october = calendar.TextCalendar().formatmonthname(2010, 10, 10)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000277 self.assertEqual(old_october, new_october)
Georg Brandl7004bd12010-10-19 18:54:25 +0000278
Ezio Melotti85710a42012-09-21 17:26:35 +0300279 def test_itermonthdates(self):
280 # ensure itermonthdates doesn't overflow after datetime.MAXYEAR
281 # see #15421
282 list(calendar.Calendar().itermonthdates(datetime.MAXYEAR, 12))
283
Walter Dörwald59ad4562004-07-02 19:00:09 +0000284
285class MonthCalendarTestCase(unittest.TestCase):
286 def setUp(self):
287 self.oldfirstweekday = calendar.firstweekday()
288 calendar.setfirstweekday(self.firstweekday)
289
290 def tearDown(self):
291 calendar.setfirstweekday(self.oldfirstweekday)
292
293 def check_weeks(self, year, month, weeks):
294 cal = calendar.monthcalendar(year, month)
295 self.assertEqual(len(cal), len(weeks))
Guido van Rossum805365e2007-05-07 22:24:25 +0000296 for i in range(len(weeks)):
Walter Dörwald59ad4562004-07-02 19:00:09 +0000297 self.assertEqual(weeks[i], sum(day != 0 for day in cal[i]))
298
299
300class MondayTestCase(MonthCalendarTestCase):
301 firstweekday = calendar.MONDAY
302
303 def test_february(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000304 # A 28-day february starting on monday (7+7+7+7 days)
Walter Dörwald59ad4562004-07-02 19:00:09 +0000305 self.check_weeks(1999, 2, (7, 7, 7, 7))
306
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000307 # A 28-day february starting on tuesday (6+7+7+7+1 days)
Walter Dörwald59ad4562004-07-02 19:00:09 +0000308 self.check_weeks(2005, 2, (6, 7, 7, 7, 1))
309
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000310 # A 28-day february starting on sunday (1+7+7+7+6 days)
Walter Dörwald59ad4562004-07-02 19:00:09 +0000311 self.check_weeks(1987, 2, (1, 7, 7, 7, 6))
312
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000313 # A 29-day february starting on monday (7+7+7+7+1 days)
Walter Dörwald59ad4562004-07-02 19:00:09 +0000314 self.check_weeks(1988, 2, (7, 7, 7, 7, 1))
315
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000316 # A 29-day february starting on tuesday (6+7+7+7+2 days)
Walter Dörwald59ad4562004-07-02 19:00:09 +0000317 self.check_weeks(1972, 2, (6, 7, 7, 7, 2))
318
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000319 # A 29-day february starting on sunday (1+7+7+7+7 days)
Walter Dörwald59ad4562004-07-02 19:00:09 +0000320 self.check_weeks(2004, 2, (1, 7, 7, 7, 7))
321
322 def test_april(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000323 # A 30-day april starting on monday (7+7+7+7+2 days)
Walter Dörwald59ad4562004-07-02 19:00:09 +0000324 self.check_weeks(1935, 4, (7, 7, 7, 7, 2))
325
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000326 # A 30-day april starting on tuesday (6+7+7+7+3 days)
Walter Dörwald59ad4562004-07-02 19:00:09 +0000327 self.check_weeks(1975, 4, (6, 7, 7, 7, 3))
328
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000329 # A 30-day april starting on sunday (1+7+7+7+7+1 days)
Walter Dörwald59ad4562004-07-02 19:00:09 +0000330 self.check_weeks(1945, 4, (1, 7, 7, 7, 7, 1))
331
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000332 # A 30-day april starting on saturday (2+7+7+7+7 days)
Walter Dörwald59ad4562004-07-02 19:00:09 +0000333 self.check_weeks(1995, 4, (2, 7, 7, 7, 7))
334
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000335 # A 30-day april starting on friday (3+7+7+7+6 days)
Walter Dörwald59ad4562004-07-02 19:00:09 +0000336 self.check_weeks(1994, 4, (3, 7, 7, 7, 6))
337
338 def test_december(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000339 # A 31-day december starting on monday (7+7+7+7+3 days)
Walter Dörwald59ad4562004-07-02 19:00:09 +0000340 self.check_weeks(1980, 12, (7, 7, 7, 7, 3))
341
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000342 # A 31-day december starting on tuesday (6+7+7+7+4 days)
Walter Dörwald59ad4562004-07-02 19:00:09 +0000343 self.check_weeks(1987, 12, (6, 7, 7, 7, 4))
344
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000345 # A 31-day december starting on sunday (1+7+7+7+7+2 days)
Walter Dörwald59ad4562004-07-02 19:00:09 +0000346 self.check_weeks(1968, 12, (1, 7, 7, 7, 7, 2))
347
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000348 # A 31-day december starting on thursday (4+7+7+7+6 days)
Walter Dörwald59ad4562004-07-02 19:00:09 +0000349 self.check_weeks(1988, 12, (4, 7, 7, 7, 6))
350
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000351 # A 31-day december starting on friday (3+7+7+7+7 days)
Walter Dörwald59ad4562004-07-02 19:00:09 +0000352 self.check_weeks(2017, 12, (3, 7, 7, 7, 7))
353
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000354 # A 31-day december starting on saturday (2+7+7+7+7+1 days)
Walter Dörwald59ad4562004-07-02 19:00:09 +0000355 self.check_weeks(2068, 12, (2, 7, 7, 7, 7, 1))
356
357
Walter Dörwald302fa6d2004-07-08 17:14:17 +0000358class SundayTestCase(MonthCalendarTestCase):
359 firstweekday = calendar.SUNDAY
360
361 def test_february(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000362 # A 28-day february starting on sunday (7+7+7+7 days)
Walter Dörwald302fa6d2004-07-08 17:14:17 +0000363 self.check_weeks(2009, 2, (7, 7, 7, 7))
364
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000365 # A 28-day february starting on monday (6+7+7+7+1 days)
Walter Dörwald302fa6d2004-07-08 17:14:17 +0000366 self.check_weeks(1999, 2, (6, 7, 7, 7, 1))
367
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000368 # A 28-day february starting on saturday (1+7+7+7+6 days)
Walter Dörwald302fa6d2004-07-08 17:14:17 +0000369 self.check_weeks(1997, 2, (1, 7, 7, 7, 6))
370
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000371 # A 29-day february starting on sunday (7+7+7+7+1 days)
Walter Dörwald302fa6d2004-07-08 17:14:17 +0000372 self.check_weeks(2004, 2, (7, 7, 7, 7, 1))
373
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000374 # A 29-day february starting on monday (6+7+7+7+2 days)
Walter Dörwald302fa6d2004-07-08 17:14:17 +0000375 self.check_weeks(1960, 2, (6, 7, 7, 7, 2))
376
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000377 # A 29-day february starting on saturday (1+7+7+7+7 days)
Walter Dörwald302fa6d2004-07-08 17:14:17 +0000378 self.check_weeks(1964, 2, (1, 7, 7, 7, 7))
379
380 def test_april(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000381 # A 30-day april starting on sunday (7+7+7+7+2 days)
Walter Dörwald302fa6d2004-07-08 17:14:17 +0000382 self.check_weeks(1923, 4, (7, 7, 7, 7, 2))
383
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000384 # A 30-day april starting on monday (6+7+7+7+3 days)
Walter Dörwald302fa6d2004-07-08 17:14:17 +0000385 self.check_weeks(1918, 4, (6, 7, 7, 7, 3))
386
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000387 # A 30-day april starting on saturday (1+7+7+7+7+1 days)
Walter Dörwald302fa6d2004-07-08 17:14:17 +0000388 self.check_weeks(1950, 4, (1, 7, 7, 7, 7, 1))
389
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000390 # A 30-day april starting on friday (2+7+7+7+7 days)
Walter Dörwald302fa6d2004-07-08 17:14:17 +0000391 self.check_weeks(1960, 4, (2, 7, 7, 7, 7))
392
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000393 # A 30-day april starting on thursday (3+7+7+7+6 days)
Walter Dörwald302fa6d2004-07-08 17:14:17 +0000394 self.check_weeks(1909, 4, (3, 7, 7, 7, 6))
395
396 def test_december(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000397 # A 31-day december starting on sunday (7+7+7+7+3 days)
Walter Dörwald302fa6d2004-07-08 17:14:17 +0000398 self.check_weeks(2080, 12, (7, 7, 7, 7, 3))
399
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000400 # A 31-day december starting on monday (6+7+7+7+4 days)
Walter Dörwald302fa6d2004-07-08 17:14:17 +0000401 self.check_weeks(1941, 12, (6, 7, 7, 7, 4))
402
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000403 # A 31-day december starting on saturday (1+7+7+7+7+2 days)
Walter Dörwald302fa6d2004-07-08 17:14:17 +0000404 self.check_weeks(1923, 12, (1, 7, 7, 7, 7, 2))
405
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000406 # A 31-day december starting on wednesday (4+7+7+7+6 days)
Walter Dörwald302fa6d2004-07-08 17:14:17 +0000407 self.check_weeks(1948, 12, (4, 7, 7, 7, 6))
408
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000409 # A 31-day december starting on thursday (3+7+7+7+7 days)
Walter Dörwald302fa6d2004-07-08 17:14:17 +0000410 self.check_weeks(1927, 12, (3, 7, 7, 7, 7))
411
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000412 # A 31-day december starting on friday (2+7+7+7+7+1 days)
Walter Dörwald302fa6d2004-07-08 17:14:17 +0000413 self.check_weeks(1995, 12, (2, 7, 7, 7, 7, 1))
414
Alexander Belopolsky43ca7102010-06-14 17:32:03 +0000415class TimegmTestCase(unittest.TestCase):
416 TIMESTAMPS = [0, 10, 100, 1000, 10000, 100000, 1000000,
417 1234567890, 1262304000, 1275785153,]
418 def test_timegm(self):
419 for secs in self.TIMESTAMPS:
420 tuple = time.gmtime(secs)
421 self.assertEqual(secs, calendar.timegm(tuple))
Walter Dörwald302fa6d2004-07-08 17:14:17 +0000422
Brett Cannoncfae36f2010-07-23 13:54:14 +0000423class MonthRangeTestCase(unittest.TestCase):
424 def test_january(self):
425 # Tests valid lower boundary case.
426 self.assertEqual(calendar.monthrange(2004,1), (3,31))
427
428 def test_february_leap(self):
429 # Tests February during leap year.
430 self.assertEqual(calendar.monthrange(2004,2), (6,29))
431
432 def test_february_nonleap(self):
433 # Tests February in non-leap year.
434 self.assertEqual(calendar.monthrange(2010,2), (0,28))
435
436 def test_december(self):
437 # Tests valid upper boundary case.
438 self.assertEqual(calendar.monthrange(2004,12), (2,31))
439
440 def test_zeroth_month(self):
441 # Tests low invalid boundary case.
442 with self.assertRaises(calendar.IllegalMonthError):
443 calendar.monthrange(2004, 0)
444
445 def test_thirteenth_month(self):
446 # Tests high invalid boundary case.
447 with self.assertRaises(calendar.IllegalMonthError):
448 calendar.monthrange(2004, 13)
449
R. David Murray1daaf9e2010-12-31 19:21:14 +0000450class LeapdaysTestCase(unittest.TestCase):
451 def test_no_range(self):
452 # test when no range i.e. two identical years as args
453 self.assertEqual(calendar.leapdays(2010,2010), 0)
454
455 def test_no_leapdays(self):
456 # test when no leap years in range
457 self.assertEqual(calendar.leapdays(2010,2011), 0)
458
459 def test_no_leapdays_upper_boundary(self):
460 # test no leap years in range, when upper boundary is a leap year
461 self.assertEqual(calendar.leapdays(2010,2012), 0)
462
463 def test_one_leapday_lower_boundary(self):
464 # test when one leap year in range, lower boundary is leap year
465 self.assertEqual(calendar.leapdays(2012,2013), 1)
466
467 def test_several_leapyears_in_range(self):
468 self.assertEqual(calendar.leapdays(1997,2020), 5)
469
Brett Cannoncfae36f2010-07-23 13:54:14 +0000470
Senthil Kumaran962fed92011-08-11 09:22:52 +0800471class ConsoleOutputTestCase(unittest.TestCase):
472 def test_outputs_bytes(self):
473 (return_code, stdout, stderr) = assert_python_ok('-m', 'calendar', '--type=html', '2010')
474 self.assertEqual(stdout[:6], b'<?xml ')
475
Fred Draked077ca12001-12-12 05:38:08 +0000476def test_main():
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000477 support.run_unittest(
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000478 OutputTestCase,
Walter Dörwald59ad4562004-07-02 19:00:09 +0000479 CalendarTestCase,
Walter Dörwald302fa6d2004-07-08 17:14:17 +0000480 MondayTestCase,
Alexander Belopolsky43ca7102010-06-14 17:32:03 +0000481 SundayTestCase,
482 TimegmTestCase,
Brett Cannoncfae36f2010-07-23 13:54:14 +0000483 MonthRangeTestCase,
R. David Murray1daaf9e2010-12-31 19:21:14 +0000484 LeapdaysTestCase,
Senthil Kumaran962fed92011-08-11 09:22:52 +0800485 ConsoleOutputTestCase
Walter Dörwald59ad4562004-07-02 19:00:09 +0000486 )
487
Fred Draked077ca12001-12-12 05:38:08 +0000488
489if __name__ == "__main__":
490 test_main()