blob: 6241d114d33823784790c4bf1db10c81aa75050c [file] [log] [blame]
Fred Draked077ca12001-12-12 05:38:08 +00001import calendar
2import unittest
3
Benjamin Petersonee8712c2008-05-20 21:35:26 +00004from test import support
Berker Peksagce643912015-05-06 06:33:17 +03005from test.support.script_helper import assert_python_ok, assert_python_failure
Alexander Belopolsky43ca7102010-06-14 17:32:03 +00006import time
Georg Brandl7004bd12010-10-19 18:54:25 +00007import locale
R David Murrayd0c86952012-05-29 12:55:05 -04008import sys
Ezio Melotti85710a42012-09-21 17:26:35 +03009import datetime
Serhiy Storchakaaef859c2015-02-05 15:14:35 +020010import os
R David Murrayd0c86952012-05-29 12:55:05 -040011
Alexander Belopolsky66c88ce2017-10-26 15:34:11 -040012# From https://en.wikipedia.org/wiki/Leap_year_starting_on_Saturday
13result_0_02_text = """\
14 February 0
15Mo Tu We Th Fr Sa Su
16 1 2 3 4 5 6
17 7 8 9 10 11 12 13
1814 15 16 17 18 19 20
1921 22 23 24 25 26 27
2028 29
21"""
22
23result_0_text = """\
24 0
25
26 January February March
27Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su
28 1 2 1 2 3 4 5 6 1 2 3 4 5
29 3 4 5 6 7 8 9 7 8 9 10 11 12 13 6 7 8 9 10 11 12
3010 11 12 13 14 15 16 14 15 16 17 18 19 20 13 14 15 16 17 18 19
3117 18 19 20 21 22 23 21 22 23 24 25 26 27 20 21 22 23 24 25 26
3224 25 26 27 28 29 30 28 29 27 28 29 30 31
3331
34
35 April May June
36Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su
37 1 2 1 2 3 4 5 6 7 1 2 3 4
38 3 4 5 6 7 8 9 8 9 10 11 12 13 14 5 6 7 8 9 10 11
3910 11 12 13 14 15 16 15 16 17 18 19 20 21 12 13 14 15 16 17 18
4017 18 19 20 21 22 23 22 23 24 25 26 27 28 19 20 21 22 23 24 25
4124 25 26 27 28 29 30 29 30 31 26 27 28 29 30
42
43 July August September
44Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su
45 1 2 1 2 3 4 5 6 1 2 3
46 3 4 5 6 7 8 9 7 8 9 10 11 12 13 4 5 6 7 8 9 10
4710 11 12 13 14 15 16 14 15 16 17 18 19 20 11 12 13 14 15 16 17
4817 18 19 20 21 22 23 21 22 23 24 25 26 27 18 19 20 21 22 23 24
4924 25 26 27 28 29 30 28 29 30 31 25 26 27 28 29 30
5031
51
52 October November December
53Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su
54 1 1 2 3 4 5 1 2 3
55 2 3 4 5 6 7 8 6 7 8 9 10 11 12 4 5 6 7 8 9 10
56 9 10 11 12 13 14 15 13 14 15 16 17 18 19 11 12 13 14 15 16 17
5716 17 18 19 20 21 22 20 21 22 23 24 25 26 18 19 20 21 22 23 24
5823 24 25 26 27 28 29 27 28 29 30 25 26 27 28 29 30 31
5930 31
60"""
61
Serhiy Storchakaaef859c2015-02-05 15:14:35 +020062result_2004_01_text = """\
R David Murrayd0c86952012-05-29 12:55:05 -040063 January 2004
64Mo Tu We Th Fr Sa Su
65 1 2 3 4
66 5 6 7 8 9 10 11
6712 13 14 15 16 17 18
6819 20 21 22 23 24 25
6926 27 28 29 30 31
70"""
Fred Draked077ca12001-12-12 05:38:08 +000071
Serhiy Storchakaaef859c2015-02-05 15:14:35 +020072result_2004_text = """\
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000073 2004
74
75 January February March
76Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su
77 1 2 3 4 1 1 2 3 4 5 6 7
78 5 6 7 8 9 10 11 2 3 4 5 6 7 8 8 9 10 11 12 13 14
7912 13 14 15 16 17 18 9 10 11 12 13 14 15 15 16 17 18 19 20 21
8019 20 21 22 23 24 25 16 17 18 19 20 21 22 22 23 24 25 26 27 28
8126 27 28 29 30 31 23 24 25 26 27 28 29 29 30 31
82
83 April May June
84Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su
85 1 2 3 4 1 2 1 2 3 4 5 6
86 5 6 7 8 9 10 11 3 4 5 6 7 8 9 7 8 9 10 11 12 13
8712 13 14 15 16 17 18 10 11 12 13 14 15 16 14 15 16 17 18 19 20
8819 20 21 22 23 24 25 17 18 19 20 21 22 23 21 22 23 24 25 26 27
8926 27 28 29 30 24 25 26 27 28 29 30 28 29 30
90 31
91
92 July August September
93Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su
94 1 2 3 4 1 1 2 3 4 5
95 5 6 7 8 9 10 11 2 3 4 5 6 7 8 6 7 8 9 10 11 12
9612 13 14 15 16 17 18 9 10 11 12 13 14 15 13 14 15 16 17 18 19
9719 20 21 22 23 24 25 16 17 18 19 20 21 22 20 21 22 23 24 25 26
9826 27 28 29 30 31 23 24 25 26 27 28 29 27 28 29 30
99 30 31
100
101 October November December
102Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su
103 1 2 3 1 2 3 4 5 6 7 1 2 3 4 5
104 4 5 6 7 8 9 10 8 9 10 11 12 13 14 6 7 8 9 10 11 12
10511 12 13 14 15 16 17 15 16 17 18 19 20 21 13 14 15 16 17 18 19
10618 19 20 21 22 23 24 22 23 24 25 26 27 28 20 21 22 23 24 25 26
10725 26 27 28 29 30 31 29 30 27 28 29 30 31
108"""
109
Oz N Tiram8b7a4cc2017-06-06 11:35:59 +0200110
111default_format = dict(year="year", month="month", encoding="ascii")
112
Serhiy Storchakaaef859c2015-02-05 15:14:35 +0200113result_2004_html = """\
Oz N Tiram8b7a4cc2017-06-06 11:35:59 +0200114<?xml version="1.0" encoding="{encoding}"?>
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000115<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
116<html>
117<head>
Oz N Tiram8b7a4cc2017-06-06 11:35:59 +0200118<meta http-equiv="Content-Type" content="text/html; charset={encoding}" />
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000119<link rel="stylesheet" type="text/css" href="calendar.css" />
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000120<title>Calendar for 2004</title>
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000121</head>
122<body>
Oz N Tiram8b7a4cc2017-06-06 11:35:59 +0200123<table border="0" cellpadding="0" cellspacing="0" class="{year}">
124<tr><th colspan="3" class="{year}">2004</th></tr><tr><td><table border="0" cellpadding="0" cellspacing="0" class="{month}">
125<tr><th colspan="7" class="{month}">January</th></tr>
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000126<tr><th class="mon">Mon</th><th class="tue">Tue</th><th class="wed">Wed</th><th class="thu">Thu</th><th class="fri">Fri</th><th class="sat">Sat</th><th class="sun">Sun</th></tr>
127<tr><td class="noday">&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>
128<tr><td class="mon">5</td><td class="tue">6</td><td class="wed">7</td><td class="thu">8</td><td class="fri">9</td><td class="sat">10</td><td class="sun">11</td></tr>
129<tr><td class="mon">12</td><td class="tue">13</td><td class="wed">14</td><td class="thu">15</td><td class="fri">16</td><td class="sat">17</td><td class="sun">18</td></tr>
130<tr><td class="mon">19</td><td class="tue">20</td><td class="wed">21</td><td class="thu">22</td><td class="fri">23</td><td class="sat">24</td><td class="sun">25</td></tr>
131<tr><td class="mon">26</td><td class="tue">27</td><td class="wed">28</td><td class="thu">29</td><td class="fri">30</td><td class="sat">31</td><td class="noday">&nbsp;</td></tr>
132</table>
Oz N Tiram8b7a4cc2017-06-06 11:35:59 +0200133</td><td><table border="0" cellpadding="0" cellspacing="0" class="{month}">
134<tr><th colspan="7" class="{month}">February</th></tr>
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000135<tr><th class="mon">Mon</th><th class="tue">Tue</th><th class="wed">Wed</th><th class="thu">Thu</th><th class="fri">Fri</th><th class="sat">Sat</th><th class="sun">Sun</th></tr>
136<tr><td class="noday">&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>
137<tr><td class="mon">2</td><td class="tue">3</td><td class="wed">4</td><td class="thu">5</td><td class="fri">6</td><td class="sat">7</td><td class="sun">8</td></tr>
138<tr><td class="mon">9</td><td class="tue">10</td><td class="wed">11</td><td class="thu">12</td><td class="fri">13</td><td class="sat">14</td><td class="sun">15</td></tr>
139<tr><td class="mon">16</td><td class="tue">17</td><td class="wed">18</td><td class="thu">19</td><td class="fri">20</td><td class="sat">21</td><td class="sun">22</td></tr>
140<tr><td class="mon">23</td><td class="tue">24</td><td class="wed">25</td><td class="thu">26</td><td class="fri">27</td><td class="sat">28</td><td class="sun">29</td></tr>
141</table>
Oz N Tiram8b7a4cc2017-06-06 11:35:59 +0200142</td><td><table border="0" cellpadding="0" cellspacing="0" class="{month}">
143<tr><th colspan="7" class="{month}">March</th></tr>
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000144<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>
145<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>
146<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>
147<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>
148<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>
149<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>
150</table>
Oz N Tiram8b7a4cc2017-06-06 11:35:59 +0200151</td></tr><tr><td><table border="0" cellpadding="0" cellspacing="0" class="{month}">
152<tr><th colspan="7" class="{month}">April</th></tr>
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000153<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>
154<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>
155<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>
156<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>
157<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>
158<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>
159</table>
Oz N Tiram8b7a4cc2017-06-06 11:35:59 +0200160</td><td><table border="0" cellpadding="0" cellspacing="0" class="{month}">
161<tr><th colspan="7" class="{month}">May</th></tr>
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000162<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>
163<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>
164<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>
165<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>
166<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>
167<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>
168<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>
169</table>
Oz N Tiram8b7a4cc2017-06-06 11:35:59 +0200170</td><td><table border="0" cellpadding="0" cellspacing="0" class="{month}">
171<tr><th colspan="7" class="{month}">June</th></tr>
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000172<tr><th class="mon">Mon</th><th class="tue">Tue</th><th class="wed">Wed</th><th class="thu">Thu</th><th class="fri">Fri</th><th class="sat">Sat</th><th class="sun">Sun</th></tr>
173<tr><td class="noday">&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>
174<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>
175<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>
176<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>
177<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>
178</table>
Oz N Tiram8b7a4cc2017-06-06 11:35:59 +0200179</td></tr><tr><td><table border="0" cellpadding="0" cellspacing="0" class="{month}">
180<tr><th colspan="7" class="{month}">July</th></tr>
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000181<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>
182<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>
183<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>
184<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>
185<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>
186<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>
187</table>
Oz N Tiram8b7a4cc2017-06-06 11:35:59 +0200188</td><td><table border="0" cellpadding="0" cellspacing="0" class="{month}">
189<tr><th colspan="7" class="{month}">August</th></tr>
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000190<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>
191<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>
192<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>
193<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>
194<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>
195<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>
196<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>
197</table>
Oz N Tiram8b7a4cc2017-06-06 11:35:59 +0200198</td><td><table border="0" cellpadding="0" cellspacing="0" class="{month}">
199<tr><th colspan="7" class="{month}">September</th></tr>
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000200<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>
201<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>
202<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>
203<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>
204<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>
205<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>
206</table>
Oz N Tiram8b7a4cc2017-06-06 11:35:59 +0200207</td></tr><tr><td><table border="0" cellpadding="0" cellspacing="0" class="{month}">
208<tr><th colspan="7" class="{month}">October</th></tr>
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000209<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>
210<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>
211<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>
212<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>
213<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>
214<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>
215</table>
Oz N Tiram8b7a4cc2017-06-06 11:35:59 +0200216</td><td><table border="0" cellpadding="0" cellspacing="0" class="{month}">
217<tr><th colspan="7" class="{month}">November</th></tr>
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000218<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>
219<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>
220<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>
221<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>
222<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>
223<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>
224</table>
Oz N Tiram8b7a4cc2017-06-06 11:35:59 +0200225</td><td><table border="0" cellpadding="0" cellspacing="0" class="{month}">
226<tr><th colspan="7" class="{month}">December</th></tr>
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000227<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>
228<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>
229<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>
230<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>
231<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>
232<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>
233</table>
234</td></tr></table></body>
235</html>
236"""
237
R David Murrayd0c86952012-05-29 12:55:05 -0400238result_2004_days = [
239 [[[0, 0, 0, 1, 2, 3, 4],
240 [5, 6, 7, 8, 9, 10, 11],
241 [12, 13, 14, 15, 16, 17, 18],
242 [19, 20, 21, 22, 23, 24, 25],
243 [26, 27, 28, 29, 30, 31, 0]],
244 [[0, 0, 0, 0, 0, 0, 1],
245 [2, 3, 4, 5, 6, 7, 8],
246 [9, 10, 11, 12, 13, 14, 15],
247 [16, 17, 18, 19, 20, 21, 22],
248 [23, 24, 25, 26, 27, 28, 29]],
249 [[1, 2, 3, 4, 5, 6, 7],
250 [8, 9, 10, 11, 12, 13, 14],
251 [15, 16, 17, 18, 19, 20, 21],
252 [22, 23, 24, 25, 26, 27, 28],
253 [29, 30, 31, 0, 0, 0, 0]]],
254 [[[0, 0, 0, 1, 2, 3, 4],
255 [5, 6, 7, 8, 9, 10, 11],
256 [12, 13, 14, 15, 16, 17, 18],
257 [19, 20, 21, 22, 23, 24, 25],
258 [26, 27, 28, 29, 30, 0, 0]],
259 [[0, 0, 0, 0, 0, 1, 2],
260 [3, 4, 5, 6, 7, 8, 9],
261 [10, 11, 12, 13, 14, 15, 16],
262 [17, 18, 19, 20, 21, 22, 23],
263 [24, 25, 26, 27, 28, 29, 30],
264 [31, 0, 0, 0, 0, 0, 0]],
265 [[0, 1, 2, 3, 4, 5, 6],
266 [7, 8, 9, 10, 11, 12, 13],
267 [14, 15, 16, 17, 18, 19, 20],
268 [21, 22, 23, 24, 25, 26, 27],
269 [28, 29, 30, 0, 0, 0, 0]]],
270 [[[0, 0, 0, 1, 2, 3, 4],
271 [5, 6, 7, 8, 9, 10, 11],
272 [12, 13, 14, 15, 16, 17, 18],
273 [19, 20, 21, 22, 23, 24, 25],
274 [26, 27, 28, 29, 30, 31, 0]],
275 [[0, 0, 0, 0, 0, 0, 1],
276 [2, 3, 4, 5, 6, 7, 8],
277 [9, 10, 11, 12, 13, 14, 15],
278 [16, 17, 18, 19, 20, 21, 22],
279 [23, 24, 25, 26, 27, 28, 29],
280 [30, 31, 0, 0, 0, 0, 0]],
281 [[0, 0, 1, 2, 3, 4, 5],
282 [6, 7, 8, 9, 10, 11, 12],
283 [13, 14, 15, 16, 17, 18, 19],
284 [20, 21, 22, 23, 24, 25, 26],
285 [27, 28, 29, 30, 0, 0, 0]]],
286 [[[0, 0, 0, 0, 1, 2, 3],
287 [4, 5, 6, 7, 8, 9, 10],
288 [11, 12, 13, 14, 15, 16, 17],
289 [18, 19, 20, 21, 22, 23, 24],
290 [25, 26, 27, 28, 29, 30, 31]],
291 [[1, 2, 3, 4, 5, 6, 7],
292 [8, 9, 10, 11, 12, 13, 14],
293 [15, 16, 17, 18, 19, 20, 21],
294 [22, 23, 24, 25, 26, 27, 28],
295 [29, 30, 0, 0, 0, 0, 0]],
296 [[0, 0, 1, 2, 3, 4, 5],
297 [6, 7, 8, 9, 10, 11, 12],
298 [13, 14, 15, 16, 17, 18, 19],
299 [20, 21, 22, 23, 24, 25, 26],
300 [27, 28, 29, 30, 31, 0, 0]]]
301]
302
303result_2004_dates = \
304 [[['12/29/03 12/30/03 12/31/03 01/01/04 01/02/04 01/03/04 01/04/04',
305 '01/05/04 01/06/04 01/07/04 01/08/04 01/09/04 01/10/04 01/11/04',
306 '01/12/04 01/13/04 01/14/04 01/15/04 01/16/04 01/17/04 01/18/04',
307 '01/19/04 01/20/04 01/21/04 01/22/04 01/23/04 01/24/04 01/25/04',
308 '01/26/04 01/27/04 01/28/04 01/29/04 01/30/04 01/31/04 02/01/04'],
309 ['01/26/04 01/27/04 01/28/04 01/29/04 01/30/04 01/31/04 02/01/04',
310 '02/02/04 02/03/04 02/04/04 02/05/04 02/06/04 02/07/04 02/08/04',
311 '02/09/04 02/10/04 02/11/04 02/12/04 02/13/04 02/14/04 02/15/04',
312 '02/16/04 02/17/04 02/18/04 02/19/04 02/20/04 02/21/04 02/22/04',
313 '02/23/04 02/24/04 02/25/04 02/26/04 02/27/04 02/28/04 02/29/04'],
314 ['03/01/04 03/02/04 03/03/04 03/04/04 03/05/04 03/06/04 03/07/04',
315 '03/08/04 03/09/04 03/10/04 03/11/04 03/12/04 03/13/04 03/14/04',
316 '03/15/04 03/16/04 03/17/04 03/18/04 03/19/04 03/20/04 03/21/04',
317 '03/22/04 03/23/04 03/24/04 03/25/04 03/26/04 03/27/04 03/28/04',
318 '03/29/04 03/30/04 03/31/04 04/01/04 04/02/04 04/03/04 04/04/04']],
319 [['03/29/04 03/30/04 03/31/04 04/01/04 04/02/04 04/03/04 04/04/04',
320 '04/05/04 04/06/04 04/07/04 04/08/04 04/09/04 04/10/04 04/11/04',
321 '04/12/04 04/13/04 04/14/04 04/15/04 04/16/04 04/17/04 04/18/04',
322 '04/19/04 04/20/04 04/21/04 04/22/04 04/23/04 04/24/04 04/25/04',
323 '04/26/04 04/27/04 04/28/04 04/29/04 04/30/04 05/01/04 05/02/04'],
324 ['04/26/04 04/27/04 04/28/04 04/29/04 04/30/04 05/01/04 05/02/04',
325 '05/03/04 05/04/04 05/05/04 05/06/04 05/07/04 05/08/04 05/09/04',
326 '05/10/04 05/11/04 05/12/04 05/13/04 05/14/04 05/15/04 05/16/04',
327 '05/17/04 05/18/04 05/19/04 05/20/04 05/21/04 05/22/04 05/23/04',
328 '05/24/04 05/25/04 05/26/04 05/27/04 05/28/04 05/29/04 05/30/04',
329 '05/31/04 06/01/04 06/02/04 06/03/04 06/04/04 06/05/04 06/06/04'],
330 ['05/31/04 06/01/04 06/02/04 06/03/04 06/04/04 06/05/04 06/06/04',
331 '06/07/04 06/08/04 06/09/04 06/10/04 06/11/04 06/12/04 06/13/04',
332 '06/14/04 06/15/04 06/16/04 06/17/04 06/18/04 06/19/04 06/20/04',
333 '06/21/04 06/22/04 06/23/04 06/24/04 06/25/04 06/26/04 06/27/04',
334 '06/28/04 06/29/04 06/30/04 07/01/04 07/02/04 07/03/04 07/04/04']],
335 [['06/28/04 06/29/04 06/30/04 07/01/04 07/02/04 07/03/04 07/04/04',
336 '07/05/04 07/06/04 07/07/04 07/08/04 07/09/04 07/10/04 07/11/04',
337 '07/12/04 07/13/04 07/14/04 07/15/04 07/16/04 07/17/04 07/18/04',
338 '07/19/04 07/20/04 07/21/04 07/22/04 07/23/04 07/24/04 07/25/04',
339 '07/26/04 07/27/04 07/28/04 07/29/04 07/30/04 07/31/04 08/01/04'],
340 ['07/26/04 07/27/04 07/28/04 07/29/04 07/30/04 07/31/04 08/01/04',
341 '08/02/04 08/03/04 08/04/04 08/05/04 08/06/04 08/07/04 08/08/04',
342 '08/09/04 08/10/04 08/11/04 08/12/04 08/13/04 08/14/04 08/15/04',
343 '08/16/04 08/17/04 08/18/04 08/19/04 08/20/04 08/21/04 08/22/04',
344 '08/23/04 08/24/04 08/25/04 08/26/04 08/27/04 08/28/04 08/29/04',
345 '08/30/04 08/31/04 09/01/04 09/02/04 09/03/04 09/04/04 09/05/04'],
346 ['08/30/04 08/31/04 09/01/04 09/02/04 09/03/04 09/04/04 09/05/04',
347 '09/06/04 09/07/04 09/08/04 09/09/04 09/10/04 09/11/04 09/12/04',
348 '09/13/04 09/14/04 09/15/04 09/16/04 09/17/04 09/18/04 09/19/04',
349 '09/20/04 09/21/04 09/22/04 09/23/04 09/24/04 09/25/04 09/26/04',
350 '09/27/04 09/28/04 09/29/04 09/30/04 10/01/04 10/02/04 10/03/04']],
351 [['09/27/04 09/28/04 09/29/04 09/30/04 10/01/04 10/02/04 10/03/04',
352 '10/04/04 10/05/04 10/06/04 10/07/04 10/08/04 10/09/04 10/10/04',
353 '10/11/04 10/12/04 10/13/04 10/14/04 10/15/04 10/16/04 10/17/04',
354 '10/18/04 10/19/04 10/20/04 10/21/04 10/22/04 10/23/04 10/24/04',
355 '10/25/04 10/26/04 10/27/04 10/28/04 10/29/04 10/30/04 10/31/04'],
356 ['11/01/04 11/02/04 11/03/04 11/04/04 11/05/04 11/06/04 11/07/04',
357 '11/08/04 11/09/04 11/10/04 11/11/04 11/12/04 11/13/04 11/14/04',
358 '11/15/04 11/16/04 11/17/04 11/18/04 11/19/04 11/20/04 11/21/04',
359 '11/22/04 11/23/04 11/24/04 11/25/04 11/26/04 11/27/04 11/28/04',
360 '11/29/04 11/30/04 12/01/04 12/02/04 12/03/04 12/04/04 12/05/04'],
361 ['11/29/04 11/30/04 12/01/04 12/02/04 12/03/04 12/04/04 12/05/04',
362 '12/06/04 12/07/04 12/08/04 12/09/04 12/10/04 12/11/04 12/12/04',
363 '12/13/04 12/14/04 12/15/04 12/16/04 12/17/04 12/18/04 12/19/04',
364 '12/20/04 12/21/04 12/22/04 12/23/04 12/24/04 12/25/04 12/26/04',
365 '12/27/04 12/28/04 12/29/04 12/30/04 12/31/04 01/01/05 01/02/05']]]
366
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000367
368class OutputTestCase(unittest.TestCase):
369 def normalize_calendar(self, s):
Mark Dickinson934896d2009-02-21 20:59:32 +0000370 # Filters out locale dependent strings
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000371 def neitherspacenordigit(c):
372 return not c.isspace() and not c.isdigit()
373
374 lines = []
Ezio Melottid8b509b2011-09-28 17:37:55 +0300375 for line in s.splitlines(keepends=False):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000376 # Drop texts, as they are locale dependent
377 if line and not filter(neitherspacenordigit, line):
378 lines.append(line)
379 return lines
380
R David Murrayd0c86952012-05-29 12:55:05 -0400381 def check_htmlcalendar_encoding(self, req, res):
382 cal = calendar.HTMLCalendar()
Oz N Tiram8b7a4cc2017-06-06 11:35:59 +0200383 format_ = default_format.copy()
384 format_["encoding"] = req or 'utf-8'
385 output = cal.formatyearpage(2004, encoding=req)
R David Murrayd0c86952012-05-29 12:55:05 -0400386 self.assertEqual(
Oz N Tiram8b7a4cc2017-06-06 11:35:59 +0200387 output,
388 result_2004_html.format(**format_).encode(res)
R David Murrayd0c86952012-05-29 12:55:05 -0400389 )
390
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000391 def test_output(self):
392 self.assertEqual(
393 self.normalize_calendar(calendar.calendar(2004)),
394 self.normalize_calendar(result_2004_text)
395 )
Alexander Belopolsky66c88ce2017-10-26 15:34:11 -0400396 self.assertEqual(
397 self.normalize_calendar(calendar.calendar(0)),
398 self.normalize_calendar(result_0_text)
399 )
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000400
401 def test_output_textcalendar(self):
402 self.assertEqual(
Serhiy Storchakaaef859c2015-02-05 15:14:35 +0200403 calendar.TextCalendar().formatyear(2004),
404 result_2004_text
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000405 )
Alexander Belopolsky66c88ce2017-10-26 15:34:11 -0400406 self.assertEqual(
407 calendar.TextCalendar().formatyear(0),
408 result_0_text
409 )
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000410
R David Murrayd0c86952012-05-29 12:55:05 -0400411 def test_output_htmlcalendar_encoding_ascii(self):
412 self.check_htmlcalendar_encoding('ascii', 'ascii')
413
414 def test_output_htmlcalendar_encoding_utf8(self):
415 self.check_htmlcalendar_encoding('utf-8', 'utf-8')
416
417 def test_output_htmlcalendar_encoding_default(self):
418 self.check_htmlcalendar_encoding(None, sys.getdefaultencoding())
419
420 def test_yeardatescalendar(self):
421 def shrink(cal):
R David Murraybb756782012-05-30 08:10:54 -0400422 return [[[' '.join('{:02d}/{:02d}/{}'.format(
423 d.month, d.day, str(d.year)[-2:]) for d in z)
424 for z in y] for y in x] for x in cal]
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000425 self.assertEqual(
R David Murrayd0c86952012-05-29 12:55:05 -0400426 shrink(calendar.Calendar().yeardatescalendar(2004)),
427 result_2004_dates
428 )
429
430 def test_yeardayscalendar(self):
431 self.assertEqual(
432 calendar.Calendar().yeardayscalendar(2004),
433 result_2004_days
434 )
435
436 def test_formatweekheader_short(self):
437 self.assertEqual(
438 calendar.TextCalendar().formatweekheader(2),
439 'Mo Tu We Th Fr Sa Su'
440 )
441
442 def test_formatweekheader_long(self):
443 self.assertEqual(
444 calendar.TextCalendar().formatweekheader(9),
445 ' Monday Tuesday Wednesday Thursday '
446 ' Friday Saturday Sunday '
447 )
448
449 def test_formatmonth(self):
450 self.assertEqual(
Serhiy Storchakaaef859c2015-02-05 15:14:35 +0200451 calendar.TextCalendar().formatmonth(2004, 1),
452 result_2004_01_text
R David Murrayd0c86952012-05-29 12:55:05 -0400453 )
Alexander Belopolsky66c88ce2017-10-26 15:34:11 -0400454 self.assertEqual(
455 calendar.TextCalendar().formatmonth(0, 2),
456 result_0_02_text
457 )
R David Murrayd0c86952012-05-29 12:55:05 -0400458
459 def test_formatmonthname_with_year(self):
460 self.assertEqual(
461 calendar.HTMLCalendar().formatmonthname(2004, 1, withyear=True),
462 '<tr><th colspan="7" class="month">January 2004</th></tr>'
463 )
464
465 def test_formatmonthname_without_year(self):
466 self.assertEqual(
467 calendar.HTMLCalendar().formatmonthname(2004, 1, withyear=False),
468 '<tr><th colspan="7" class="month">January</th></tr>'
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000469 )
470
Ezio Melotti87f09372013-09-14 04:55:53 +0300471 def test_prweek(self):
472 with support.captured_stdout() as out:
473 week = [(1,0), (2,1), (3,2), (4,3), (5,4), (6,5), (7,6)]
474 calendar.TextCalendar().prweek(week, 1)
Serhiy Storchaka0595ed22016-10-25 15:20:58 +0300475 self.assertEqual(out.getvalue(), " 1 2 3 4 5 6 7")
Ezio Melotti87f09372013-09-14 04:55:53 +0300476
477 def test_prmonth(self):
478 with support.captured_stdout() as out:
479 calendar.TextCalendar().prmonth(2004, 1)
Serhiy Storchaka7ff51bd2016-10-25 15:00:52 +0300480 self.assertEqual(out.getvalue(), result_2004_01_text)
Ezio Melotti87f09372013-09-14 04:55:53 +0300481
482 def test_pryear(self):
483 with support.captured_stdout() as out:
484 calendar.TextCalendar().pryear(2004)
Serhiy Storchaka0595ed22016-10-25 15:20:58 +0300485 self.assertEqual(out.getvalue(), result_2004_text)
Ezio Melotti87f09372013-09-14 04:55:53 +0300486
487 def test_format(self):
488 with support.captured_stdout() as out:
489 calendar.format(["1", "2", "3"], colwidth=3, spacing=1)
490 self.assertEqual(out.getvalue().strip(), "1 2 3")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000491
Fred Draked077ca12001-12-12 05:38:08 +0000492class CalendarTestCase(unittest.TestCase):
493 def test_isleap(self):
494 # Make sure that the return is right for a few years, and
495 # ensure that the return values are 1 or 0, not just true or
496 # false (see SF bug #485794). Specific additional tests may
497 # be appropriate; this tests a single "cycle".
498 self.assertEqual(calendar.isleap(2000), 1)
499 self.assertEqual(calendar.isleap(2001), 0)
500 self.assertEqual(calendar.isleap(2002), 0)
501 self.assertEqual(calendar.isleap(2003), 0)
502
503 def test_setfirstweekday(self):
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000504 self.assertRaises(TypeError, calendar.setfirstweekday, 'flabber')
Fred Draked077ca12001-12-12 05:38:08 +0000505 self.assertRaises(ValueError, calendar.setfirstweekday, -1)
506 self.assertRaises(ValueError, calendar.setfirstweekday, 200)
507 orig = calendar.firstweekday()
508 calendar.setfirstweekday(calendar.SUNDAY)
509 self.assertEqual(calendar.firstweekday(), calendar.SUNDAY)
510 calendar.setfirstweekday(calendar.MONDAY)
511 self.assertEqual(calendar.firstweekday(), calendar.MONDAY)
512 calendar.setfirstweekday(orig)
513
R David Murrayd0c86952012-05-29 12:55:05 -0400514 def test_illegal_weekday_reported(self):
515 with self.assertRaisesRegex(calendar.IllegalWeekdayError, '123'):
516 calendar.setfirstweekday(123)
517
518 def test_enumerate_weekdays(self):
Skip Montanaro693c6c42002-03-15 03:57:04 +0000519 self.assertRaises(IndexError, calendar.day_abbr.__getitem__, -10)
520 self.assertRaises(IndexError, calendar.day_name.__getitem__, 10)
521 self.assertEqual(len([d for d in calendar.day_abbr]), 7)
Fred Draked077ca12001-12-12 05:38:08 +0000522
Tim Peters0c2c8e72002-03-23 03:26:53 +0000523 def test_days(self):
524 for attr in "day_name", "day_abbr":
525 value = getattr(calendar, attr)
526 self.assertEqual(len(value), 7)
527 self.assertEqual(len(value[:]), 7)
528 # ensure they're all unique
Tim Petersbbc0d442004-11-13 16:18:32 +0000529 self.assertEqual(len(set(value)), 7)
530 # verify it "acts like a sequence" in two forms of iteration
531 self.assertEqual(value[::-1], list(reversed(value)))
Tim Peters0c2c8e72002-03-23 03:26:53 +0000532
533 def test_months(self):
534 for attr in "month_name", "month_abbr":
535 value = getattr(calendar, attr)
536 self.assertEqual(len(value), 13)
537 self.assertEqual(len(value[:]), 13)
538 self.assertEqual(value[0], "")
539 # ensure they're all unique
Tim Petersbbc0d442004-11-13 16:18:32 +0000540 self.assertEqual(len(set(value)), 13)
541 # verify it "acts like a sequence" in two forms of iteration
542 self.assertEqual(value[::-1], list(reversed(value)))
Tim Peters0c2c8e72002-03-23 03:26:53 +0000543
R David Murrayd0c86952012-05-29 12:55:05 -0400544 def test_locale_calendars(self):
Georg Brandl7004bd12010-10-19 18:54:25 +0000545 # ensure that Locale{Text,HTML}Calendar resets the locale properly
546 # (it is still not thread-safe though)
Georg Brandl7004bd12010-10-19 18:54:25 +0000547 old_october = calendar.TextCalendar().formatmonthname(2010, 10, 10)
Georg Brandl9450cc02010-10-20 06:50:19 +0000548 try:
Serhiy Storchakaf9fcdb72013-01-31 16:00:42 +0200549 cal = calendar.LocaleTextCalendar(locale='')
550 local_weekday = cal.formatweekday(1, 10)
551 local_month = cal.formatmonthname(2010, 10, 10)
Georg Brandl9450cc02010-10-20 06:50:19 +0000552 except locale.Error:
553 # cannot set the system default locale -- skip rest of test
Serhiy Storchakaf9fcdb72013-01-31 16:00:42 +0200554 raise unittest.SkipTest('cannot set the system default locale')
555 self.assertIsInstance(local_weekday, str)
556 self.assertIsInstance(local_month, str)
557 self.assertEqual(len(local_weekday), 10)
558 self.assertGreaterEqual(len(local_month), 10)
559 cal = calendar.LocaleHTMLCalendar(locale='')
560 local_weekday = cal.formatweekday(1)
561 local_month = cal.formatmonthname(2010, 10)
562 self.assertIsInstance(local_weekday, str)
563 self.assertIsInstance(local_month, str)
Georg Brandl7004bd12010-10-19 18:54:25 +0000564 new_october = calendar.TextCalendar().formatmonthname(2010, 10, 10)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000565 self.assertEqual(old_october, new_october)
Georg Brandl7004bd12010-10-19 18:54:25 +0000566
Alexander Belopolskyfdd9b212017-10-24 13:17:10 -0400567 def test_itermonthdays3(self):
568 # ensure itermonthdays3 doesn't overflow after datetime.MAXYEAR
569 list(calendar.Calendar().itermonthdays3(datetime.MAXYEAR, 12))
570
571 def test_itermonthdays4(self):
572 cal = calendar.Calendar(firstweekday=3)
573 days = list(cal.itermonthdays4(2001, 2))
574 self.assertEqual(days[0], (2001, 2, 1, 3))
575 self.assertEqual(days[-1], (2001, 2, 28, 2))
Ezio Melotti85710a42012-09-21 17:26:35 +0300576
Alexander Belopolsky957b7562016-09-27 20:26:39 -0400577 def test_itermonthdays(self):
578 for firstweekday in range(7):
579 cal = calendar.Calendar(firstweekday)
580 # Test the extremes, see #28253 and #26650
581 for y, m in [(1, 1), (9999, 12)]:
582 days = list(cal.itermonthdays(y, m))
583 self.assertIn(len(days), (35, 42))
584 # Test a short month
585 cal = calendar.Calendar(firstweekday=3)
586 days = list(cal.itermonthdays(2001, 2))
587 self.assertEqual(days, list(range(1, 29)))
588
589 def test_itermonthdays2(self):
590 for firstweekday in range(7):
591 cal = calendar.Calendar(firstweekday)
592 # Test the extremes, see #28253 and #26650
593 for y, m in [(1, 1), (9999, 12)]:
594 days = list(cal.itermonthdays2(y, m))
595 self.assertEqual(days[0][1], firstweekday)
596 self.assertEqual(days[-1][1], (firstweekday - 1) % 7)
597
Walter Dörwald59ad4562004-07-02 19:00:09 +0000598
599class MonthCalendarTestCase(unittest.TestCase):
600 def setUp(self):
601 self.oldfirstweekday = calendar.firstweekday()
602 calendar.setfirstweekday(self.firstweekday)
603
604 def tearDown(self):
605 calendar.setfirstweekday(self.oldfirstweekday)
606
607 def check_weeks(self, year, month, weeks):
608 cal = calendar.monthcalendar(year, month)
609 self.assertEqual(len(cal), len(weeks))
Guido van Rossum805365e2007-05-07 22:24:25 +0000610 for i in range(len(weeks)):
Walter Dörwald59ad4562004-07-02 19:00:09 +0000611 self.assertEqual(weeks[i], sum(day != 0 for day in cal[i]))
612
613
614class MondayTestCase(MonthCalendarTestCase):
615 firstweekday = calendar.MONDAY
616
617 def test_february(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000618 # A 28-day february starting on monday (7+7+7+7 days)
Walter Dörwald59ad4562004-07-02 19:00:09 +0000619 self.check_weeks(1999, 2, (7, 7, 7, 7))
620
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000621 # A 28-day february starting on tuesday (6+7+7+7+1 days)
Walter Dörwald59ad4562004-07-02 19:00:09 +0000622 self.check_weeks(2005, 2, (6, 7, 7, 7, 1))
623
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000624 # A 28-day february starting on sunday (1+7+7+7+6 days)
Walter Dörwald59ad4562004-07-02 19:00:09 +0000625 self.check_weeks(1987, 2, (1, 7, 7, 7, 6))
626
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000627 # A 29-day february starting on monday (7+7+7+7+1 days)
Walter Dörwald59ad4562004-07-02 19:00:09 +0000628 self.check_weeks(1988, 2, (7, 7, 7, 7, 1))
629
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000630 # A 29-day february starting on tuesday (6+7+7+7+2 days)
Walter Dörwald59ad4562004-07-02 19:00:09 +0000631 self.check_weeks(1972, 2, (6, 7, 7, 7, 2))
632
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000633 # A 29-day february starting on sunday (1+7+7+7+7 days)
Walter Dörwald59ad4562004-07-02 19:00:09 +0000634 self.check_weeks(2004, 2, (1, 7, 7, 7, 7))
635
636 def test_april(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000637 # A 30-day april starting on monday (7+7+7+7+2 days)
Walter Dörwald59ad4562004-07-02 19:00:09 +0000638 self.check_weeks(1935, 4, (7, 7, 7, 7, 2))
639
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000640 # A 30-day april starting on tuesday (6+7+7+7+3 days)
Walter Dörwald59ad4562004-07-02 19:00:09 +0000641 self.check_weeks(1975, 4, (6, 7, 7, 7, 3))
642
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000643 # A 30-day april starting on sunday (1+7+7+7+7+1 days)
Walter Dörwald59ad4562004-07-02 19:00:09 +0000644 self.check_weeks(1945, 4, (1, 7, 7, 7, 7, 1))
645
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000646 # A 30-day april starting on saturday (2+7+7+7+7 days)
Walter Dörwald59ad4562004-07-02 19:00:09 +0000647 self.check_weeks(1995, 4, (2, 7, 7, 7, 7))
648
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000649 # A 30-day april starting on friday (3+7+7+7+6 days)
Walter Dörwald59ad4562004-07-02 19:00:09 +0000650 self.check_weeks(1994, 4, (3, 7, 7, 7, 6))
651
652 def test_december(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000653 # A 31-day december starting on monday (7+7+7+7+3 days)
Walter Dörwald59ad4562004-07-02 19:00:09 +0000654 self.check_weeks(1980, 12, (7, 7, 7, 7, 3))
655
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000656 # A 31-day december starting on tuesday (6+7+7+7+4 days)
Walter Dörwald59ad4562004-07-02 19:00:09 +0000657 self.check_weeks(1987, 12, (6, 7, 7, 7, 4))
658
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000659 # A 31-day december starting on sunday (1+7+7+7+7+2 days)
Walter Dörwald59ad4562004-07-02 19:00:09 +0000660 self.check_weeks(1968, 12, (1, 7, 7, 7, 7, 2))
661
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000662 # A 31-day december starting on thursday (4+7+7+7+6 days)
Walter Dörwald59ad4562004-07-02 19:00:09 +0000663 self.check_weeks(1988, 12, (4, 7, 7, 7, 6))
664
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000665 # A 31-day december starting on friday (3+7+7+7+7 days)
Walter Dörwald59ad4562004-07-02 19:00:09 +0000666 self.check_weeks(2017, 12, (3, 7, 7, 7, 7))
667
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000668 # A 31-day december starting on saturday (2+7+7+7+7+1 days)
Walter Dörwald59ad4562004-07-02 19:00:09 +0000669 self.check_weeks(2068, 12, (2, 7, 7, 7, 7, 1))
670
671
Walter Dörwald302fa6d2004-07-08 17:14:17 +0000672class SundayTestCase(MonthCalendarTestCase):
673 firstweekday = calendar.SUNDAY
674
675 def test_february(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000676 # A 28-day february starting on sunday (7+7+7+7 days)
Walter Dörwald302fa6d2004-07-08 17:14:17 +0000677 self.check_weeks(2009, 2, (7, 7, 7, 7))
678
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000679 # A 28-day february starting on monday (6+7+7+7+1 days)
Walter Dörwald302fa6d2004-07-08 17:14:17 +0000680 self.check_weeks(1999, 2, (6, 7, 7, 7, 1))
681
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000682 # A 28-day february starting on saturday (1+7+7+7+6 days)
Walter Dörwald302fa6d2004-07-08 17:14:17 +0000683 self.check_weeks(1997, 2, (1, 7, 7, 7, 6))
684
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000685 # A 29-day february starting on sunday (7+7+7+7+1 days)
Walter Dörwald302fa6d2004-07-08 17:14:17 +0000686 self.check_weeks(2004, 2, (7, 7, 7, 7, 1))
687
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000688 # A 29-day february starting on monday (6+7+7+7+2 days)
Walter Dörwald302fa6d2004-07-08 17:14:17 +0000689 self.check_weeks(1960, 2, (6, 7, 7, 7, 2))
690
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000691 # A 29-day february starting on saturday (1+7+7+7+7 days)
Walter Dörwald302fa6d2004-07-08 17:14:17 +0000692 self.check_weeks(1964, 2, (1, 7, 7, 7, 7))
693
694 def test_april(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000695 # A 30-day april starting on sunday (7+7+7+7+2 days)
Walter Dörwald302fa6d2004-07-08 17:14:17 +0000696 self.check_weeks(1923, 4, (7, 7, 7, 7, 2))
697
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000698 # A 30-day april starting on monday (6+7+7+7+3 days)
Walter Dörwald302fa6d2004-07-08 17:14:17 +0000699 self.check_weeks(1918, 4, (6, 7, 7, 7, 3))
700
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000701 # A 30-day april starting on saturday (1+7+7+7+7+1 days)
Walter Dörwald302fa6d2004-07-08 17:14:17 +0000702 self.check_weeks(1950, 4, (1, 7, 7, 7, 7, 1))
703
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000704 # A 30-day april starting on friday (2+7+7+7+7 days)
Walter Dörwald302fa6d2004-07-08 17:14:17 +0000705 self.check_weeks(1960, 4, (2, 7, 7, 7, 7))
706
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000707 # A 30-day april starting on thursday (3+7+7+7+6 days)
Walter Dörwald302fa6d2004-07-08 17:14:17 +0000708 self.check_weeks(1909, 4, (3, 7, 7, 7, 6))
709
710 def test_december(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000711 # A 31-day december starting on sunday (7+7+7+7+3 days)
Walter Dörwald302fa6d2004-07-08 17:14:17 +0000712 self.check_weeks(2080, 12, (7, 7, 7, 7, 3))
713
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000714 # A 31-day december starting on monday (6+7+7+7+4 days)
Walter Dörwald302fa6d2004-07-08 17:14:17 +0000715 self.check_weeks(1941, 12, (6, 7, 7, 7, 4))
716
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000717 # A 31-day december starting on saturday (1+7+7+7+7+2 days)
Walter Dörwald302fa6d2004-07-08 17:14:17 +0000718 self.check_weeks(1923, 12, (1, 7, 7, 7, 7, 2))
719
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000720 # A 31-day december starting on wednesday (4+7+7+7+6 days)
Walter Dörwald302fa6d2004-07-08 17:14:17 +0000721 self.check_weeks(1948, 12, (4, 7, 7, 7, 6))
722
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000723 # A 31-day december starting on thursday (3+7+7+7+7 days)
Walter Dörwald302fa6d2004-07-08 17:14:17 +0000724 self.check_weeks(1927, 12, (3, 7, 7, 7, 7))
725
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000726 # A 31-day december starting on friday (2+7+7+7+7+1 days)
Walter Dörwald302fa6d2004-07-08 17:14:17 +0000727 self.check_weeks(1995, 12, (2, 7, 7, 7, 7, 1))
728
Alexander Belopolsky43ca7102010-06-14 17:32:03 +0000729class TimegmTestCase(unittest.TestCase):
730 TIMESTAMPS = [0, 10, 100, 1000, 10000, 100000, 1000000,
731 1234567890, 1262304000, 1275785153,]
732 def test_timegm(self):
733 for secs in self.TIMESTAMPS:
734 tuple = time.gmtime(secs)
735 self.assertEqual(secs, calendar.timegm(tuple))
Walter Dörwald302fa6d2004-07-08 17:14:17 +0000736
Brett Cannoncfae36f2010-07-23 13:54:14 +0000737class MonthRangeTestCase(unittest.TestCase):
738 def test_january(self):
739 # Tests valid lower boundary case.
740 self.assertEqual(calendar.monthrange(2004,1), (3,31))
741
742 def test_february_leap(self):
743 # Tests February during leap year.
744 self.assertEqual(calendar.monthrange(2004,2), (6,29))
745
746 def test_february_nonleap(self):
747 # Tests February in non-leap year.
748 self.assertEqual(calendar.monthrange(2010,2), (0,28))
749
750 def test_december(self):
751 # Tests valid upper boundary case.
752 self.assertEqual(calendar.monthrange(2004,12), (2,31))
753
754 def test_zeroth_month(self):
755 # Tests low invalid boundary case.
756 with self.assertRaises(calendar.IllegalMonthError):
757 calendar.monthrange(2004, 0)
758
759 def test_thirteenth_month(self):
760 # Tests high invalid boundary case.
761 with self.assertRaises(calendar.IllegalMonthError):
762 calendar.monthrange(2004, 13)
763
R David Murrayd0c86952012-05-29 12:55:05 -0400764 def test_illegal_month_reported(self):
765 with self.assertRaisesRegex(calendar.IllegalMonthError, '65'):
766 calendar.monthrange(2004, 65)
767
R. David Murray1daaf9e2010-12-31 19:21:14 +0000768class LeapdaysTestCase(unittest.TestCase):
769 def test_no_range(self):
770 # test when no range i.e. two identical years as args
771 self.assertEqual(calendar.leapdays(2010,2010), 0)
772
773 def test_no_leapdays(self):
774 # test when no leap years in range
775 self.assertEqual(calendar.leapdays(2010,2011), 0)
776
777 def test_no_leapdays_upper_boundary(self):
778 # test no leap years in range, when upper boundary is a leap year
779 self.assertEqual(calendar.leapdays(2010,2012), 0)
780
781 def test_one_leapday_lower_boundary(self):
782 # test when one leap year in range, lower boundary is leap year
783 self.assertEqual(calendar.leapdays(2012,2013), 1)
784
785 def test_several_leapyears_in_range(self):
786 self.assertEqual(calendar.leapdays(1997,2020), 5)
787
Brett Cannoncfae36f2010-07-23 13:54:14 +0000788
Serhiy Storchakaaef859c2015-02-05 15:14:35 +0200789def conv(s):
790 return s.replace('\n', os.linesep).encode()
Senthil Kumaran962fed92011-08-11 09:22:52 +0800791
Serhiy Storchakaaef859c2015-02-05 15:14:35 +0200792class CommandLineTestCase(unittest.TestCase):
793 def run_ok(self, *args):
794 return assert_python_ok('-m', 'calendar', *args)[1]
795
796 def assertFailure(self, *args):
797 rc, stdout, stderr = assert_python_failure('-m', 'calendar', *args)
Serhiy Storchaka97852612015-11-01 17:14:27 +0200798 self.assertIn(b'usage:', stderr)
Serhiy Storchakaaef859c2015-02-05 15:14:35 +0200799 self.assertEqual(rc, 2)
800
801 def test_help(self):
802 stdout = self.run_ok('-h')
Serhiy Storchaka97852612015-11-01 17:14:27 +0200803 self.assertIn(b'usage:', stdout)
Serhiy Storchakaaef859c2015-02-05 15:14:35 +0200804 self.assertIn(b'calendar.py', stdout)
805 self.assertIn(b'--help', stdout)
806
807 def test_illegal_arguments(self):
808 self.assertFailure('-z')
Serhiy Storchaka97852612015-11-01 17:14:27 +0200809 self.assertFailure('spam')
810 self.assertFailure('2004', 'spam')
Serhiy Storchakaaef859c2015-02-05 15:14:35 +0200811 self.assertFailure('-t', 'html', '2004', '1')
812
813 def test_output_current_year(self):
814 stdout = self.run_ok()
815 year = datetime.datetime.now().year
816 self.assertIn((' %s' % year).encode(), stdout)
817 self.assertIn(b'January', stdout)
818 self.assertIn(b'Mo Tu We Th Fr Sa Su', stdout)
819
820 def test_output_year(self):
821 stdout = self.run_ok('2004')
822 self.assertEqual(stdout, conv(result_2004_text))
823
824 def test_output_month(self):
825 stdout = self.run_ok('2004', '1')
826 self.assertEqual(stdout, conv(result_2004_01_text))
827
828 def test_option_encoding(self):
829 self.assertFailure('-e')
830 self.assertFailure('--encoding')
831 stdout = self.run_ok('--encoding', 'utf-16-le', '2004')
832 self.assertEqual(stdout, result_2004_text.encode('utf-16-le'))
833
834 def test_option_locale(self):
835 self.assertFailure('-L')
836 self.assertFailure('--locale')
837 self.assertFailure('-L', 'en')
838 lang, enc = locale.getdefaultlocale()
839 lang = lang or 'C'
840 enc = enc or 'UTF-8'
841 try:
842 oldlocale = locale.getlocale(locale.LC_TIME)
843 try:
844 locale.setlocale(locale.LC_TIME, (lang, enc))
845 finally:
846 locale.setlocale(locale.LC_TIME, oldlocale)
847 except (locale.Error, ValueError):
848 self.skipTest('cannot set the system default locale')
849 stdout = self.run_ok('--locale', lang, '--encoding', enc, '2004')
850 self.assertIn('2004'.encode(enc), stdout)
851
852 def test_option_width(self):
853 self.assertFailure('-w')
854 self.assertFailure('--width')
855 self.assertFailure('-w', 'spam')
856 stdout = self.run_ok('--width', '3', '2004')
857 self.assertIn(b'Mon Tue Wed Thu Fri Sat Sun', stdout)
858
859 def test_option_lines(self):
860 self.assertFailure('-l')
861 self.assertFailure('--lines')
862 self.assertFailure('-l', 'spam')
863 stdout = self.run_ok('--lines', '2', '2004')
864 self.assertIn(conv('December\n\nMo Tu We'), stdout)
865
866 def test_option_spacing(self):
867 self.assertFailure('-s')
868 self.assertFailure('--spacing')
869 self.assertFailure('-s', 'spam')
870 stdout = self.run_ok('--spacing', '8', '2004')
871 self.assertIn(b'Su Mo', stdout)
872
873 def test_option_months(self):
874 self.assertFailure('-m')
875 self.assertFailure('--month')
876 self.assertFailure('-m', 'spam')
877 stdout = self.run_ok('--months', '1', '2004')
878 self.assertIn(conv('\nMo Tu We Th Fr Sa Su\n'), stdout)
879
880 def test_option_type(self):
881 self.assertFailure('-t')
882 self.assertFailure('--type')
883 self.assertFailure('-t', 'spam')
884 stdout = self.run_ok('--type', 'text', '2004')
885 self.assertEqual(stdout, conv(result_2004_text))
886 stdout = self.run_ok('--type', 'html', '2004')
887 self.assertEqual(stdout[:6], b'<?xml ')
888 self.assertIn(b'<title>Calendar for 2004</title>', stdout)
889
890 def test_html_output_current_year(self):
891 stdout = self.run_ok('--type', 'html')
892 year = datetime.datetime.now().year
893 self.assertIn(('<title>Calendar for %s</title>' % year).encode(),
894 stdout)
895 self.assertIn(b'<tr><th colspan="7" class="month">January</th></tr>',
896 stdout)
897
898 def test_html_output_year_encoding(self):
899 stdout = self.run_ok('-t', 'html', '--encoding', 'ascii', '2004')
900 self.assertEqual(stdout,
Oz N Tiram8b7a4cc2017-06-06 11:35:59 +0200901 result_2004_html.format(**default_format).encode('ascii'))
Serhiy Storchakaaef859c2015-02-05 15:14:35 +0200902
903 def test_html_output_year_css(self):
904 self.assertFailure('-t', 'html', '-c')
905 self.assertFailure('-t', 'html', '--css')
906 stdout = self.run_ok('-t', 'html', '--css', 'custom.css', '2004')
907 self.assertIn(b'<link rel="stylesheet" type="text/css" '
908 b'href="custom.css" />', stdout)
Walter Dörwald59ad4562004-07-02 19:00:09 +0000909
Fred Draked077ca12001-12-12 05:38:08 +0000910
Martin Panter4eb376c2016-01-16 06:49:30 +0000911class MiscTestCase(unittest.TestCase):
912 def test__all__(self):
Serhiy Storchaka2c1d3e32016-01-16 11:05:11 +0200913 blacklist = {'mdays', 'January', 'February', 'EPOCH',
Martin Panter4eb376c2016-01-16 06:49:30 +0000914 'MONDAY', 'TUESDAY', 'WEDNESDAY', 'THURSDAY', 'FRIDAY',
915 'SATURDAY', 'SUNDAY', 'different_locale', 'c',
Alexander Belopolskyfdd9b212017-10-24 13:17:10 -0400916 'prweek', 'week', 'format', 'formatstring', 'main',
917 'monthlen', 'prevmonth', 'nextmonth'}
Martin Panter4eb376c2016-01-16 06:49:30 +0000918 support.check__all__(self, calendar, blacklist=blacklist)
919
920
Oz N Tiram8b7a4cc2017-06-06 11:35:59 +0200921class TestSubClassingCase(unittest.TestCase):
922
923 def setUp(self):
924
925 class CustomHTMLCal(calendar.HTMLCalendar):
926 cssclasses = [style + " text-nowrap" for style in
927 calendar.HTMLCalendar.cssclasses]
928 cssclasses_weekday_head = ["red", "blue", "green", "lilac",
929 "yellow", "orange", "pink"]
930 cssclass_month_head = "text-center month-head"
931 cssclass_month = "text-center month"
932 cssclass_year = "text-italic "
933 cssclass_year_head = "lead "
934
935 self.cal = CustomHTMLCal()
936
937 def test_formatmonthname(self):
938 self.assertIn('class="text-center month-head"',
939 self.cal.formatmonthname(2017, 5))
940
941 def test_formatmonth(self):
942 self.assertIn('class="text-center month"',
943 self.cal.formatmonth(2017, 5))
944
945 def test_formatweek(self):
946 weeks = self.cal.monthdays2calendar(2017, 5)
947 self.assertIn('class="wed text-nowrap"', self.cal.formatweek(weeks[0]))
948
949 def test_formatweek_head(self):
950 header = self.cal.formatweekheader()
951 for color in self.cal.cssclasses_weekday_head:
952 self.assertIn('<th class="%s">' % color, header)
953
954 def test_format_year(self):
955 self.assertIn(
956 ('<table border="0" cellpadding="0" cellspacing="0" class="%s">' %
957 self.cal.cssclass_year), self.cal.formatyear(2017))
958
959 def test_format_year_head(self):
960 self.assertIn('<tr><th colspan="%d" class="%s">%s</th></tr>' % (
961 3, self.cal.cssclass_year_head, 2017), self.cal.formatyear(2017))
962
Fred Draked077ca12001-12-12 05:38:08 +0000963if __name__ == "__main__":
Serhiy Storchakaaef859c2015-02-05 15:14:35 +0200964 unittest.main()