Home | History | Annotate | Download | only in test
      1 import calendar
      2 import unittest
      3 
      4 from test import support
      5 from test.support.script_helper import assert_python_ok, assert_python_failure
      6 import time
      7 import locale
      8 import sys
      9 import datetime
     10 import os
     11 
     12 result_2004_01_text = """\
     13     January 2004
     14 Mo Tu We Th Fr Sa Su
     15           1  2  3  4
     16  5  6  7  8  9 10 11
     17 12 13 14 15 16 17 18
     18 19 20 21 22 23 24 25
     19 26 27 28 29 30 31
     20 """
     21 
     22 result_2004_text = """\
     23                                   2004
     24 
     25       January                   February                   March
     26 Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su
     27           1  2  3  4                         1       1  2  3  4  5  6  7
     28  5  6  7  8  9 10 11       2  3  4  5  6  7  8       8  9 10 11 12 13 14
     29 12 13 14 15 16 17 18       9 10 11 12 13 14 15      15 16 17 18 19 20 21
     30 19 20 21 22 23 24 25      16 17 18 19 20 21 22      22 23 24 25 26 27 28
     31 26 27 28 29 30 31         23 24 25 26 27 28 29      29 30 31
     32 
     33        April                      May                       June
     34 Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su
     35           1  2  3  4                      1  2          1  2  3  4  5  6
     36  5  6  7  8  9 10 11       3  4  5  6  7  8  9       7  8  9 10 11 12 13
     37 12 13 14 15 16 17 18      10 11 12 13 14 15 16      14 15 16 17 18 19 20
     38 19 20 21 22 23 24 25      17 18 19 20 21 22 23      21 22 23 24 25 26 27
     39 26 27 28 29 30            24 25 26 27 28 29 30      28 29 30
     40                           31
     41 
     42         July                     August                  September
     43 Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su
     44           1  2  3  4                         1             1  2  3  4  5
     45  5  6  7  8  9 10 11       2  3  4  5  6  7  8       6  7  8  9 10 11 12
     46 12 13 14 15 16 17 18       9 10 11 12 13 14 15      13 14 15 16 17 18 19
     47 19 20 21 22 23 24 25      16 17 18 19 20 21 22      20 21 22 23 24 25 26
     48 26 27 28 29 30 31         23 24 25 26 27 28 29      27 28 29 30
     49                           30 31
     50 
     51       October                   November                  December
     52 Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su
     53              1  2  3       1  2  3  4  5  6  7             1  2  3  4  5
     54  4  5  6  7  8  9 10       8  9 10 11 12 13 14       6  7  8  9 10 11 12
     55 11 12 13 14 15 16 17      15 16 17 18 19 20 21      13 14 15 16 17 18 19
     56 18 19 20 21 22 23 24      22 23 24 25 26 27 28      20 21 22 23 24 25 26
     57 25 26 27 28 29 30 31      29 30                     27 28 29 30 31
     58 """
     59 
     60 result_2004_html = """\
     61 <?xml version="1.0" encoding="%(e)s"?>
     62 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
     63 <html>
     64 <head>
     65 <meta http-equiv="Content-Type" content="text/html; charset=%(e)s" />
     66 <link rel="stylesheet" type="text/css" href="calendar.css" />
     67 <title>Calendar for 2004</title>
     68 </head>
     69 <body>
     70 <table border="0" cellpadding="0" cellspacing="0" class="year">
     71 <tr><th colspan="3" class="year">2004</th></tr><tr><td><table border="0" cellpadding="0" cellspacing="0" class="month">
     72 <tr><th colspan="7" class="month">January</th></tr>
     73 <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>
     74 <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>
     75 <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>
     76 <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>
     77 <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>
     78 <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>
     79 </table>
     80 </td><td><table border="0" cellpadding="0" cellspacing="0" class="month">
     81 <tr><th colspan="7" class="month">February</th></tr>
     82 <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>
     83 <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>
     84 <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>
     85 <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>
     86 <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>
     87 <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>
     88 </table>
     89 </td><td><table border="0" cellpadding="0" cellspacing="0" class="month">
     90 <tr><th colspan="7" class="month">March</th></tr>
     91 <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>
     92 <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>
     93 <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>
     94 <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>
     95 <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>
     96 <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>
     97 </table>
     98 </td></tr><tr><td><table border="0" cellpadding="0" cellspacing="0" class="month">
     99 <tr><th colspan="7" class="month">April</th></tr>
    100 <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>
    101 <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>
    102 <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>
    103 <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>
    104 <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>
    105 <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>
    106 </table>
    107 </td><td><table border="0" cellpadding="0" cellspacing="0" class="month">
    108 <tr><th colspan="7" class="month">May</th></tr>
    109 <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>
    110 <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>
    111 <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>
    112 <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>
    113 <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>
    114 <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>
    115 <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>
    116 </table>
    117 </td><td><table border="0" cellpadding="0" cellspacing="0" class="month">
    118 <tr><th colspan="7" class="month">June</th></tr>
    119 <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>
    120 <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>
    121 <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>
    122 <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>
    123 <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>
    124 <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>
    125 </table>
    126 </td></tr><tr><td><table border="0" cellpadding="0" cellspacing="0" class="month">
    127 <tr><th colspan="7" class="month">July</th></tr>
    128 <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>
    129 <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>
    130 <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>
    131 <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>
    132 <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>
    133 <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>
    134 </table>
    135 </td><td><table border="0" cellpadding="0" cellspacing="0" class="month">
    136 <tr><th colspan="7" class="month">August</th></tr>
    137 <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>
    138 <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>
    139 <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>
    140 <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>
    141 <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>
    142 <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>
    143 <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>
    144 </table>
    145 </td><td><table border="0" cellpadding="0" cellspacing="0" class="month">
    146 <tr><th colspan="7" class="month">September</th></tr>
    147 <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>
    148 <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>
    149 <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>
    150 <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>
    151 <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>
    152 <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>
    153 </table>
    154 </td></tr><tr><td><table border="0" cellpadding="0" cellspacing="0" class="month">
    155 <tr><th colspan="7" class="month">October</th></tr>
    156 <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>
    157 <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>
    158 <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>
    159 <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>
    160 <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>
    161 <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>
    162 </table>
    163 </td><td><table border="0" cellpadding="0" cellspacing="0" class="month">
    164 <tr><th colspan="7" class="month">November</th></tr>
    165 <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>
    166 <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>
    167 <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>
    168 <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>
    169 <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>
    170 <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>
    171 </table>
    172 </td><td><table border="0" cellpadding="0" cellspacing="0" class="month">
    173 <tr><th colspan="7" class="month">December</th></tr>
    174 <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>
    175 <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>
    176 <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>
    177 <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>
    178 <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>
    179 <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>
    180 </table>
    181 </td></tr></table></body>
    182 </html>
    183 """
    184 
    185 result_2004_days = [
    186     [[[0, 0, 0, 1, 2, 3, 4],
    187       [5, 6, 7, 8, 9, 10, 11],
    188       [12, 13, 14, 15, 16, 17, 18],
    189       [19, 20, 21, 22, 23, 24, 25],
    190       [26, 27, 28, 29, 30, 31, 0]],
    191      [[0, 0, 0, 0, 0, 0, 1],
    192       [2, 3, 4, 5, 6, 7, 8],
    193       [9, 10, 11, 12, 13, 14, 15],
    194       [16, 17, 18, 19, 20, 21, 22],
    195       [23, 24, 25, 26, 27, 28, 29]],
    196      [[1, 2, 3, 4, 5, 6, 7],
    197       [8, 9, 10, 11, 12, 13, 14],
    198       [15, 16, 17, 18, 19, 20, 21],
    199       [22, 23, 24, 25, 26, 27, 28],
    200       [29, 30, 31, 0, 0, 0, 0]]],
    201     [[[0, 0, 0, 1, 2, 3, 4],
    202       [5, 6, 7, 8, 9, 10, 11],
    203       [12, 13, 14, 15, 16, 17, 18],
    204       [19, 20, 21, 22, 23, 24, 25],
    205       [26, 27, 28, 29, 30, 0, 0]],
    206      [[0, 0, 0, 0, 0, 1, 2],
    207       [3, 4, 5, 6, 7, 8, 9],
    208       [10, 11, 12, 13, 14, 15, 16],
    209       [17, 18, 19, 20, 21, 22, 23],
    210       [24, 25, 26, 27, 28, 29, 30],
    211       [31, 0, 0, 0, 0, 0, 0]],
    212      [[0, 1, 2, 3, 4, 5, 6],
    213       [7, 8, 9, 10, 11, 12, 13],
    214       [14, 15, 16, 17, 18, 19, 20],
    215       [21, 22, 23, 24, 25, 26, 27],
    216       [28, 29, 30, 0, 0, 0, 0]]],
    217     [[[0, 0, 0, 1, 2, 3, 4],
    218       [5, 6, 7, 8, 9, 10, 11],
    219       [12, 13, 14, 15, 16, 17, 18],
    220       [19, 20, 21, 22, 23, 24, 25],
    221       [26, 27, 28, 29, 30, 31, 0]],
    222      [[0, 0, 0, 0, 0, 0, 1],
    223       [2, 3, 4, 5, 6, 7, 8],
    224       [9, 10, 11, 12, 13, 14, 15],
    225       [16, 17, 18, 19, 20, 21, 22],
    226       [23, 24, 25, 26, 27, 28, 29],
    227       [30, 31, 0, 0, 0, 0, 0]],
    228      [[0, 0, 1, 2, 3, 4, 5],
    229       [6, 7, 8, 9, 10, 11, 12],
    230       [13, 14, 15, 16, 17, 18, 19],
    231       [20, 21, 22, 23, 24, 25, 26],
    232       [27, 28, 29, 30, 0, 0, 0]]],
    233     [[[0, 0, 0, 0, 1, 2, 3],
    234       [4, 5, 6, 7, 8, 9, 10],
    235       [11, 12, 13, 14, 15, 16, 17],
    236       [18, 19, 20, 21, 22, 23, 24],
    237       [25, 26, 27, 28, 29, 30, 31]],
    238      [[1, 2, 3, 4, 5, 6, 7],
    239       [8, 9, 10, 11, 12, 13, 14],
    240       [15, 16, 17, 18, 19, 20, 21],
    241       [22, 23, 24, 25, 26, 27, 28],
    242       [29, 30, 0, 0, 0, 0, 0]],
    243      [[0, 0, 1, 2, 3, 4, 5],
    244       [6, 7, 8, 9, 10, 11, 12],
    245       [13, 14, 15, 16, 17, 18, 19],
    246       [20, 21, 22, 23, 24, 25, 26],
    247       [27, 28, 29, 30, 31, 0, 0]]]
    248 ]
    249 
    250 result_2004_dates = \
    251     [[['12/29/03 12/30/03 12/31/03 01/01/04 01/02/04 01/03/04 01/04/04',
    252        '01/05/04 01/06/04 01/07/04 01/08/04 01/09/04 01/10/04 01/11/04',
    253        '01/12/04 01/13/04 01/14/04 01/15/04 01/16/04 01/17/04 01/18/04',
    254        '01/19/04 01/20/04 01/21/04 01/22/04 01/23/04 01/24/04 01/25/04',
    255        '01/26/04 01/27/04 01/28/04 01/29/04 01/30/04 01/31/04 02/01/04'],
    256       ['01/26/04 01/27/04 01/28/04 01/29/04 01/30/04 01/31/04 02/01/04',
    257        '02/02/04 02/03/04 02/04/04 02/05/04 02/06/04 02/07/04 02/08/04',
    258        '02/09/04 02/10/04 02/11/04 02/12/04 02/13/04 02/14/04 02/15/04',
    259        '02/16/04 02/17/04 02/18/04 02/19/04 02/20/04 02/21/04 02/22/04',
    260        '02/23/04 02/24/04 02/25/04 02/26/04 02/27/04 02/28/04 02/29/04'],
    261       ['03/01/04 03/02/04 03/03/04 03/04/04 03/05/04 03/06/04 03/07/04',
    262        '03/08/04 03/09/04 03/10/04 03/11/04 03/12/04 03/13/04 03/14/04',
    263        '03/15/04 03/16/04 03/17/04 03/18/04 03/19/04 03/20/04 03/21/04',
    264        '03/22/04 03/23/04 03/24/04 03/25/04 03/26/04 03/27/04 03/28/04',
    265        '03/29/04 03/30/04 03/31/04 04/01/04 04/02/04 04/03/04 04/04/04']],
    266      [['03/29/04 03/30/04 03/31/04 04/01/04 04/02/04 04/03/04 04/04/04',
    267        '04/05/04 04/06/04 04/07/04 04/08/04 04/09/04 04/10/04 04/11/04',
    268        '04/12/04 04/13/04 04/14/04 04/15/04 04/16/04 04/17/04 04/18/04',
    269        '04/19/04 04/20/04 04/21/04 04/22/04 04/23/04 04/24/04 04/25/04',
    270        '04/26/04 04/27/04 04/28/04 04/29/04 04/30/04 05/01/04 05/02/04'],
    271       ['04/26/04 04/27/04 04/28/04 04/29/04 04/30/04 05/01/04 05/02/04',
    272        '05/03/04 05/04/04 05/05/04 05/06/04 05/07/04 05/08/04 05/09/04',
    273        '05/10/04 05/11/04 05/12/04 05/13/04 05/14/04 05/15/04 05/16/04',
    274        '05/17/04 05/18/04 05/19/04 05/20/04 05/21/04 05/22/04 05/23/04',
    275        '05/24/04 05/25/04 05/26/04 05/27/04 05/28/04 05/29/04 05/30/04',
    276        '05/31/04 06/01/04 06/02/04 06/03/04 06/04/04 06/05/04 06/06/04'],
    277       ['05/31/04 06/01/04 06/02/04 06/03/04 06/04/04 06/05/04 06/06/04',
    278        '06/07/04 06/08/04 06/09/04 06/10/04 06/11/04 06/12/04 06/13/04',
    279        '06/14/04 06/15/04 06/16/04 06/17/04 06/18/04 06/19/04 06/20/04',
    280        '06/21/04 06/22/04 06/23/04 06/24/04 06/25/04 06/26/04 06/27/04',
    281        '06/28/04 06/29/04 06/30/04 07/01/04 07/02/04 07/03/04 07/04/04']],
    282      [['06/28/04 06/29/04 06/30/04 07/01/04 07/02/04 07/03/04 07/04/04',
    283        '07/05/04 07/06/04 07/07/04 07/08/04 07/09/04 07/10/04 07/11/04',
    284        '07/12/04 07/13/04 07/14/04 07/15/04 07/16/04 07/17/04 07/18/04',
    285        '07/19/04 07/20/04 07/21/04 07/22/04 07/23/04 07/24/04 07/25/04',
    286        '07/26/04 07/27/04 07/28/04 07/29/04 07/30/04 07/31/04 08/01/04'],
    287       ['07/26/04 07/27/04 07/28/04 07/29/04 07/30/04 07/31/04 08/01/04',
    288        '08/02/04 08/03/04 08/04/04 08/05/04 08/06/04 08/07/04 08/08/04',
    289        '08/09/04 08/10/04 08/11/04 08/12/04 08/13/04 08/14/04 08/15/04',
    290        '08/16/04 08/17/04 08/18/04 08/19/04 08/20/04 08/21/04 08/22/04',
    291        '08/23/04 08/24/04 08/25/04 08/26/04 08/27/04 08/28/04 08/29/04',
    292        '08/30/04 08/31/04 09/01/04 09/02/04 09/03/04 09/04/04 09/05/04'],
    293       ['08/30/04 08/31/04 09/01/04 09/02/04 09/03/04 09/04/04 09/05/04',
    294        '09/06/04 09/07/04 09/08/04 09/09/04 09/10/04 09/11/04 09/12/04',
    295        '09/13/04 09/14/04 09/15/04 09/16/04 09/17/04 09/18/04 09/19/04',
    296        '09/20/04 09/21/04 09/22/04 09/23/04 09/24/04 09/25/04 09/26/04',
    297        '09/27/04 09/28/04 09/29/04 09/30/04 10/01/04 10/02/04 10/03/04']],
    298      [['09/27/04 09/28/04 09/29/04 09/30/04 10/01/04 10/02/04 10/03/04',
    299        '10/04/04 10/05/04 10/06/04 10/07/04 10/08/04 10/09/04 10/10/04',
    300        '10/11/04 10/12/04 10/13/04 10/14/04 10/15/04 10/16/04 10/17/04',
    301        '10/18/04 10/19/04 10/20/04 10/21/04 10/22/04 10/23/04 10/24/04',
    302        '10/25/04 10/26/04 10/27/04 10/28/04 10/29/04 10/30/04 10/31/04'],
    303       ['11/01/04 11/02/04 11/03/04 11/04/04 11/05/04 11/06/04 11/07/04',
    304        '11/08/04 11/09/04 11/10/04 11/11/04 11/12/04 11/13/04 11/14/04',
    305        '11/15/04 11/16/04 11/17/04 11/18/04 11/19/04 11/20/04 11/21/04',
    306        '11/22/04 11/23/04 11/24/04 11/25/04 11/26/04 11/27/04 11/28/04',
    307        '11/29/04 11/30/04 12/01/04 12/02/04 12/03/04 12/04/04 12/05/04'],
    308       ['11/29/04 11/30/04 12/01/04 12/02/04 12/03/04 12/04/04 12/05/04',
    309        '12/06/04 12/07/04 12/08/04 12/09/04 12/10/04 12/11/04 12/12/04',
    310        '12/13/04 12/14/04 12/15/04 12/16/04 12/17/04 12/18/04 12/19/04',
    311        '12/20/04 12/21/04 12/22/04 12/23/04 12/24/04 12/25/04 12/26/04',
    312        '12/27/04 12/28/04 12/29/04 12/30/04 12/31/04 01/01/05 01/02/05']]]
    313 
    314 
    315 class OutputTestCase(unittest.TestCase):
    316     def normalize_calendar(self, s):
    317         # Filters out locale dependent strings
    318         def neitherspacenordigit(c):
    319             return not c.isspace() and not c.isdigit()
    320 
    321         lines = []
    322         for line in s.splitlines(keepends=False):
    323             # Drop texts, as they are locale dependent
    324             if line and not filter(neitherspacenordigit, line):
    325                 lines.append(line)
    326         return lines
    327 
    328     def check_htmlcalendar_encoding(self, req, res):
    329         cal = calendar.HTMLCalendar()
    330         self.assertEqual(
    331             cal.formatyearpage(2004, encoding=req),
    332             (result_2004_html % {'e': res}).encode(res)
    333         )
    334 
    335     def test_output(self):
    336         self.assertEqual(
    337             self.normalize_calendar(calendar.calendar(2004)),
    338             self.normalize_calendar(result_2004_text)
    339         )
    340 
    341     def test_output_textcalendar(self):
    342         self.assertEqual(
    343             calendar.TextCalendar().formatyear(2004),
    344             result_2004_text
    345         )
    346 
    347     def test_output_htmlcalendar_encoding_ascii(self):
    348         self.check_htmlcalendar_encoding('ascii', 'ascii')
    349 
    350     def test_output_htmlcalendar_encoding_utf8(self):
    351         self.check_htmlcalendar_encoding('utf-8', 'utf-8')
    352 
    353     def test_output_htmlcalendar_encoding_default(self):
    354         self.check_htmlcalendar_encoding(None, sys.getdefaultencoding())
    355 
    356     def test_yeardatescalendar(self):
    357         def shrink(cal):
    358             return [[[' '.join('{:02d}/{:02d}/{}'.format(
    359                                 d.month, d.day, str(d.year)[-2:]) for d in z)
    360                             for z in y] for y in x] for x in cal]
    361         self.assertEqual(
    362             shrink(calendar.Calendar().yeardatescalendar(2004)),
    363             result_2004_dates
    364         )
    365 
    366     def test_yeardayscalendar(self):
    367         self.assertEqual(
    368             calendar.Calendar().yeardayscalendar(2004),
    369             result_2004_days
    370         )
    371 
    372     def test_formatweekheader_short(self):
    373         self.assertEqual(
    374             calendar.TextCalendar().formatweekheader(2),
    375             'Mo Tu We Th Fr Sa Su'
    376         )
    377 
    378     def test_formatweekheader_long(self):
    379         self.assertEqual(
    380             calendar.TextCalendar().formatweekheader(9),
    381             '  Monday   Tuesday  Wednesday  Thursday '
    382             '  Friday   Saturday   Sunday '
    383         )
    384 
    385     def test_formatmonth(self):
    386         self.assertEqual(
    387             calendar.TextCalendar().formatmonth(2004, 1),
    388             result_2004_01_text
    389         )
    390 
    391     def test_formatmonthname_with_year(self):
    392         self.assertEqual(
    393             calendar.HTMLCalendar().formatmonthname(2004, 1, withyear=True),
    394             '<tr><th colspan="7" class="month">January 2004</th></tr>'
    395         )
    396 
    397     def test_formatmonthname_without_year(self):
    398         self.assertEqual(
    399             calendar.HTMLCalendar().formatmonthname(2004, 1, withyear=False),
    400             '<tr><th colspan="7" class="month">January</th></tr>'
    401         )
    402 
    403     def test_prweek(self):
    404         with support.captured_stdout() as out:
    405             week = [(1,0), (2,1), (3,2), (4,3), (5,4), (6,5), (7,6)]
    406             calendar.TextCalendar().prweek(week, 1)
    407             self.assertEqual(out.getvalue().strip(), "1  2  3  4  5  6  7")
    408 
    409     def test_prmonth(self):
    410         with support.captured_stdout() as out:
    411             calendar.TextCalendar().prmonth(2004, 1)
    412             self.assertEqual(out.getvalue(), result_2004_01_text)
    413 
    414     def test_pryear(self):
    415         with support.captured_stdout() as out:
    416             calendar.TextCalendar().pryear(2004)
    417             self.assertEqual(out.getvalue().strip(), result_2004_text.strip())
    418 
    419     def test_format(self):
    420         with support.captured_stdout() as out:
    421             calendar.format(["1", "2", "3"], colwidth=3, spacing=1)
    422             self.assertEqual(out.getvalue().strip(), "1   2   3")
    423 
    424 class CalendarTestCase(unittest.TestCase):
    425     def test_isleap(self):
    426         # Make sure that the return is right for a few years, and
    427         # ensure that the return values are 1 or 0, not just true or
    428         # false (see SF bug #485794).  Specific additional tests may
    429         # be appropriate; this tests a single "cycle".
    430         self.assertEqual(calendar.isleap(2000), 1)
    431         self.assertEqual(calendar.isleap(2001), 0)
    432         self.assertEqual(calendar.isleap(2002), 0)
    433         self.assertEqual(calendar.isleap(2003), 0)
    434 
    435     def test_setfirstweekday(self):
    436         self.assertRaises(TypeError, calendar.setfirstweekday, 'flabber')
    437         self.assertRaises(ValueError, calendar.setfirstweekday, -1)
    438         self.assertRaises(ValueError, calendar.setfirstweekday, 200)
    439         orig = calendar.firstweekday()
    440         calendar.setfirstweekday(calendar.SUNDAY)
    441         self.assertEqual(calendar.firstweekday(), calendar.SUNDAY)
    442         calendar.setfirstweekday(calendar.MONDAY)
    443         self.assertEqual(calendar.firstweekday(), calendar.MONDAY)
    444         calendar.setfirstweekday(orig)
    445 
    446     def test_illegal_weekday_reported(self):
    447         with self.assertRaisesRegex(calendar.IllegalWeekdayError, '123'):
    448             calendar.setfirstweekday(123)
    449 
    450     def test_enumerate_weekdays(self):
    451         self.assertRaises(IndexError, calendar.day_abbr.__getitem__, -10)
    452         self.assertRaises(IndexError, calendar.day_name.__getitem__, 10)
    453         self.assertEqual(len([d for d in calendar.day_abbr]), 7)
    454 
    455     def test_days(self):
    456         for attr in "day_name", "day_abbr":
    457             value = getattr(calendar, attr)
    458             self.assertEqual(len(value), 7)
    459             self.assertEqual(len(value[:]), 7)
    460             # ensure they're all unique
    461             self.assertEqual(len(set(value)), 7)
    462             # verify it "acts like a sequence" in two forms of iteration
    463             self.assertEqual(value[::-1], list(reversed(value)))
    464 
    465     def test_months(self):
    466         for attr in "month_name", "month_abbr":
    467             value = getattr(calendar, attr)
    468             self.assertEqual(len(value), 13)
    469             self.assertEqual(len(value[:]), 13)
    470             self.assertEqual(value[0], "")
    471             # ensure they're all unique
    472             self.assertEqual(len(set(value)), 13)
    473             # verify it "acts like a sequence" in two forms of iteration
    474             self.assertEqual(value[::-1], list(reversed(value)))
    475 
    476     def test_locale_calendars(self):
    477         # ensure that Locale{Text,HTML}Calendar resets the locale properly
    478         # (it is still not thread-safe though)
    479         old_october = calendar.TextCalendar().formatmonthname(2010, 10, 10)
    480         try:
    481             cal = calendar.LocaleTextCalendar(locale='')
    482             local_weekday = cal.formatweekday(1, 10)
    483             local_month = cal.formatmonthname(2010, 10, 10)
    484         except locale.Error:
    485             # cannot set the system default locale -- skip rest of test
    486             raise unittest.SkipTest('cannot set the system default locale')
    487         self.assertIsInstance(local_weekday, str)
    488         self.assertIsInstance(local_month, str)
    489         self.assertEqual(len(local_weekday), 10)
    490         self.assertGreaterEqual(len(local_month), 10)
    491         cal = calendar.LocaleHTMLCalendar(locale='')
    492         local_weekday = cal.formatweekday(1)
    493         local_month = cal.formatmonthname(2010, 10)
    494         self.assertIsInstance(local_weekday, str)
    495         self.assertIsInstance(local_month, str)
    496         new_october = calendar.TextCalendar().formatmonthname(2010, 10, 10)
    497         self.assertEqual(old_october, new_october)
    498 
    499     def test_itermonthdates(self):
    500         # ensure itermonthdates doesn't overflow after datetime.MAXYEAR
    501         # see #15421
    502         list(calendar.Calendar().itermonthdates(datetime.MAXYEAR, 12))
    503 
    504     def test_itermonthdays(self):
    505         for firstweekday in range(7):
    506             cal = calendar.Calendar(firstweekday)
    507             # Test the extremes, see #28253 and #26650
    508             for y, m in [(1, 1), (9999, 12)]:
    509                 days = list(cal.itermonthdays(y, m))
    510                 self.assertIn(len(days), (35, 42))
    511         # Test a short month
    512         cal = calendar.Calendar(firstweekday=3)
    513         days = list(cal.itermonthdays(2001, 2))
    514         self.assertEqual(days, list(range(1, 29)))
    515 
    516     def test_itermonthdays2(self):
    517         for firstweekday in range(7):
    518             cal = calendar.Calendar(firstweekday)
    519             # Test the extremes, see #28253 and #26650
    520             for y, m in [(1, 1), (9999, 12)]:
    521                 days = list(cal.itermonthdays2(y, m))
    522                 self.assertEqual(days[0][1], firstweekday)
    523                 self.assertEqual(days[-1][1], (firstweekday - 1) % 7)
    524 
    525 
    526 class MonthCalendarTestCase(unittest.TestCase):
    527     def setUp(self):
    528         self.oldfirstweekday = calendar.firstweekday()
    529         calendar.setfirstweekday(self.firstweekday)
    530 
    531     def tearDown(self):
    532         calendar.setfirstweekday(self.oldfirstweekday)
    533 
    534     def check_weeks(self, year, month, weeks):
    535         cal = calendar.monthcalendar(year, month)
    536         self.assertEqual(len(cal), len(weeks))
    537         for i in range(len(weeks)):
    538             self.assertEqual(weeks[i], sum(day != 0 for day in cal[i]))
    539 
    540 
    541 class MondayTestCase(MonthCalendarTestCase):
    542     firstweekday = calendar.MONDAY
    543 
    544     def test_february(self):
    545         # A 28-day february starting on monday (7+7+7+7 days)
    546         self.check_weeks(1999, 2, (7, 7, 7, 7))
    547 
    548         # A 28-day february starting on tuesday (6+7+7+7+1 days)
    549         self.check_weeks(2005, 2, (6, 7, 7, 7, 1))
    550 
    551         # A 28-day february starting on sunday (1+7+7+7+6 days)
    552         self.check_weeks(1987, 2, (1, 7, 7, 7, 6))
    553 
    554         # A 29-day february starting on monday (7+7+7+7+1 days)
    555         self.check_weeks(1988, 2, (7, 7, 7, 7, 1))
    556 
    557         # A 29-day february starting on tuesday (6+7+7+7+2 days)
    558         self.check_weeks(1972, 2, (6, 7, 7, 7, 2))
    559 
    560         # A 29-day february starting on sunday (1+7+7+7+7 days)
    561         self.check_weeks(2004, 2, (1, 7, 7, 7, 7))
    562 
    563     def test_april(self):
    564         # A 30-day april starting on monday (7+7+7+7+2 days)
    565         self.check_weeks(1935, 4, (7, 7, 7, 7, 2))
    566 
    567         # A 30-day april starting on tuesday (6+7+7+7+3 days)
    568         self.check_weeks(1975, 4, (6, 7, 7, 7, 3))
    569 
    570         # A 30-day april starting on sunday (1+7+7+7+7+1 days)
    571         self.check_weeks(1945, 4, (1, 7, 7, 7, 7, 1))
    572 
    573         # A 30-day april starting on saturday (2+7+7+7+7 days)
    574         self.check_weeks(1995, 4, (2, 7, 7, 7, 7))
    575 
    576         # A 30-day april starting on friday (3+7+7+7+6 days)
    577         self.check_weeks(1994, 4, (3, 7, 7, 7, 6))
    578 
    579     def test_december(self):
    580         # A 31-day december starting on monday (7+7+7+7+3 days)
    581         self.check_weeks(1980, 12, (7, 7, 7, 7, 3))
    582 
    583         # A 31-day december starting on tuesday (6+7+7+7+4 days)
    584         self.check_weeks(1987, 12, (6, 7, 7, 7, 4))
    585 
    586         # A 31-day december starting on sunday (1+7+7+7+7+2 days)
    587         self.check_weeks(1968, 12, (1, 7, 7, 7, 7, 2))
    588 
    589         # A 31-day december starting on thursday (4+7+7+7+6 days)
    590         self.check_weeks(1988, 12, (4, 7, 7, 7, 6))
    591 
    592         # A 31-day december starting on friday (3+7+7+7+7 days)
    593         self.check_weeks(2017, 12, (3, 7, 7, 7, 7))
    594 
    595         # A 31-day december starting on saturday (2+7+7+7+7+1 days)
    596         self.check_weeks(2068, 12, (2, 7, 7, 7, 7, 1))
    597 
    598 
    599 class SundayTestCase(MonthCalendarTestCase):
    600     firstweekday = calendar.SUNDAY
    601 
    602     def test_february(self):
    603         # A 28-day february starting on sunday (7+7+7+7 days)
    604         self.check_weeks(2009, 2, (7, 7, 7, 7))
    605 
    606         # A 28-day february starting on monday (6+7+7+7+1 days)
    607         self.check_weeks(1999, 2, (6, 7, 7, 7, 1))
    608 
    609         # A 28-day february starting on saturday (1+7+7+7+6 days)
    610         self.check_weeks(1997, 2, (1, 7, 7, 7, 6))
    611 
    612         # A 29-day february starting on sunday (7+7+7+7+1 days)
    613         self.check_weeks(2004, 2, (7, 7, 7, 7, 1))
    614 
    615         # A 29-day february starting on monday (6+7+7+7+2 days)
    616         self.check_weeks(1960, 2, (6, 7, 7, 7, 2))
    617 
    618         # A 29-day february starting on saturday (1+7+7+7+7 days)
    619         self.check_weeks(1964, 2, (1, 7, 7, 7, 7))
    620 
    621     def test_april(self):
    622         # A 30-day april starting on sunday (7+7+7+7+2 days)
    623         self.check_weeks(1923, 4, (7, 7, 7, 7, 2))
    624 
    625         # A 30-day april starting on monday (6+7+7+7+3 days)
    626         self.check_weeks(1918, 4, (6, 7, 7, 7, 3))
    627 
    628         # A 30-day april starting on saturday (1+7+7+7+7+1 days)
    629         self.check_weeks(1950, 4, (1, 7, 7, 7, 7, 1))
    630 
    631         # A 30-day april starting on friday (2+7+7+7+7 days)
    632         self.check_weeks(1960, 4, (2, 7, 7, 7, 7))
    633 
    634         # A 30-day april starting on thursday (3+7+7+7+6 days)
    635         self.check_weeks(1909, 4, (3, 7, 7, 7, 6))
    636 
    637     def test_december(self):
    638         # A 31-day december starting on sunday (7+7+7+7+3 days)
    639         self.check_weeks(2080, 12, (7, 7, 7, 7, 3))
    640 
    641         # A 31-day december starting on monday (6+7+7+7+4 days)
    642         self.check_weeks(1941, 12, (6, 7, 7, 7, 4))
    643 
    644         # A 31-day december starting on saturday (1+7+7+7+7+2 days)
    645         self.check_weeks(1923, 12, (1, 7, 7, 7, 7, 2))
    646 
    647         # A 31-day december starting on wednesday (4+7+7+7+6 days)
    648         self.check_weeks(1948, 12, (4, 7, 7, 7, 6))
    649 
    650         # A 31-day december starting on thursday (3+7+7+7+7 days)
    651         self.check_weeks(1927, 12, (3, 7, 7, 7, 7))
    652 
    653         # A 31-day december starting on friday (2+7+7+7+7+1 days)
    654         self.check_weeks(1995, 12, (2, 7, 7, 7, 7, 1))
    655 
    656 class TimegmTestCase(unittest.TestCase):
    657     TIMESTAMPS = [0, 10, 100, 1000, 10000, 100000, 1000000,
    658                   1234567890, 1262304000, 1275785153,]
    659     def test_timegm(self):
    660         for secs in self.TIMESTAMPS:
    661             tuple = time.gmtime(secs)
    662             self.assertEqual(secs, calendar.timegm(tuple))
    663 
    664 class MonthRangeTestCase(unittest.TestCase):
    665     def test_january(self):
    666         # Tests valid lower boundary case.
    667         self.assertEqual(calendar.monthrange(2004,1), (3,31))
    668 
    669     def test_february_leap(self):
    670         # Tests February during leap year.
    671         self.assertEqual(calendar.monthrange(2004,2), (6,29))
    672 
    673     def test_february_nonleap(self):
    674         # Tests February in non-leap year.
    675         self.assertEqual(calendar.monthrange(2010,2), (0,28))
    676 
    677     def test_december(self):
    678         # Tests valid upper boundary case.
    679         self.assertEqual(calendar.monthrange(2004,12), (2,31))
    680 
    681     def test_zeroth_month(self):
    682         # Tests low invalid boundary case.
    683         with self.assertRaises(calendar.IllegalMonthError):
    684             calendar.monthrange(2004, 0)
    685 
    686     def test_thirteenth_month(self):
    687         # Tests high invalid boundary case.
    688         with self.assertRaises(calendar.IllegalMonthError):
    689             calendar.monthrange(2004, 13)
    690 
    691     def test_illegal_month_reported(self):
    692         with self.assertRaisesRegex(calendar.IllegalMonthError, '65'):
    693             calendar.monthrange(2004, 65)
    694 
    695 class LeapdaysTestCase(unittest.TestCase):
    696     def test_no_range(self):
    697         # test when no range i.e. two identical years as args
    698         self.assertEqual(calendar.leapdays(2010,2010), 0)
    699 
    700     def test_no_leapdays(self):
    701         # test when no leap years in range
    702         self.assertEqual(calendar.leapdays(2010,2011), 0)
    703 
    704     def test_no_leapdays_upper_boundary(self):
    705         # test no leap years in range, when upper boundary is a leap year
    706         self.assertEqual(calendar.leapdays(2010,2012), 0)
    707 
    708     def test_one_leapday_lower_boundary(self):
    709         # test when one leap year in range, lower boundary is leap year
    710         self.assertEqual(calendar.leapdays(2012,2013), 1)
    711 
    712     def test_several_leapyears_in_range(self):
    713         self.assertEqual(calendar.leapdays(1997,2020), 5)
    714 
    715 
    716 def conv(s):
    717     return s.replace('\n', os.linesep).encode()
    718 
    719 class CommandLineTestCase(unittest.TestCase):
    720     def run_ok(self, *args):
    721         return assert_python_ok('-m', 'calendar', *args)[1]
    722 
    723     def assertFailure(self, *args):
    724         rc, stdout, stderr = assert_python_failure('-m', 'calendar', *args)
    725         self.assertIn(b'usage:', stderr)
    726         self.assertEqual(rc, 2)
    727 
    728     def test_help(self):
    729         stdout = self.run_ok('-h')
    730         self.assertIn(b'usage:', stdout)
    731         self.assertIn(b'calendar.py', stdout)
    732         self.assertIn(b'--help', stdout)
    733 
    734     def test_illegal_arguments(self):
    735         self.assertFailure('-z')
    736         self.assertFailure('spam')
    737         self.assertFailure('2004', 'spam')
    738         self.assertFailure('-t', 'html', '2004', '1')
    739 
    740     def test_output_current_year(self):
    741         stdout = self.run_ok()
    742         year = datetime.datetime.now().year
    743         self.assertIn((' %s' % year).encode(), stdout)
    744         self.assertIn(b'January', stdout)
    745         self.assertIn(b'Mo Tu We Th Fr Sa Su', stdout)
    746 
    747     def test_output_year(self):
    748         stdout = self.run_ok('2004')
    749         self.assertEqual(stdout, conv(result_2004_text))
    750 
    751     def test_output_month(self):
    752         stdout = self.run_ok('2004', '1')
    753         self.assertEqual(stdout, conv(result_2004_01_text))
    754 
    755     def test_option_encoding(self):
    756         self.assertFailure('-e')
    757         self.assertFailure('--encoding')
    758         stdout = self.run_ok('--encoding', 'utf-16-le', '2004')
    759         self.assertEqual(stdout, result_2004_text.encode('utf-16-le'))
    760 
    761     def test_option_locale(self):
    762         self.assertFailure('-L')
    763         self.assertFailure('--locale')
    764         self.assertFailure('-L', 'en')
    765         lang, enc = locale.getdefaultlocale()
    766         lang = lang or 'C'
    767         enc = enc or 'UTF-8'
    768         try:
    769             oldlocale = locale.getlocale(locale.LC_TIME)
    770             try:
    771                 locale.setlocale(locale.LC_TIME, (lang, enc))
    772             finally:
    773                 locale.setlocale(locale.LC_TIME, oldlocale)
    774         except (locale.Error, ValueError):
    775             self.skipTest('cannot set the system default locale')
    776         stdout = self.run_ok('--locale', lang, '--encoding', enc, '2004')
    777         self.assertIn('2004'.encode(enc), stdout)
    778 
    779     def test_option_width(self):
    780         self.assertFailure('-w')
    781         self.assertFailure('--width')
    782         self.assertFailure('-w', 'spam')
    783         stdout = self.run_ok('--width', '3', '2004')
    784         self.assertIn(b'Mon Tue Wed Thu Fri Sat Sun', stdout)
    785 
    786     def test_option_lines(self):
    787         self.assertFailure('-l')
    788         self.assertFailure('--lines')
    789         self.assertFailure('-l', 'spam')
    790         stdout = self.run_ok('--lines', '2', '2004')
    791         self.assertIn(conv('December\n\nMo Tu We'), stdout)
    792 
    793     def test_option_spacing(self):
    794         self.assertFailure('-s')
    795         self.assertFailure('--spacing')
    796         self.assertFailure('-s', 'spam')
    797         stdout = self.run_ok('--spacing', '8', '2004')
    798         self.assertIn(b'Su        Mo', stdout)
    799 
    800     def test_option_months(self):
    801         self.assertFailure('-m')
    802         self.assertFailure('--month')
    803         self.assertFailure('-m', 'spam')
    804         stdout = self.run_ok('--months', '1', '2004')
    805         self.assertIn(conv('\nMo Tu We Th Fr Sa Su\n'), stdout)
    806 
    807     def test_option_type(self):
    808         self.assertFailure('-t')
    809         self.assertFailure('--type')
    810         self.assertFailure('-t', 'spam')
    811         stdout = self.run_ok('--type', 'text', '2004')
    812         self.assertEqual(stdout, conv(result_2004_text))
    813         stdout = self.run_ok('--type', 'html', '2004')
    814         self.assertEqual(stdout[:6], b'<?xml ')
    815         self.assertIn(b'<title>Calendar for 2004</title>', stdout)
    816 
    817     def test_html_output_current_year(self):
    818         stdout = self.run_ok('--type', 'html')
    819         year = datetime.datetime.now().year
    820         self.assertIn(('<title>Calendar for %s</title>' % year).encode(),
    821                       stdout)
    822         self.assertIn(b'<tr><th colspan="7" class="month">January</th></tr>',
    823                       stdout)
    824 
    825     def test_html_output_year_encoding(self):
    826         stdout = self.run_ok('-t', 'html', '--encoding', 'ascii', '2004')
    827         self.assertEqual(stdout,
    828                          (result_2004_html % {'e': 'ascii'}).encode('ascii'))
    829 
    830     def test_html_output_year_css(self):
    831         self.assertFailure('-t', 'html', '-c')
    832         self.assertFailure('-t', 'html', '--css')
    833         stdout = self.run_ok('-t', 'html', '--css', 'custom.css', '2004')
    834         self.assertIn(b'<link rel="stylesheet" type="text/css" '
    835                       b'href="custom.css" />', stdout)
    836 
    837 
    838 class MiscTestCase(unittest.TestCase):
    839     def test__all__(self):
    840         blacklist = {'mdays', 'January', 'February', 'EPOCH',
    841                      'MONDAY', 'TUESDAY', 'WEDNESDAY', 'THURSDAY', 'FRIDAY',
    842                      'SATURDAY', 'SUNDAY', 'different_locale', 'c',
    843                      'prweek', 'week', 'format', 'formatstring', 'main'}
    844         support.check__all__(self, calendar, blacklist=blacklist)
    845 
    846 
    847 if __name__ == "__main__":
    848     unittest.main()
    849