1 import calendar 2 import unittest 3 4 from test import test_support 5 import locale 6 import datetime 7 8 9 result_2004_text = """ 10 2004 11 12 January February March 13 Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su 14 1 2 3 4 1 1 2 3 4 5 6 7 15 5 6 7 8 9 10 11 2 3 4 5 6 7 8 8 9 10 11 12 13 14 16 12 13 14 15 16 17 18 9 10 11 12 13 14 15 15 16 17 18 19 20 21 17 19 20 21 22 23 24 25 16 17 18 19 20 21 22 22 23 24 25 26 27 28 18 26 27 28 29 30 31 23 24 25 26 27 28 29 29 30 31 19 20 April May June 21 Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su 22 1 2 3 4 1 2 1 2 3 4 5 6 23 5 6 7 8 9 10 11 3 4 5 6 7 8 9 7 8 9 10 11 12 13 24 12 13 14 15 16 17 18 10 11 12 13 14 15 16 14 15 16 17 18 19 20 25 19 20 21 22 23 24 25 17 18 19 20 21 22 23 21 22 23 24 25 26 27 26 26 27 28 29 30 24 25 26 27 28 29 30 28 29 30 27 31 28 29 July August September 30 Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su 31 1 2 3 4 1 1 2 3 4 5 32 5 6 7 8 9 10 11 2 3 4 5 6 7 8 6 7 8 9 10 11 12 33 12 13 14 15 16 17 18 9 10 11 12 13 14 15 13 14 15 16 17 18 19 34 19 20 21 22 23 24 25 16 17 18 19 20 21 22 20 21 22 23 24 25 26 35 26 27 28 29 30 31 23 24 25 26 27 28 29 27 28 29 30 36 30 31 37 38 October November December 39 Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su 40 1 2 3 1 2 3 4 5 6 7 1 2 3 4 5 41 4 5 6 7 8 9 10 8 9 10 11 12 13 14 6 7 8 9 10 11 12 42 11 12 13 14 15 16 17 15 16 17 18 19 20 21 13 14 15 16 17 18 19 43 18 19 20 21 22 23 24 22 23 24 25 26 27 28 20 21 22 23 24 25 26 44 25 26 27 28 29 30 31 29 30 27 28 29 30 31 45 """ 46 47 result_2004_html = """ 48 <?xml version="1.0" encoding="ascii"?> 49 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 50 <html> 51 <head> 52 <meta http-equiv="Content-Type" content="text/html; charset=ascii" /> 53 <link rel="stylesheet" type="text/css" href="calendar.css" /> 54 <title>Calendar for 2004</title> 55 </head> 56 <body> 57 <table border="0" cellpadding="0" cellspacing="0" class="year"> 58 <tr><th colspan="3" class="year">2004</th></tr><tr><td><table border="0" cellpadding="0" cellspacing="0" class="month"> 59 <tr><th colspan="7" class="month">January</th></tr> 60 <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> 61 <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> 62 <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> 63 <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> 64 <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> 65 <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> 66 </table> 67 </td><td><table border="0" cellpadding="0" cellspacing="0" class="month"> 68 <tr><th colspan="7" class="month">February</th></tr> 69 <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> 70 <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> 71 <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> 72 <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> 73 <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> 74 <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> 75 </table> 76 </td><td><table border="0" cellpadding="0" cellspacing="0" class="month"> 77 <tr><th colspan="7" class="month">March</th></tr> 78 <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> 79 <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> 80 <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> 81 <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> 82 <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> 83 <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> 84 </table> 85 </td></tr><tr><td><table border="0" cellpadding="0" cellspacing="0" class="month"> 86 <tr><th colspan="7" class="month">April</th></tr> 87 <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> 88 <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> 89 <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> 90 <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> 91 <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> 92 <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> 93 </table> 94 </td><td><table border="0" cellpadding="0" cellspacing="0" class="month"> 95 <tr><th colspan="7" class="month">May</th></tr> 96 <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> 97 <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> 98 <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> 99 <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> 100 <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> 101 <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> 102 <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> 103 </table> 104 </td><td><table border="0" cellpadding="0" cellspacing="0" class="month"> 105 <tr><th colspan="7" class="month">June</th></tr> 106 <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> 107 <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> 108 <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> 109 <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> 110 <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> 111 <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> 112 </table> 113 </td></tr><tr><td><table border="0" cellpadding="0" cellspacing="0" class="month"> 114 <tr><th colspan="7" class="month">July</th></tr> 115 <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> 116 <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> 117 <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> 118 <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> 119 <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> 120 <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> 121 </table> 122 </td><td><table border="0" cellpadding="0" cellspacing="0" class="month"> 123 <tr><th colspan="7" class="month">August</th></tr> 124 <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> 125 <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> 126 <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> 127 <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> 128 <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> 129 <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> 130 <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> 131 </table> 132 </td><td><table border="0" cellpadding="0" cellspacing="0" class="month"> 133 <tr><th colspan="7" class="month">September</th></tr> 134 <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> 135 <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> 136 <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> 137 <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> 138 <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> 139 <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> 140 </table> 141 </td></tr><tr><td><table border="0" cellpadding="0" cellspacing="0" class="month"> 142 <tr><th colspan="7" class="month">October</th></tr> 143 <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> 144 <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> 145 <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> 146 <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> 147 <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> 148 <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> 149 </table> 150 </td><td><table border="0" cellpadding="0" cellspacing="0" class="month"> 151 <tr><th colspan="7" class="month">November</th></tr> 152 <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> 153 <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> 154 <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> 155 <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> 156 <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> 157 <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> 158 </table> 159 </td><td><table border="0" cellpadding="0" cellspacing="0" class="month"> 160 <tr><th colspan="7" class="month">December</th></tr> 161 <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> 162 <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> 163 <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> 164 <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> 165 <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> 166 <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> 167 </table> 168 </td></tr></table></body> 169 </html> 170 """ 171 172 173 class OutputTestCase(unittest.TestCase): 174 def normalize_calendar(self, s): 175 # Filters out locale dependent strings 176 def neitherspacenordigit(c): 177 return not c.isspace() and not c.isdigit() 178 179 lines = [] 180 for line in s.splitlines(False): 181 # Drop texts, as they are locale dependent 182 if line and not filter(neitherspacenordigit, line): 183 lines.append(line) 184 return lines 185 186 def test_output(self): 187 self.assertEqual( 188 self.normalize_calendar(calendar.calendar(2004)), 189 self.normalize_calendar(result_2004_text) 190 ) 191 192 def test_output_textcalendar(self): 193 self.assertEqual( 194 calendar.TextCalendar().formatyear(2004).strip(), 195 result_2004_text.strip() 196 ) 197 198 def test_output_htmlcalendar(self): 199 self.assertEqual( 200 calendar.HTMLCalendar().formatyearpage(2004).strip(), 201 result_2004_html.strip() 202 ) 203 204 205 class CalendarTestCase(unittest.TestCase): 206 def test_isleap(self): 207 # Make sure that the return is right for a few years, and 208 # ensure that the return values are 1 or 0, not just true or 209 # false (see SF bug #485794). Specific additional tests may 210 # be appropriate; this tests a single "cycle". 211 self.assertEqual(calendar.isleap(2000), 1) 212 self.assertEqual(calendar.isleap(2001), 0) 213 self.assertEqual(calendar.isleap(2002), 0) 214 self.assertEqual(calendar.isleap(2003), 0) 215 216 def test_setfirstweekday(self): 217 self.assertRaises(ValueError, calendar.setfirstweekday, 'flabber') 218 self.assertRaises(ValueError, calendar.setfirstweekday, -1) 219 self.assertRaises(ValueError, calendar.setfirstweekday, 200) 220 orig = calendar.firstweekday() 221 calendar.setfirstweekday(calendar.SUNDAY) 222 self.assertEqual(calendar.firstweekday(), calendar.SUNDAY) 223 calendar.setfirstweekday(calendar.MONDAY) 224 self.assertEqual(calendar.firstweekday(), calendar.MONDAY) 225 calendar.setfirstweekday(orig) 226 227 def test_enumerateweekdays(self): 228 self.assertRaises(IndexError, calendar.day_abbr.__getitem__, -10) 229 self.assertRaises(IndexError, calendar.day_name.__getitem__, 10) 230 self.assertEqual(len([d for d in calendar.day_abbr]), 7) 231 232 def test_days(self): 233 for attr in "day_name", "day_abbr": 234 value = getattr(calendar, attr) 235 self.assertEqual(len(value), 7) 236 self.assertEqual(len(value[:]), 7) 237 # ensure they're all unique 238 self.assertEqual(len(set(value)), 7) 239 # verify it "acts like a sequence" in two forms of iteration 240 self.assertEqual(value[::-1], list(reversed(value))) 241 242 def test_months(self): 243 for attr in "month_name", "month_abbr": 244 value = getattr(calendar, attr) 245 self.assertEqual(len(value), 13) 246 self.assertEqual(len(value[:]), 13) 247 self.assertEqual(value[0], "") 248 # ensure they're all unique 249 self.assertEqual(len(set(value)), 13) 250 # verify it "acts like a sequence" in two forms of iteration 251 self.assertEqual(value[::-1], list(reversed(value))) 252 253 def test_localecalendars(self): 254 # ensure that Locale{Text,HTML}Calendar resets the locale properly 255 # (it is still not thread-safe though) 256 old_october = calendar.TextCalendar().formatmonthname(2010, 10, 10) 257 try: 258 cal = calendar.LocaleTextCalendar(locale='') 259 local_weekday = cal.formatweekday(1, 10) 260 local_month = cal.formatmonthname(2010, 10, 10) 261 except locale.Error: 262 # cannot set the system default locale -- skip rest of test 263 raise unittest.SkipTest('cannot set the system default locale') 264 # should be encodable 265 local_weekday.encode('utf-8') 266 local_month.encode('utf-8') 267 self.assertEqual(len(local_weekday), 10) 268 self.assertGreaterEqual(len(local_month), 10) 269 cal = calendar.LocaleHTMLCalendar(locale='') 270 local_weekday = cal.formatweekday(1) 271 local_month = cal.formatmonthname(2010, 10) 272 # should be encodable 273 local_weekday.encode('utf-8') 274 local_month.encode('utf-8') 275 new_october = calendar.TextCalendar().formatmonthname(2010, 10, 10) 276 self.assertEqual(old_october, new_october) 277 278 def test_itermonthdates(self): 279 # ensure itermonthdates doesn't overflow after datetime.MAXYEAR 280 # see #15421 281 list(calendar.Calendar().itermonthdates(datetime.MAXYEAR, 12)) 282 283 284 class MonthCalendarTestCase(unittest.TestCase): 285 def setUp(self): 286 self.oldfirstweekday = calendar.firstweekday() 287 calendar.setfirstweekday(self.firstweekday) 288 289 def tearDown(self): 290 calendar.setfirstweekday(self.oldfirstweekday) 291 292 def check_weeks(self, year, month, weeks): 293 cal = calendar.monthcalendar(year, month) 294 self.assertEqual(len(cal), len(weeks)) 295 for i in xrange(len(weeks)): 296 self.assertEqual(weeks[i], sum(day != 0 for day in cal[i])) 297 298 299 class MondayTestCase(MonthCalendarTestCase): 300 firstweekday = calendar.MONDAY 301 302 def test_february(self): 303 # A 28-day february starting on monday (7+7+7+7 days) 304 self.check_weeks(1999, 2, (7, 7, 7, 7)) 305 306 # A 28-day february starting on tuesday (6+7+7+7+1 days) 307 self.check_weeks(2005, 2, (6, 7, 7, 7, 1)) 308 309 # A 28-day february starting on sunday (1+7+7+7+6 days) 310 self.check_weeks(1987, 2, (1, 7, 7, 7, 6)) 311 312 # A 29-day february starting on monday (7+7+7+7+1 days) 313 self.check_weeks(1988, 2, (7, 7, 7, 7, 1)) 314 315 # A 29-day february starting on tuesday (6+7+7+7+2 days) 316 self.check_weeks(1972, 2, (6, 7, 7, 7, 2)) 317 318 # A 29-day february starting on sunday (1+7+7+7+7 days) 319 self.check_weeks(2004, 2, (1, 7, 7, 7, 7)) 320 321 def test_april(self): 322 # A 30-day april starting on monday (7+7+7+7+2 days) 323 self.check_weeks(1935, 4, (7, 7, 7, 7, 2)) 324 325 # A 30-day april starting on tuesday (6+7+7+7+3 days) 326 self.check_weeks(1975, 4, (6, 7, 7, 7, 3)) 327 328 # A 30-day april starting on sunday (1+7+7+7+7+1 days) 329 self.check_weeks(1945, 4, (1, 7, 7, 7, 7, 1)) 330 331 # A 30-day april starting on saturday (2+7+7+7+7 days) 332 self.check_weeks(1995, 4, (2, 7, 7, 7, 7)) 333 334 # A 30-day april starting on friday (3+7+7+7+6 days) 335 self.check_weeks(1994, 4, (3, 7, 7, 7, 6)) 336 337 def test_december(self): 338 # A 31-day december starting on monday (7+7+7+7+3 days) 339 self.check_weeks(1980, 12, (7, 7, 7, 7, 3)) 340 341 # A 31-day december starting on tuesday (6+7+7+7+4 days) 342 self.check_weeks(1987, 12, (6, 7, 7, 7, 4)) 343 344 # A 31-day december starting on sunday (1+7+7+7+7+2 days) 345 self.check_weeks(1968, 12, (1, 7, 7, 7, 7, 2)) 346 347 # A 31-day december starting on thursday (4+7+7+7+6 days) 348 self.check_weeks(1988, 12, (4, 7, 7, 7, 6)) 349 350 # A 31-day december starting on friday (3+7+7+7+7 days) 351 self.check_weeks(2017, 12, (3, 7, 7, 7, 7)) 352 353 # A 31-day december starting on saturday (2+7+7+7+7+1 days) 354 self.check_weeks(2068, 12, (2, 7, 7, 7, 7, 1)) 355 356 357 class SundayTestCase(MonthCalendarTestCase): 358 firstweekday = calendar.SUNDAY 359 360 def test_february(self): 361 # A 28-day february starting on sunday (7+7+7+7 days) 362 self.check_weeks(2009, 2, (7, 7, 7, 7)) 363 364 # A 28-day february starting on monday (6+7+7+7+1 days) 365 self.check_weeks(1999, 2, (6, 7, 7, 7, 1)) 366 367 # A 28-day february starting on saturday (1+7+7+7+6 days) 368 self.check_weeks(1997, 2, (1, 7, 7, 7, 6)) 369 370 # A 29-day february starting on sunday (7+7+7+7+1 days) 371 self.check_weeks(2004, 2, (7, 7, 7, 7, 1)) 372 373 # A 29-day february starting on monday (6+7+7+7+2 days) 374 self.check_weeks(1960, 2, (6, 7, 7, 7, 2)) 375 376 # A 29-day february starting on saturday (1+7+7+7+7 days) 377 self.check_weeks(1964, 2, (1, 7, 7, 7, 7)) 378 379 def test_april(self): 380 # A 30-day april starting on sunday (7+7+7+7+2 days) 381 self.check_weeks(1923, 4, (7, 7, 7, 7, 2)) 382 383 # A 30-day april starting on monday (6+7+7+7+3 days) 384 self.check_weeks(1918, 4, (6, 7, 7, 7, 3)) 385 386 # A 30-day april starting on saturday (1+7+7+7+7+1 days) 387 self.check_weeks(1950, 4, (1, 7, 7, 7, 7, 1)) 388 389 # A 30-day april starting on friday (2+7+7+7+7 days) 390 self.check_weeks(1960, 4, (2, 7, 7, 7, 7)) 391 392 # A 30-day april starting on thursday (3+7+7+7+6 days) 393 self.check_weeks(1909, 4, (3, 7, 7, 7, 6)) 394 395 def test_december(self): 396 # A 31-day december starting on sunday (7+7+7+7+3 days) 397 self.check_weeks(2080, 12, (7, 7, 7, 7, 3)) 398 399 # A 31-day december starting on monday (6+7+7+7+4 days) 400 self.check_weeks(1941, 12, (6, 7, 7, 7, 4)) 401 402 # A 31-day december starting on saturday (1+7+7+7+7+2 days) 403 self.check_weeks(1923, 12, (1, 7, 7, 7, 7, 2)) 404 405 # A 31-day december starting on wednesday (4+7+7+7+6 days) 406 self.check_weeks(1948, 12, (4, 7, 7, 7, 6)) 407 408 # A 31-day december starting on thursday (3+7+7+7+7 days) 409 self.check_weeks(1927, 12, (3, 7, 7, 7, 7)) 410 411 # A 31-day december starting on friday (2+7+7+7+7+1 days) 412 self.check_weeks(1995, 12, (2, 7, 7, 7, 7, 1)) 413 414 415 class MonthRangeTestCase(unittest.TestCase): 416 def test_january(self): 417 # Tests valid lower boundary case. 418 self.assertEqual(calendar.monthrange(2004,1), (3,31)) 419 420 def test_february_leap(self): 421 # Tests February during leap year. 422 self.assertEqual(calendar.monthrange(2004,2), (6,29)) 423 424 def test_february_nonleap(self): 425 # Tests February in non-leap year. 426 self.assertEqual(calendar.monthrange(2010,2), (0,28)) 427 428 def test_december(self): 429 # Tests valid upper boundary case. 430 self.assertEqual(calendar.monthrange(2004,12), (2,31)) 431 432 def test_zeroth_month(self): 433 # Tests low invalid boundary case. 434 with self.assertRaises(calendar.IllegalMonthError): 435 calendar.monthrange(2004, 0) 436 437 def test_thirteenth_month(self): 438 # Tests high invalid boundary case. 439 with self.assertRaises(calendar.IllegalMonthError): 440 calendar.monthrange(2004, 13) 441 442 class LeapdaysTestCase(unittest.TestCase): 443 def test_no_range(self): 444 # test when no range i.e. two identical years as args 445 self.assertEqual(calendar.leapdays(2010,2010), 0) 446 447 def test_no_leapdays(self): 448 # test when no leap years in range 449 self.assertEqual(calendar.leapdays(2010,2011), 0) 450 451 def test_no_leapdays_upper_boundary(self): 452 # test no leap years in range, when upper boundary is a leap year 453 self.assertEqual(calendar.leapdays(2010,2012), 0) 454 455 def test_one_leapday_lower_boundary(self): 456 # test when one leap year in range, lower boundary is leap year 457 self.assertEqual(calendar.leapdays(2012,2013), 1) 458 459 def test_several_leapyears_in_range(self): 460 self.assertEqual(calendar.leapdays(1997,2020), 5) 461 462 463 def test_main(): 464 test_support.run_unittest( 465 OutputTestCase, 466 CalendarTestCase, 467 MondayTestCase, 468 SundayTestCase, 469 MonthRangeTestCase, 470 LeapdaysTestCase, 471 ) 472 473 474 if __name__ == "__main__": 475 test_main() 476