1import calendar 2import unittest 3 4from test import test_support 5from test.script_helper import assert_python_ok, assert_python_failure 6import locale 7import datetime 8import os 9 10result_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""" 19 20result_2004_text = """\ 21 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 58result_2004_html = """\ 59<?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" /> 65<title>Calendar for 2004</title> 66</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"> </td><td class="noday"> </td><td class="noday"> </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"> </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"> </td><td class="noday"> </td><td class="noday"> </td><td class="noday"> </td><td class="noday"> </td><td class="noday"> </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"> </td><td class="noday"> </td><td class="noday"> </td><td class="noday"> </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"> </td><td class="noday"> </td><td class="noday"> </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"> </td><td class="noday"> </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"> </td><td class="noday"> </td><td class="noday"> </td><td class="noday"> </td><td class="noday"> </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"> </td><td class="noday"> </td><td class="noday"> </td><td class="noday"> </td><td class="noday"> </td><td class="noday"> </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"> </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"> </td><td class="noday"> </td><td class="noday"> </td><td class="noday"> </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"> </td><td class="noday"> </td><td class="noday"> </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"> </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"> </td><td class="noday"> </td><td class="noday"> </td><td class="noday"> </td><td class="noday"> </td><td class="noday"> </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"> </td><td class="noday"> </td><td class="noday"> </td><td class="noday"> </td><td class="noday"> </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"> </td><td class="noday"> </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"> </td><td class="noday"> </td><td class="noday"> </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"> </td><td class="noday"> </td><td class="noday"> </td><td class="noday"> </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"> </td><td class="noday"> </td><td class="noday"> </td><td class="noday"> </td><td class="noday"> </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"> </td><td class="noday"> </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"> </td><td class="noday"> </td></tr> 178</table> 179</td></tr></table></body> 180</html> 181""" 182 183 184class OutputTestCase(unittest.TestCase): 185 def normalize_calendar(self, s): 186 # Filters out locale dependent strings 187 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)), 200 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() 213 ) 214 215 216class 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): 228 self.assertRaises(ValueError, calendar.setfirstweekday, 'flabber') 229 self.assertRaises(ValueError, calendar.setfirstweekday, -1) 230 self.assertRaises(ValueError, calendar.setfirstweekday, 200) 231 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 238 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) 242 243 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 249 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))) 252 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 260 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))) 263 264 def test_localecalendars(self): 265 # ensure that Locale{Text,HTML}Calendar resets the locale properly 266 # (it is still not thread-safe though) 267 old_october = calendar.TextCalendar().formatmonthname(2010, 10, 10) 268 try: 269 cal = calendar.LocaleTextCalendar(locale='') 270 local_weekday = cal.formatweekday(1, 10) 271 local_month = cal.formatmonthname(2010, 10, 10) 272 except locale.Error: 273 # cannot set the system default locale -- skip rest of test 274 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') 286 new_october = calendar.TextCalendar().formatmonthname(2010, 10, 10) 287 self.assertEqual(old_october, new_october) 288 289 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 294 def test_itermonthdays(self): 295 for firstweekday in range(7): 296 cal = calendar.Calendar(firstweekday) 297 # Test the extremes, see #28253 and #26650 298 for y, m in [(1, 1), (9999, 12)]: 299 days = list(cal.itermonthdays(y, m)) 300 self.assertIn(len(days), (35, 42)) 301 # Test a short month 302 cal = calendar.Calendar(firstweekday=3) 303 days = list(cal.itermonthdays(2001, 2)) 304 self.assertEqual(days, list(range(1, 29))) 305 306 def test_itermonthdays2(self): 307 for firstweekday in range(7): 308 cal = calendar.Calendar(firstweekday) 309 # Test the extremes, see #28253 and #26650 310 for y, m in [(1, 1), (9999, 12)]: 311 days = list(cal.itermonthdays2(y, m)) 312 self.assertEqual(days[0][1], firstweekday) 313 self.assertEqual(days[-1][1], (firstweekday - 1) % 7) 314 315 316class MonthCalendarTestCase(unittest.TestCase): 317 def setUp(self): 318 self.oldfirstweekday = calendar.firstweekday() 319 calendar.setfirstweekday(self.firstweekday) 320 321 def tearDown(self): 322 calendar.setfirstweekday(self.oldfirstweekday) 323 324 def check_weeks(self, year, month, weeks): 325 cal = calendar.monthcalendar(year, month) 326 self.assertEqual(len(cal), len(weeks)) 327 for i in xrange(len(weeks)): 328 self.assertEqual(weeks[i], sum(day != 0 for day in cal[i])) 329 330 331class MondayTestCase(MonthCalendarTestCase): 332 firstweekday = calendar.MONDAY 333 334 def test_february(self): 335 # A 28-day february starting on monday (7+7+7+7 days) 336 self.check_weeks(1999, 2, (7, 7, 7, 7)) 337 338 # A 28-day february starting on tuesday (6+7+7+7+1 days) 339 self.check_weeks(2005, 2, (6, 7, 7, 7, 1)) 340 341 # A 28-day february starting on sunday (1+7+7+7+6 days) 342 self.check_weeks(1987, 2, (1, 7, 7, 7, 6)) 343 344 # A 29-day february starting on monday (7+7+7+7+1 days) 345 self.check_weeks(1988, 2, (7, 7, 7, 7, 1)) 346 347 # A 29-day february starting on tuesday (6+7+7+7+2 days) 348 self.check_weeks(1972, 2, (6, 7, 7, 7, 2)) 349 350 # A 29-day february starting on sunday (1+7+7+7+7 days) 351 self.check_weeks(2004, 2, (1, 7, 7, 7, 7)) 352 353 def test_april(self): 354 # A 30-day april starting on monday (7+7+7+7+2 days) 355 self.check_weeks(1935, 4, (7, 7, 7, 7, 2)) 356 357 # A 30-day april starting on tuesday (6+7+7+7+3 days) 358 self.check_weeks(1975, 4, (6, 7, 7, 7, 3)) 359 360 # A 30-day april starting on sunday (1+7+7+7+7+1 days) 361 self.check_weeks(1945, 4, (1, 7, 7, 7, 7, 1)) 362 363 # A 30-day april starting on saturday (2+7+7+7+7 days) 364 self.check_weeks(1995, 4, (2, 7, 7, 7, 7)) 365 366 # A 30-day april starting on friday (3+7+7+7+6 days) 367 self.check_weeks(1994, 4, (3, 7, 7, 7, 6)) 368 369 def test_december(self): 370 # A 31-day december starting on monday (7+7+7+7+3 days) 371 self.check_weeks(1980, 12, (7, 7, 7, 7, 3)) 372 373 # A 31-day december starting on tuesday (6+7+7+7+4 days) 374 self.check_weeks(1987, 12, (6, 7, 7, 7, 4)) 375 376 # A 31-day december starting on sunday (1+7+7+7+7+2 days) 377 self.check_weeks(1968, 12, (1, 7, 7, 7, 7, 2)) 378 379 # A 31-day december starting on thursday (4+7+7+7+6 days) 380 self.check_weeks(1988, 12, (4, 7, 7, 7, 6)) 381 382 # A 31-day december starting on friday (3+7+7+7+7 days) 383 self.check_weeks(2017, 12, (3, 7, 7, 7, 7)) 384 385 # A 31-day december starting on saturday (2+7+7+7+7+1 days) 386 self.check_weeks(2068, 12, (2, 7, 7, 7, 7, 1)) 387 388 389class SundayTestCase(MonthCalendarTestCase): 390 firstweekday = calendar.SUNDAY 391 392 def test_february(self): 393 # A 28-day february starting on sunday (7+7+7+7 days) 394 self.check_weeks(2009, 2, (7, 7, 7, 7)) 395 396 # A 28-day february starting on monday (6+7+7+7+1 days) 397 self.check_weeks(1999, 2, (6, 7, 7, 7, 1)) 398 399 # A 28-day february starting on saturday (1+7+7+7+6 days) 400 self.check_weeks(1997, 2, (1, 7, 7, 7, 6)) 401 402 # A 29-day february starting on sunday (7+7+7+7+1 days) 403 self.check_weeks(2004, 2, (7, 7, 7, 7, 1)) 404 405 # A 29-day february starting on monday (6+7+7+7+2 days) 406 self.check_weeks(1960, 2, (6, 7, 7, 7, 2)) 407 408 # A 29-day february starting on saturday (1+7+7+7+7 days) 409 self.check_weeks(1964, 2, (1, 7, 7, 7, 7)) 410 411 def test_april(self): 412 # A 30-day april starting on sunday (7+7+7+7+2 days) 413 self.check_weeks(1923, 4, (7, 7, 7, 7, 2)) 414 415 # A 30-day april starting on monday (6+7+7+7+3 days) 416 self.check_weeks(1918, 4, (6, 7, 7, 7, 3)) 417 418 # A 30-day april starting on saturday (1+7+7+7+7+1 days) 419 self.check_weeks(1950, 4, (1, 7, 7, 7, 7, 1)) 420 421 # A 30-day april starting on friday (2+7+7+7+7 days) 422 self.check_weeks(1960, 4, (2, 7, 7, 7, 7)) 423 424 # A 30-day april starting on thursday (3+7+7+7+6 days) 425 self.check_weeks(1909, 4, (3, 7, 7, 7, 6)) 426 427 def test_december(self): 428 # A 31-day december starting on sunday (7+7+7+7+3 days) 429 self.check_weeks(2080, 12, (7, 7, 7, 7, 3)) 430 431 # A 31-day december starting on monday (6+7+7+7+4 days) 432 self.check_weeks(1941, 12, (6, 7, 7, 7, 4)) 433 434 # A 31-day december starting on saturday (1+7+7+7+7+2 days) 435 self.check_weeks(1923, 12, (1, 7, 7, 7, 7, 2)) 436 437 # A 31-day december starting on wednesday (4+7+7+7+6 days) 438 self.check_weeks(1948, 12, (4, 7, 7, 7, 6)) 439 440 # A 31-day december starting on thursday (3+7+7+7+7 days) 441 self.check_weeks(1927, 12, (3, 7, 7, 7, 7)) 442 443 # A 31-day december starting on friday (2+7+7+7+7+1 days) 444 self.check_weeks(1995, 12, (2, 7, 7, 7, 7, 1)) 445 446 447class MonthRangeTestCase(unittest.TestCase): 448 def test_january(self): 449 # Tests valid lower boundary case. 450 self.assertEqual(calendar.monthrange(2004,1), (3,31)) 451 452 def test_february_leap(self): 453 # Tests February during leap year. 454 self.assertEqual(calendar.monthrange(2004,2), (6,29)) 455 456 def test_february_nonleap(self): 457 # Tests February in non-leap year. 458 self.assertEqual(calendar.monthrange(2010,2), (0,28)) 459 460 def test_december(self): 461 # Tests valid upper boundary case. 462 self.assertEqual(calendar.monthrange(2004,12), (2,31)) 463 464 def test_zeroth_month(self): 465 # Tests low invalid boundary case. 466 with self.assertRaises(calendar.IllegalMonthError): 467 calendar.monthrange(2004, 0) 468 469 def test_thirteenth_month(self): 470 # Tests high invalid boundary case. 471 with self.assertRaises(calendar.IllegalMonthError): 472 calendar.monthrange(2004, 13) 473 474class LeapdaysTestCase(unittest.TestCase): 475 def test_no_range(self): 476 # test when no range i.e. two identical years as args 477 self.assertEqual(calendar.leapdays(2010,2010), 0) 478 479 def test_no_leapdays(self): 480 # test when no leap years in range 481 self.assertEqual(calendar.leapdays(2010,2011), 0) 482 483 def test_no_leapdays_upper_boundary(self): 484 # test no leap years in range, when upper boundary is a leap year 485 self.assertEqual(calendar.leapdays(2010,2012), 0) 486 487 def test_one_leapday_lower_boundary(self): 488 # test when one leap year in range, lower boundary is leap year 489 self.assertEqual(calendar.leapdays(2012,2013), 1) 490 491 def test_several_leapyears_in_range(self): 492 self.assertEqual(calendar.leapdays(1997,2020), 5) 493 494 495def conv(s): 496 return s.replace('\n', os.linesep) 497 498class CommandLineTestCase(unittest.TestCase): 499 def run_ok(self, *args): 500 return assert_python_ok('-m', 'calendar', *args)[1] 501 502 def assertFailure(self, *args): 503 rc, stdout, stderr = assert_python_failure('-m', 'calendar', *args) 504 self.assertIn(b'Usage:', stderr) 505 self.assertEqual(rc, 2) 506 507 def test_help(self): 508 stdout = self.run_ok('-h') 509 self.assertIn(b'Usage:', stdout) 510 self.assertIn(b'calendar.py', stdout) 511 self.assertIn(b'--help', stdout) 512 513 def test_illegal_arguments(self): 514 self.assertFailure('-z') 515 #self.assertFailure('spam') 516 #self.assertFailure('2004', 'spam') 517 self.assertFailure('-t', 'html', '2004', '1') 518 519 def test_output_current_year(self): 520 stdout = self.run_ok() 521 year = datetime.datetime.now().year 522 self.assertIn((' %s' % year).encode(), stdout) 523 self.assertIn(b'January', stdout) 524 self.assertIn(b'Mo Tu We Th Fr Sa Su', stdout) 525 526 def test_output_year(self): 527 stdout = self.run_ok('2004') 528 self.assertEqual(stdout.strip(), conv(result_2004_text).strip()) 529 530 def test_output_month(self): 531 stdout = self.run_ok('2004', '1') 532 self.assertEqual(stdout.strip(), conv(result_2004_01_text).strip()) 533 534 def test_option_encoding(self): 535 self.assertFailure('-e') 536 self.assertFailure('--encoding') 537 stdout = self.run_ok('--encoding', 'utf-16-le', '2004') 538 self.assertEqual(stdout.strip(), conv(result_2004_text.encode('utf-16-le')).strip()) 539 540 def test_option_locale(self): 541 self.assertFailure('-L') 542 self.assertFailure('--locale') 543 self.assertFailure('-L', 'en') 544 lang, enc = locale.getdefaultlocale() 545 lang = lang or 'C' 546 enc = enc or 'UTF-8' 547 try: 548 oldlocale = locale.getlocale(locale.LC_TIME) 549 try: 550 locale.setlocale(locale.LC_TIME, (lang, enc)) 551 finally: 552 locale.setlocale(locale.LC_TIME, oldlocale) 553 except (locale.Error, ValueError): 554 self.skipTest('cannot set the system default locale') 555 stdout = self.run_ok('--locale', lang, '--encoding', enc, '2004') 556 self.assertIn('2004'.encode(enc), stdout) 557 558 def test_option_width(self): 559 self.assertFailure('-w') 560 self.assertFailure('--width') 561 self.assertFailure('-w', 'spam') 562 stdout = self.run_ok('--width', '3', '2004') 563 self.assertIn(b'Mon Tue Wed Thu Fri Sat Sun', stdout) 564 565 def test_option_lines(self): 566 self.assertFailure('-l') 567 self.assertFailure('--lines') 568 self.assertFailure('-l', 'spam') 569 stdout = self.run_ok('--lines', '2', '2004') 570 self.assertIn(conv('December\n\nMo Tu We'), stdout) 571 572 def test_option_spacing(self): 573 self.assertFailure('-s') 574 self.assertFailure('--spacing') 575 self.assertFailure('-s', 'spam') 576 stdout = self.run_ok('--spacing', '8', '2004') 577 self.assertIn(b'Su Mo', stdout) 578 579 def test_option_months(self): 580 self.assertFailure('-m') 581 self.assertFailure('--month') 582 self.assertFailure('-m', 'spam') 583 stdout = self.run_ok('--months', '1', '2004') 584 self.assertIn(conv('\nMo Tu We Th Fr Sa Su\n'), stdout) 585 586 def test_option_type(self): 587 self.assertFailure('-t') 588 self.assertFailure('--type') 589 self.assertFailure('-t', 'spam') 590 stdout = self.run_ok('--type', 'text', '2004') 591 self.assertEqual(stdout.strip(), conv(result_2004_text).strip()) 592 stdout = self.run_ok('--type', 'html', '2004') 593 self.assertEqual(stdout[:6], b'<?xml ') 594 self.assertIn(b'<title>Calendar for 2004</title>', stdout) 595 596 def test_html_output_current_year(self): 597 stdout = self.run_ok('--type', 'html') 598 year = datetime.datetime.now().year 599 self.assertIn(('<title>Calendar for %s</title>' % year).encode(), 600 stdout) 601 self.assertIn(b'<tr><th colspan="7" class="month">January</th></tr>', 602 stdout) 603 604 def test_html_output_year_encoding(self): 605 stdout = self.run_ok('-t', 'html', '--encoding', 'ascii', '2004') 606 self.assertEqual(stdout.strip(), conv(result_2004_html).strip()) 607 608 def test_html_output_year_css(self): 609 self.assertFailure('-t', 'html', '-c') 610 self.assertFailure('-t', 'html', '--css') 611 stdout = self.run_ok('-t', 'html', '--css', 'custom.css', '2004') 612 self.assertIn(b'<link rel="stylesheet" type="text/css" ' 613 b'href="custom.css" />', stdout) 614 615 616def test_main(): 617 test_support.run_unittest( 618 OutputTestCase, 619 CalendarTestCase, 620 MondayTestCase, 621 SundayTestCase, 622 MonthRangeTestCase, 623 LeapdaysTestCase, 624 CommandLineTestCase, 625 ) 626 627 628if __name__ == "__main__": 629 test_main() 630 unittest.main() 631