blob: 5692642db183d1d712ed37af22a3f19fce67ca4c [file] [log] [blame]
Fred Draked077ca12001-12-12 05:38:08 +00001import calendar
2import unittest
3
Walter Dörwald21d3a322003-05-01 17:45:56 +00004from test import test_support
Serhiy Storchakad44bcc92015-02-05 15:18:26 +02005from test.script_helper import assert_python_ok, assert_python_failure
Georg Brandl79f096a2010-11-26 07:57:57 +00006import locale
Ezio Melotticadff702012-09-21 17:26:35 +03007import datetime
Serhiy Storchakad44bcc92015-02-05 15:18:26 +02008import os
Fred Draked077ca12001-12-12 05:38:08 +00009
Serhiy Storchakad44bcc92015-02-05 15:18:26 +020010result_2004_01_text = """\
11 January 2004
12Mo Tu We Th Fr Sa Su
13 1 2 3 4
14 5 6 7 8 9 10 11
1512 13 14 15 16 17 18
1619 20 21 22 23 24 25
1726 27 28 29 30 31
18"""
Fred Draked077ca12001-12-12 05:38:08 +000019
Serhiy Storchakad44bcc92015-02-05 15:18:26 +020020result_2004_text = """\
Walter Dörwald58917a62006-03-31 15:26:22 +000021 2004
22
23 January February March
24Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su
25 1 2 3 4 1 1 2 3 4 5 6 7
26 5 6 7 8 9 10 11 2 3 4 5 6 7 8 8 9 10 11 12 13 14
2712 13 14 15 16 17 18 9 10 11 12 13 14 15 15 16 17 18 19 20 21
2819 20 21 22 23 24 25 16 17 18 19 20 21 22 22 23 24 25 26 27 28
2926 27 28 29 30 31 23 24 25 26 27 28 29 29 30 31
30
31 April May June
32Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su
33 1 2 3 4 1 2 1 2 3 4 5 6
34 5 6 7 8 9 10 11 3 4 5 6 7 8 9 7 8 9 10 11 12 13
3512 13 14 15 16 17 18 10 11 12 13 14 15 16 14 15 16 17 18 19 20
3619 20 21 22 23 24 25 17 18 19 20 21 22 23 21 22 23 24 25 26 27
3726 27 28 29 30 24 25 26 27 28 29 30 28 29 30
38 31
39
40 July August September
41Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su
42 1 2 3 4 1 1 2 3 4 5
43 5 6 7 8 9 10 11 2 3 4 5 6 7 8 6 7 8 9 10 11 12
4412 13 14 15 16 17 18 9 10 11 12 13 14 15 13 14 15 16 17 18 19
4519 20 21 22 23 24 25 16 17 18 19 20 21 22 20 21 22 23 24 25 26
4626 27 28 29 30 31 23 24 25 26 27 28 29 27 28 29 30
47 30 31
48
49 October November December
50Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su
51 1 2 3 1 2 3 4 5 6 7 1 2 3 4 5
52 4 5 6 7 8 9 10 8 9 10 11 12 13 14 6 7 8 9 10 11 12
5311 12 13 14 15 16 17 15 16 17 18 19 20 21 13 14 15 16 17 18 19
5418 19 20 21 22 23 24 22 23 24 25 26 27 28 20 21 22 23 24 25 26
5525 26 27 28 29 30 31 29 30 27 28 29 30 31
56"""
57
Serhiy Storchakad44bcc92015-02-05 15:18:26 +020058result_2004_html = """\
Walter Dörwaldbc966092006-04-12 10:09:16 +000059<?xml version="1.0" encoding="ascii"?>
60<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
61<html>
62<head>
63<meta http-equiv="Content-Type" content="text/html; charset=ascii" />
64<link rel="stylesheet" type="text/css" href="calendar.css" />
Walter Dörwald6d20b702007-08-28 23:35:33 +000065<title>Calendar for 2004</title>
Walter Dörwaldbc966092006-04-12 10:09:16 +000066</head>
67<body>
68<table border="0" cellpadding="0" cellspacing="0" class="year">
69<tr><th colspan="3" class="year">2004</th></tr><tr><td><table border="0" cellpadding="0" cellspacing="0" class="month">
70<tr><th colspan="7" class="month">January</th></tr>
71<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>
72<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>
73<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>
74<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>
75<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>
76<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>
77</table>
78</td><td><table border="0" cellpadding="0" cellspacing="0" class="month">
79<tr><th colspan="7" class="month">February</th></tr>
80<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>
81<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>
82<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>
83<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>
84<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>
85<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>
86</table>
87</td><td><table border="0" cellpadding="0" cellspacing="0" class="month">
88<tr><th colspan="7" class="month">March</th></tr>
89<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>
90<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>
91<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>
92<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>
93<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>
94<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>
95</table>
96</td></tr><tr><td><table border="0" cellpadding="0" cellspacing="0" class="month">
97<tr><th colspan="7" class="month">April</th></tr>
98<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>
99<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>
100<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>
101<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>
102<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>
103<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>
104</table>
105</td><td><table border="0" cellpadding="0" cellspacing="0" class="month">
106<tr><th colspan="7" class="month">May</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="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>
109<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>
110<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>
111<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>
112<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>
113<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>
114</table>
115</td><td><table border="0" cellpadding="0" cellspacing="0" class="month">
116<tr><th colspan="7" class="month">June</th></tr>
117<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>
118<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>
119<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>
120<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>
121<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>
122<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>
123</table>
124</td></tr><tr><td><table border="0" cellpadding="0" cellspacing="0" class="month">
125<tr><th colspan="7" class="month">July</th></tr>
126<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>
127<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>
128<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>
129<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>
130<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>
131<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>
132</table>
133</td><td><table border="0" cellpadding="0" cellspacing="0" class="month">
134<tr><th colspan="7" class="month">August</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="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="sun">1</td></tr>
137<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>
138<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>
139<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>
140<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>
141<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>
142</table>
143</td><td><table border="0" cellpadding="0" cellspacing="0" class="month">
144<tr><th colspan="7" class="month">September</th></tr>
145<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>
146<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>
147<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>
148<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>
149<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>
150<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>
151</table>
152</td></tr><tr><td><table border="0" cellpadding="0" cellspacing="0" class="month">
153<tr><th colspan="7" class="month">October</th></tr>
154<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>
155<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>
156<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>
157<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>
158<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>
159<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>
160</table>
161</td><td><table border="0" cellpadding="0" cellspacing="0" class="month">
162<tr><th colspan="7" class="month">November</th></tr>
163<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>
164<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>
165<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>
166<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>
167<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>
168<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>
169</table>
170</td><td><table border="0" cellpadding="0" cellspacing="0" class="month">
171<tr><th colspan="7" class="month">December</th></tr>
172<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>
173<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>
174<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>
175<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>
176<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>
177<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>
178</table>
179</td></tr></table></body>
180</html>
181"""
182
Walter Dörwald58917a62006-03-31 15:26:22 +0000183
184class OutputTestCase(unittest.TestCase):
185 def normalize_calendar(self, s):
Mark Dickinson3e4caeb2009-02-21 20:27:01 +0000186 # Filters out locale dependent strings
Walter Dörwald58917a62006-03-31 15:26:22 +0000187 def neitherspacenordigit(c):
188 return not c.isspace() and not c.isdigit()
189
190 lines = []
191 for line in s.splitlines(False):
192 # Drop texts, as they are locale dependent
193 if line and not filter(neitherspacenordigit, line):
194 lines.append(line)
195 return lines
196
197 def test_output(self):
198 self.assertEqual(
199 self.normalize_calendar(calendar.calendar(2004)),
Walter Dörwaldbc966092006-04-12 10:09:16 +0000200 self.normalize_calendar(result_2004_text)
201 )
202
203 def test_output_textcalendar(self):
204 self.assertEqual(
205 calendar.TextCalendar().formatyear(2004).strip(),
206 result_2004_text.strip()
207 )
208
209 def test_output_htmlcalendar(self):
210 self.assertEqual(
211 calendar.HTMLCalendar().formatyearpage(2004).strip(),
212 result_2004_html.strip()
Walter Dörwald58917a62006-03-31 15:26:22 +0000213 )
214
215
Fred Draked077ca12001-12-12 05:38:08 +0000216class CalendarTestCase(unittest.TestCase):
217 def test_isleap(self):
218 # Make sure that the return is right for a few years, and
219 # ensure that the return values are 1 or 0, not just true or
220 # false (see SF bug #485794). Specific additional tests may
221 # be appropriate; this tests a single "cycle".
222 self.assertEqual(calendar.isleap(2000), 1)
223 self.assertEqual(calendar.isleap(2001), 0)
224 self.assertEqual(calendar.isleap(2002), 0)
225 self.assertEqual(calendar.isleap(2003), 0)
226
227 def test_setfirstweekday(self):
Florent Xicluna1f3b4e12010-03-07 12:14:25 +0000228 self.assertRaises(ValueError, calendar.setfirstweekday, 'flabber')
229 self.assertRaises(ValueError, calendar.setfirstweekday, -1)
230 self.assertRaises(ValueError, calendar.setfirstweekday, 200)
Fred Draked077ca12001-12-12 05:38:08 +0000231 orig = calendar.firstweekday()
232 calendar.setfirstweekday(calendar.SUNDAY)
233 self.assertEqual(calendar.firstweekday(), calendar.SUNDAY)
234 calendar.setfirstweekday(calendar.MONDAY)
235 self.assertEqual(calendar.firstweekday(), calendar.MONDAY)
236 calendar.setfirstweekday(orig)
237
Skip Montanaro693c6c42002-03-15 03:57:04 +0000238 def test_enumerateweekdays(self):
239 self.assertRaises(IndexError, calendar.day_abbr.__getitem__, -10)
240 self.assertRaises(IndexError, calendar.day_name.__getitem__, 10)
241 self.assertEqual(len([d for d in calendar.day_abbr]), 7)
Fred Draked077ca12001-12-12 05:38:08 +0000242
Tim Peters0c2c8e72002-03-23 03:26:53 +0000243 def test_days(self):
244 for attr in "day_name", "day_abbr":
245 value = getattr(calendar, attr)
246 self.assertEqual(len(value), 7)
247 self.assertEqual(len(value[:]), 7)
248 # ensure they're all unique
Tim Petersbbc0d442004-11-13 16:18:32 +0000249 self.assertEqual(len(set(value)), 7)
250 # verify it "acts like a sequence" in two forms of iteration
251 self.assertEqual(value[::-1], list(reversed(value)))
Tim Peters0c2c8e72002-03-23 03:26:53 +0000252
253 def test_months(self):
254 for attr in "month_name", "month_abbr":
255 value = getattr(calendar, attr)
256 self.assertEqual(len(value), 13)
257 self.assertEqual(len(value[:]), 13)
258 self.assertEqual(value[0], "")
259 # ensure they're all unique
Tim Petersbbc0d442004-11-13 16:18:32 +0000260 self.assertEqual(len(set(value)), 13)
261 # verify it "acts like a sequence" in two forms of iteration
262 self.assertEqual(value[::-1], list(reversed(value)))
Tim Peters0c2c8e72002-03-23 03:26:53 +0000263
Georg Brandl79f096a2010-11-26 07:57:57 +0000264 def test_localecalendars(self):
265 # ensure that Locale{Text,HTML}Calendar resets the locale properly
266 # (it is still not thread-safe though)
Georg Brandl79f096a2010-11-26 07:57:57 +0000267 old_october = calendar.TextCalendar().formatmonthname(2010, 10, 10)
Georg Brandl837fbb02010-11-26 07:58:55 +0000268 try:
Serhiy Storchaka8d510cd2013-01-31 15:57:51 +0200269 cal = calendar.LocaleTextCalendar(locale='')
270 local_weekday = cal.formatweekday(1, 10)
271 local_month = cal.formatmonthname(2010, 10, 10)
Georg Brandl837fbb02010-11-26 07:58:55 +0000272 except locale.Error:
273 # cannot set the system default locale -- skip rest of test
Serhiy Storchaka8d510cd2013-01-31 15:57:51 +0200274 raise unittest.SkipTest('cannot set the system default locale')
275 # should be encodable
276 local_weekday.encode('utf-8')
277 local_month.encode('utf-8')
278 self.assertEqual(len(local_weekday), 10)
279 self.assertGreaterEqual(len(local_month), 10)
280 cal = calendar.LocaleHTMLCalendar(locale='')
281 local_weekday = cal.formatweekday(1)
282 local_month = cal.formatmonthname(2010, 10)
283 # should be encodable
284 local_weekday.encode('utf-8')
285 local_month.encode('utf-8')
Georg Brandl79f096a2010-11-26 07:57:57 +0000286 new_october = calendar.TextCalendar().formatmonthname(2010, 10, 10)
Serhiy Storchaka88761452012-12-28 00:32:19 +0200287 self.assertEqual(old_october, new_october)
Georg Brandl79f096a2010-11-26 07:57:57 +0000288
Ezio Melotticadff702012-09-21 17:26:35 +0300289 def test_itermonthdates(self):
290 # ensure itermonthdates doesn't overflow after datetime.MAXYEAR
291 # see #15421
292 list(calendar.Calendar().itermonthdates(datetime.MAXYEAR, 12))
293
Walter Dörwald59ad4562004-07-02 19:00:09 +0000294
295class MonthCalendarTestCase(unittest.TestCase):
296 def setUp(self):
297 self.oldfirstweekday = calendar.firstweekday()
298 calendar.setfirstweekday(self.firstweekday)
299
300 def tearDown(self):
301 calendar.setfirstweekday(self.oldfirstweekday)
302
303 def check_weeks(self, year, month, weeks):
304 cal = calendar.monthcalendar(year, month)
305 self.assertEqual(len(cal), len(weeks))
306 for i in xrange(len(weeks)):
307 self.assertEqual(weeks[i], sum(day != 0 for day in cal[i]))
308
309
310class MondayTestCase(MonthCalendarTestCase):
311 firstweekday = calendar.MONDAY
312
313 def test_february(self):
Walter Dörwald58917a62006-03-31 15:26:22 +0000314 # A 28-day february starting on monday (7+7+7+7 days)
Walter Dörwald59ad4562004-07-02 19:00:09 +0000315 self.check_weeks(1999, 2, (7, 7, 7, 7))
316
Walter Dörwald58917a62006-03-31 15:26:22 +0000317 # A 28-day february starting on tuesday (6+7+7+7+1 days)
Walter Dörwald59ad4562004-07-02 19:00:09 +0000318 self.check_weeks(2005, 2, (6, 7, 7, 7, 1))
319
Walter Dörwald58917a62006-03-31 15:26:22 +0000320 # A 28-day february starting on sunday (1+7+7+7+6 days)
Walter Dörwald59ad4562004-07-02 19:00:09 +0000321 self.check_weeks(1987, 2, (1, 7, 7, 7, 6))
322
Walter Dörwald58917a62006-03-31 15:26:22 +0000323 # A 29-day february starting on monday (7+7+7+7+1 days)
Walter Dörwald59ad4562004-07-02 19:00:09 +0000324 self.check_weeks(1988, 2, (7, 7, 7, 7, 1))
325
Walter Dörwald58917a62006-03-31 15:26:22 +0000326 # A 29-day february starting on tuesday (6+7+7+7+2 days)
Walter Dörwald59ad4562004-07-02 19:00:09 +0000327 self.check_weeks(1972, 2, (6, 7, 7, 7, 2))
328
Walter Dörwald58917a62006-03-31 15:26:22 +0000329 # A 29-day february starting on sunday (1+7+7+7+7 days)
Walter Dörwald59ad4562004-07-02 19:00:09 +0000330 self.check_weeks(2004, 2, (1, 7, 7, 7, 7))
331
332 def test_april(self):
Walter Dörwald58917a62006-03-31 15:26:22 +0000333 # A 30-day april starting on monday (7+7+7+7+2 days)
Walter Dörwald59ad4562004-07-02 19:00:09 +0000334 self.check_weeks(1935, 4, (7, 7, 7, 7, 2))
335
Walter Dörwald58917a62006-03-31 15:26:22 +0000336 # A 30-day april starting on tuesday (6+7+7+7+3 days)
Walter Dörwald59ad4562004-07-02 19:00:09 +0000337 self.check_weeks(1975, 4, (6, 7, 7, 7, 3))
338
Walter Dörwald58917a62006-03-31 15:26:22 +0000339 # A 30-day april starting on sunday (1+7+7+7+7+1 days)
Walter Dörwald59ad4562004-07-02 19:00:09 +0000340 self.check_weeks(1945, 4, (1, 7, 7, 7, 7, 1))
341
Walter Dörwald58917a62006-03-31 15:26:22 +0000342 # A 30-day april starting on saturday (2+7+7+7+7 days)
Walter Dörwald59ad4562004-07-02 19:00:09 +0000343 self.check_weeks(1995, 4, (2, 7, 7, 7, 7))
344
Walter Dörwald58917a62006-03-31 15:26:22 +0000345 # A 30-day april starting on friday (3+7+7+7+6 days)
Walter Dörwald59ad4562004-07-02 19:00:09 +0000346 self.check_weeks(1994, 4, (3, 7, 7, 7, 6))
347
348 def test_december(self):
Walter Dörwald58917a62006-03-31 15:26:22 +0000349 # A 31-day december starting on monday (7+7+7+7+3 days)
Walter Dörwald59ad4562004-07-02 19:00:09 +0000350 self.check_weeks(1980, 12, (7, 7, 7, 7, 3))
351
Walter Dörwald58917a62006-03-31 15:26:22 +0000352 # A 31-day december starting on tuesday (6+7+7+7+4 days)
Walter Dörwald59ad4562004-07-02 19:00:09 +0000353 self.check_weeks(1987, 12, (6, 7, 7, 7, 4))
354
Walter Dörwald58917a62006-03-31 15:26:22 +0000355 # A 31-day december starting on sunday (1+7+7+7+7+2 days)
Walter Dörwald59ad4562004-07-02 19:00:09 +0000356 self.check_weeks(1968, 12, (1, 7, 7, 7, 7, 2))
357
Walter Dörwald58917a62006-03-31 15:26:22 +0000358 # A 31-day december starting on thursday (4+7+7+7+6 days)
Walter Dörwald59ad4562004-07-02 19:00:09 +0000359 self.check_weeks(1988, 12, (4, 7, 7, 7, 6))
360
Walter Dörwald58917a62006-03-31 15:26:22 +0000361 # A 31-day december starting on friday (3+7+7+7+7 days)
Walter Dörwald59ad4562004-07-02 19:00:09 +0000362 self.check_weeks(2017, 12, (3, 7, 7, 7, 7))
363
Walter Dörwald58917a62006-03-31 15:26:22 +0000364 # A 31-day december starting on saturday (2+7+7+7+7+1 days)
Walter Dörwald59ad4562004-07-02 19:00:09 +0000365 self.check_weeks(2068, 12, (2, 7, 7, 7, 7, 1))
366
367
Walter Dörwald302fa6d2004-07-08 17:14:17 +0000368class SundayTestCase(MonthCalendarTestCase):
369 firstweekday = calendar.SUNDAY
370
371 def test_february(self):
Walter Dörwald58917a62006-03-31 15:26:22 +0000372 # A 28-day february starting on sunday (7+7+7+7 days)
Walter Dörwald302fa6d2004-07-08 17:14:17 +0000373 self.check_weeks(2009, 2, (7, 7, 7, 7))
374
Walter Dörwald58917a62006-03-31 15:26:22 +0000375 # A 28-day february starting on monday (6+7+7+7+1 days)
Walter Dörwald302fa6d2004-07-08 17:14:17 +0000376 self.check_weeks(1999, 2, (6, 7, 7, 7, 1))
377
Walter Dörwald58917a62006-03-31 15:26:22 +0000378 # A 28-day february starting on saturday (1+7+7+7+6 days)
Walter Dörwald302fa6d2004-07-08 17:14:17 +0000379 self.check_weeks(1997, 2, (1, 7, 7, 7, 6))
380
Walter Dörwald58917a62006-03-31 15:26:22 +0000381 # A 29-day february starting on sunday (7+7+7+7+1 days)
Walter Dörwald302fa6d2004-07-08 17:14:17 +0000382 self.check_weeks(2004, 2, (7, 7, 7, 7, 1))
383
Walter Dörwald58917a62006-03-31 15:26:22 +0000384 # A 29-day february starting on monday (6+7+7+7+2 days)
Walter Dörwald302fa6d2004-07-08 17:14:17 +0000385 self.check_weeks(1960, 2, (6, 7, 7, 7, 2))
386
Walter Dörwald58917a62006-03-31 15:26:22 +0000387 # A 29-day february starting on saturday (1+7+7+7+7 days)
Walter Dörwald302fa6d2004-07-08 17:14:17 +0000388 self.check_weeks(1964, 2, (1, 7, 7, 7, 7))
389
390 def test_april(self):
Walter Dörwald58917a62006-03-31 15:26:22 +0000391 # A 30-day april starting on sunday (7+7+7+7+2 days)
Walter Dörwald302fa6d2004-07-08 17:14:17 +0000392 self.check_weeks(1923, 4, (7, 7, 7, 7, 2))
393
Walter Dörwald58917a62006-03-31 15:26:22 +0000394 # A 30-day april starting on monday (6+7+7+7+3 days)
Walter Dörwald302fa6d2004-07-08 17:14:17 +0000395 self.check_weeks(1918, 4, (6, 7, 7, 7, 3))
396
Walter Dörwald58917a62006-03-31 15:26:22 +0000397 # A 30-day april starting on saturday (1+7+7+7+7+1 days)
Walter Dörwald302fa6d2004-07-08 17:14:17 +0000398 self.check_weeks(1950, 4, (1, 7, 7, 7, 7, 1))
399
Walter Dörwald58917a62006-03-31 15:26:22 +0000400 # A 30-day april starting on friday (2+7+7+7+7 days)
Walter Dörwald302fa6d2004-07-08 17:14:17 +0000401 self.check_weeks(1960, 4, (2, 7, 7, 7, 7))
402
Walter Dörwald58917a62006-03-31 15:26:22 +0000403 # A 30-day april starting on thursday (3+7+7+7+6 days)
Walter Dörwald302fa6d2004-07-08 17:14:17 +0000404 self.check_weeks(1909, 4, (3, 7, 7, 7, 6))
405
406 def test_december(self):
Walter Dörwald58917a62006-03-31 15:26:22 +0000407 # A 31-day december starting on sunday (7+7+7+7+3 days)
Walter Dörwald302fa6d2004-07-08 17:14:17 +0000408 self.check_weeks(2080, 12, (7, 7, 7, 7, 3))
409
Walter Dörwald58917a62006-03-31 15:26:22 +0000410 # A 31-day december starting on monday (6+7+7+7+4 days)
Walter Dörwald302fa6d2004-07-08 17:14:17 +0000411 self.check_weeks(1941, 12, (6, 7, 7, 7, 4))
412
Walter Dörwald58917a62006-03-31 15:26:22 +0000413 # A 31-day december starting on saturday (1+7+7+7+7+2 days)
Walter Dörwald302fa6d2004-07-08 17:14:17 +0000414 self.check_weeks(1923, 12, (1, 7, 7, 7, 7, 2))
415
Walter Dörwald58917a62006-03-31 15:26:22 +0000416 # A 31-day december starting on wednesday (4+7+7+7+6 days)
Walter Dörwald302fa6d2004-07-08 17:14:17 +0000417 self.check_weeks(1948, 12, (4, 7, 7, 7, 6))
418
Walter Dörwald58917a62006-03-31 15:26:22 +0000419 # A 31-day december starting on thursday (3+7+7+7+7 days)
Walter Dörwald302fa6d2004-07-08 17:14:17 +0000420 self.check_weeks(1927, 12, (3, 7, 7, 7, 7))
421
Walter Dörwald58917a62006-03-31 15:26:22 +0000422 # A 31-day december starting on friday (2+7+7+7+7+1 days)
Walter Dörwald302fa6d2004-07-08 17:14:17 +0000423 self.check_weeks(1995, 12, (2, 7, 7, 7, 7, 1))
424
425
R. David Murrayc45d7992010-12-31 19:31:48 +0000426class MonthRangeTestCase(unittest.TestCase):
427 def test_january(self):
428 # Tests valid lower boundary case.
429 self.assertEqual(calendar.monthrange(2004,1), (3,31))
430
431 def test_february_leap(self):
432 # Tests February during leap year.
433 self.assertEqual(calendar.monthrange(2004,2), (6,29))
434
435 def test_february_nonleap(self):
436 # Tests February in non-leap year.
437 self.assertEqual(calendar.monthrange(2010,2), (0,28))
438
439 def test_december(self):
440 # Tests valid upper boundary case.
441 self.assertEqual(calendar.monthrange(2004,12), (2,31))
442
443 def test_zeroth_month(self):
444 # Tests low invalid boundary case.
445 with self.assertRaises(calendar.IllegalMonthError):
446 calendar.monthrange(2004, 0)
447
448 def test_thirteenth_month(self):
449 # Tests high invalid boundary case.
450 with self.assertRaises(calendar.IllegalMonthError):
451 calendar.monthrange(2004, 13)
452
453class LeapdaysTestCase(unittest.TestCase):
454 def test_no_range(self):
455 # test when no range i.e. two identical years as args
456 self.assertEqual(calendar.leapdays(2010,2010), 0)
457
458 def test_no_leapdays(self):
459 # test when no leap years in range
460 self.assertEqual(calendar.leapdays(2010,2011), 0)
461
462 def test_no_leapdays_upper_boundary(self):
463 # test no leap years in range, when upper boundary is a leap year
464 self.assertEqual(calendar.leapdays(2010,2012), 0)
465
466 def test_one_leapday_lower_boundary(self):
467 # test when one leap year in range, lower boundary is leap year
468 self.assertEqual(calendar.leapdays(2012,2013), 1)
469
470 def test_several_leapyears_in_range(self):
471 self.assertEqual(calendar.leapdays(1997,2020), 5)
472
473
Serhiy Storchakadbd85aa2015-02-05 18:03:27 +0200474def conv(s):
475 return s.replace('\n', os.linesep)
476
Serhiy Storchakad44bcc92015-02-05 15:18:26 +0200477class CommandLineTestCase(unittest.TestCase):
478 def run_ok(self, *args):
479 return assert_python_ok('-m', 'calendar', *args)[1]
480
481 def assertFailure(self, *args):
482 rc, stdout, stderr = assert_python_failure('-m', 'calendar', *args)
483 self.assertIn(b'Usage:', stderr)
484 self.assertEqual(rc, 2)
485
486 def test_help(self):
487 stdout = self.run_ok('-h')
488 self.assertIn(b'Usage:', stdout)
489 self.assertIn(b'calendar.py', stdout)
490 self.assertIn(b'--help', stdout)
491
492 def test_illegal_arguments(self):
493 self.assertFailure('-z')
494 #self.assertFailure('spam')
495 #self.assertFailure('2004', 'spam')
496 self.assertFailure('-t', 'html', '2004', '1')
497
498 def test_output_current_year(self):
499 stdout = self.run_ok()
500 year = datetime.datetime.now().year
501 self.assertIn((' %s' % year).encode(), stdout)
502 self.assertIn(b'January', stdout)
503 self.assertIn(b'Mo Tu We Th Fr Sa Su', stdout)
504
505 def test_output_year(self):
506 stdout = self.run_ok('2004')
Serhiy Storchakadbd85aa2015-02-05 18:03:27 +0200507 self.assertEqual(stdout.strip(), conv(result_2004_text).strip())
Serhiy Storchakad44bcc92015-02-05 15:18:26 +0200508
509 def test_output_month(self):
510 stdout = self.run_ok('2004', '1')
Serhiy Storchakadbd85aa2015-02-05 18:03:27 +0200511 self.assertEqual(stdout.strip(), conv(result_2004_01_text).strip())
Serhiy Storchakad44bcc92015-02-05 15:18:26 +0200512
513 def test_option_encoding(self):
514 self.assertFailure('-e')
515 self.assertFailure('--encoding')
516 stdout = self.run_ok('--encoding', 'rot-13', '2004')
Serhiy Storchakadbd85aa2015-02-05 18:03:27 +0200517 self.assertEqual(stdout.strip(), conv(result_2004_text.encode('rot-13')).strip())
Serhiy Storchakad44bcc92015-02-05 15:18:26 +0200518
519 def test_option_locale(self):
520 self.assertFailure('-L')
521 self.assertFailure('--locale')
522 self.assertFailure('-L', 'en')
523 lang, enc = locale.getdefaultlocale()
524 lang = lang or 'C'
525 enc = enc or 'UTF-8'
526 try:
527 oldlocale = locale.getlocale(locale.LC_TIME)
528 try:
529 locale.setlocale(locale.LC_TIME, (lang, enc))
530 finally:
531 locale.setlocale(locale.LC_TIME, oldlocale)
532 except (locale.Error, ValueError):
533 self.skipTest('cannot set the system default locale')
534 stdout = self.run_ok('--locale', lang, '--encoding', enc, '2004')
535 self.assertIn('2004'.encode(enc), stdout)
536
537 def test_option_width(self):
538 self.assertFailure('-w')
539 self.assertFailure('--width')
540 self.assertFailure('-w', 'spam')
541 stdout = self.run_ok('--width', '3', '2004')
542 self.assertIn(b'Mon Tue Wed Thu Fri Sat Sun', stdout)
543
544 def test_option_lines(self):
545 self.assertFailure('-l')
546 self.assertFailure('--lines')
547 self.assertFailure('-l', 'spam')
548 stdout = self.run_ok('--lines', '2', '2004')
Serhiy Storchakadbd85aa2015-02-05 18:03:27 +0200549 self.assertIn(conv('December\n\nMo Tu We'), stdout)
Serhiy Storchakad44bcc92015-02-05 15:18:26 +0200550
551 def test_option_spacing(self):
552 self.assertFailure('-s')
553 self.assertFailure('--spacing')
554 self.assertFailure('-s', 'spam')
555 stdout = self.run_ok('--spacing', '8', '2004')
556 self.assertIn(b'Su Mo', stdout)
557
558 def test_option_months(self):
559 self.assertFailure('-m')
560 self.assertFailure('--month')
561 self.assertFailure('-m', 'spam')
562 stdout = self.run_ok('--months', '1', '2004')
Serhiy Storchakadbd85aa2015-02-05 18:03:27 +0200563 self.assertIn(conv('\nMo Tu We Th Fr Sa Su\n'), stdout)
Serhiy Storchakad44bcc92015-02-05 15:18:26 +0200564
565 def test_option_type(self):
566 self.assertFailure('-t')
567 self.assertFailure('--type')
568 self.assertFailure('-t', 'spam')
569 stdout = self.run_ok('--type', 'text', '2004')
Serhiy Storchakadbd85aa2015-02-05 18:03:27 +0200570 self.assertEqual(stdout.strip(), conv(result_2004_text).strip())
Serhiy Storchakad44bcc92015-02-05 15:18:26 +0200571 stdout = self.run_ok('--type', 'html', '2004')
572 self.assertEqual(stdout[:6], b'<?xml ')
573 self.assertIn(b'<title>Calendar for 2004</title>', stdout)
574
575 def test_html_output_current_year(self):
576 stdout = self.run_ok('--type', 'html')
577 year = datetime.datetime.now().year
578 self.assertIn(('<title>Calendar for %s</title>' % year).encode(),
579 stdout)
580 self.assertIn(b'<tr><th colspan="7" class="month">January</th></tr>',
581 stdout)
582
583 def test_html_output_year_encoding(self):
584 stdout = self.run_ok('-t', 'html', '--encoding', 'ascii', '2004')
Serhiy Storchakadbd85aa2015-02-05 18:03:27 +0200585 self.assertEqual(stdout.strip(), conv(result_2004_html).strip())
Serhiy Storchakad44bcc92015-02-05 15:18:26 +0200586
587 def test_html_output_year_css(self):
588 self.assertFailure('-t', 'html', '-c')
589 self.assertFailure('-t', 'html', '--css')
590 stdout = self.run_ok('-t', 'html', '--css', 'custom.css', '2004')
591 self.assertIn(b'<link rel="stylesheet" type="text/css" '
592 b'href="custom.css" />', stdout)
593
594
Fred Draked077ca12001-12-12 05:38:08 +0000595def test_main():
Walter Dörwald59ad4562004-07-02 19:00:09 +0000596 test_support.run_unittest(
Walter Dörwald58917a62006-03-31 15:26:22 +0000597 OutputTestCase,
Walter Dörwald59ad4562004-07-02 19:00:09 +0000598 CalendarTestCase,
Walter Dörwald302fa6d2004-07-08 17:14:17 +0000599 MondayTestCase,
R. David Murrayc45d7992010-12-31 19:31:48 +0000600 SundayTestCase,
601 MonthRangeTestCase,
602 LeapdaysTestCase,
Serhiy Storchakad44bcc92015-02-05 15:18:26 +0200603 CommandLineTestCase,
Walter Dörwald59ad4562004-07-02 19:00:09 +0000604 )
605
Fred Draked077ca12001-12-12 05:38:08 +0000606
607if __name__ == "__main__":
608 test_main()
Serhiy Storchakad44bcc92015-02-05 15:18:26 +0200609 unittest.main()