1import calendar
2import unittest
3
4from test import support
5from test.support.script_helper import assert_python_ok, assert_python_failure
6import time
7import locale
8import sys
9import datetime
10import os
11
12result_2004_01_text = """\
13    January 2004
14Mo Tu We Th Fr Sa Su
15          1  2  3  4
16 5  6  7  8  9 10 11
1712 13 14 15 16 17 18
1819 20 21 22 23 24 25
1926 27 28 29 30 31
20"""
21
22result_2004_text = """\
23                                  2004
24
25      January                   February                   March
26Mo 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
2912 13 14 15 16 17 18       9 10 11 12 13 14 15      15 16 17 18 19 20 21
3019 20 21 22 23 24 25      16 17 18 19 20 21 22      22 23 24 25 26 27 28
3126 27 28 29 30 31         23 24 25 26 27 28 29      29 30 31
32
33       April                      May                       June
34Mo 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
3712 13 14 15 16 17 18      10 11 12 13 14 15 16      14 15 16 17 18 19 20
3819 20 21 22 23 24 25      17 18 19 20 21 22 23      21 22 23 24 25 26 27
3926 27 28 29 30            24 25 26 27 28 29 30      28 29 30
40                          31
41
42        July                     August                  September
43Mo 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
4612 13 14 15 16 17 18       9 10 11 12 13 14 15      13 14 15 16 17 18 19
4719 20 21 22 23 24 25      16 17 18 19 20 21 22      20 21 22 23 24 25 26
4826 27 28 29 30 31         23 24 25 26 27 28 29      27 28 29 30
49                          30 31
50
51      October                   November                  December
52Mo 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
5511 12 13 14 15 16 17      15 16 17 18 19 20 21      13 14 15 16 17 18 19
5618 19 20 21 22 23 24      22 23 24 25 26 27 28      20 21 22 23 24 25 26
5725 26 27 28 29 30 31      29 30                     27 28 29 30 31
58"""
59
60result_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
185result_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
250result_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
315class 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
424class 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
526class 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
541class 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
599class 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
656class 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
664class 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
695class 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
716def conv(s):
717    return s.replace('\n', os.linesep).encode()
718
719class 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
838class 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
847if __name__ == "__main__":
848    unittest.main()
849