Home | History | Annotate | Download | only in test
      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">&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>
     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">&nbsp;</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">&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>
     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">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</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">&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>
     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">&nbsp;</td><td class="noday">&nbsp;</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">&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>
     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">&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>
    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">&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>
    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">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</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">&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>
    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">&nbsp;</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">&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>
    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">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</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">&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>
    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">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</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">&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>
    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">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</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">&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>
    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">&nbsp;</td><td class="noday">&nbsp;</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