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