Merge lp:~rockstar/entertainer/fix-weather-tests-again into lp:entertainer

Proposed by Paul Hummer
Status: Merged
Approved by: Matt Layman
Approved revision: 370
Merged at revision: not available
Proposed branch: lp:~rockstar/entertainer/fix-weather-tests-again
Merge into: lp:entertainer
Diff against target: None lines
To merge this branch: bzr merge lp:~rockstar/entertainer/fix-weather-tests-again
Reviewer Review Type Date Requested Status
Matt Layman Approve
Review via email: mp+6241@code.launchpad.net

Commit message

The weather tests are no longer fragile to what time of day it is, or what timezone it is.

To post a comment you must log in.
Revision history for this message
Paul Hummer (rockstar) wrote :

This branch looks a lot more heavy than it really is. For us that don't live in England, there are windows of time where one of the weather tests doesn't pass. This is because my datetime.now() is a different day than what day Google knows it is in Bath, England.

Initially, I thought datetime.utcnow() would be fine, since UTC 0 is England, but that still doesn't work, because utcnow() doesn't compensate for DST. The solution in this branch implements a tzinfo object specific to England, which I could then pass to datetime.now to specify a timezone which understands DST.

This will make the tests pass no matter what time it is in your local timezone, and no matter whether or not it's DST.

Revision history for this message
Matt Layman (mblayman) wrote :

Conceptually, I understand what you're doing. I'll confess I don't understand all the actual code, but I'll assume that you took the time to do proper research into subclassing tzinfo. The proof is in the pudding: the test passes now (I'm currently in a time of day where it would fail).

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'entertainerlib/tests/test_weather.py'
2--- entertainerlib/tests/test_weather.py 2009-02-10 00:59:03 +0000
3+++ entertainerlib/tests/test_weather.py 2009-05-06 01:59:02 +0000
4@@ -4,7 +4,7 @@
5 __copyright__ = "2008, Jamie Bennett"
6 __author__ = "Jamie Bennett <jamie@linuxuk.org>"
7
8-from datetime import datetime
9+from datetime import datetime, timedelta, tzinfo
10
11 from entertainerlib.tests import EntertainerTest
12 from entertainerlib.utils.weather import Weather
13@@ -27,11 +27,62 @@
14
15 def testWeatherFindRemote(self):
16 """Tests the weather code using a call to the outside world"""
17+ class EnglandTimeZone(tzinfo):
18+ '''An implementation of tzinfo specific to England.'''
19+ def __init__(self):
20+ tzinfo.__init__(self)
21+ self.stdoffset = timedelta(hours=0)
22+ self.reprname = 'England'
23+ self.stdname = 'WET' # Western Europe Time
24+ self.dstname = 'BST' # British Summer Time
25+
26+ def __repr__(self):
27+ return self.reprname
28+
29+ def _first_sunday_on_or_after(self, dt):
30+ '''Figure out the DST date.'''
31+ days_to_go = 6 - dt.weekday()
32+ if days_to_go:
33+ dt += timedelta(days_to_go)
34+ return dt
35+
36+ def tzname(self, dt):
37+ '''See `tzinfo.tzname`.'''
38+ if self.dst(dt):
39+ return self.dstname
40+ else:
41+ return self.stdname
42+
43+ def utcoffset(self, dt):
44+ '''See `tzinfo.utcoffset`.'''
45+ return self.stdoffset + self.dst(dt)
46+
47+ def dst(self, dt):
48+ '''See `tzinfo.dst`.'''
49+ DSTSTART = datetime(1, 4, 1, 2)
50+ DSTEND = datetime(1, 10, 25, 1)
51+ ZERO = timedelta(0)
52+ HOUR = timedelta(hours=1)
53+ if dt is None or dt.tzinfo is None:
54+ return ZERO
55+ assert dt.tzinfo is self
56+
57+ start = self._first_sunday_on_or_after(
58+ DSTSTART.replace(year=dt.year))
59+ end = self._first_sunday_on_or_after(
60+ DSTEND.replace(year=dt.year))
61+
62+ if start <= dt.replace(tzinfo=None) < end:
63+ return HOUR
64+ else:
65+ return ZERO
66+ england = EnglandTimeZone()
67+
68 self.weather.set_location('Bath,England')
69 self.weather.refresh()
70 forecasts = self.weather.get_forecasts()
71 today = forecasts[0]
72- day = datetime.now().strftime('%a')
73+ day = datetime.now(england).strftime('%a')
74 self.assertEqual(str(today["Day"]), day)
75
76 def testWeatherSet(self):

Subscribers

People subscribed via source and target branches