Skip to content

Commit b494310

Browse files
Python 3 (#24)
Python 3 compatibility and more tests
1 parent c575c5f commit b494310

File tree

5 files changed

+102
-3
lines changed

5 files changed

+102
-3
lines changed

.travis.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,17 @@ sudo: false
33
python:
44
- '2.6'
55
- '2.7'
6+
- '3.3'
7+
- '3.4'
8+
- '3.5'
69
env:
710
- secure: PEOM40L5TK78GFQyt2I2PgOFf8QYGcP0YZmgMhacuKnCI0Lr3wztXucWtxeVpXeuDDe12d349FumQrg6ard8T69ZZYe25eJ5lR9ZMyVOzFJ9Ew3XhoEgWBgKFRNjEkhFU+/reYWRBkYHyFImLe9d8wq1I2UMQ6z2189PLKfBtIg=
811
install:
912
- pip install .
1013
- pip install -r requirements.txt
1114
script:
1215
- nosetests -w tests/unit
13-
- nosetests -w tests/integration
16+
- if [[ "$API_KEY" != "" ]]; then nosetests -w tests/integration; fi
1417
deploy:
1518
provider: pypi
1619
user: jacob.tomlinson

datapoint/Manager.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
from datetime import datetime
66
from datetime import timedelta
7+
import sys
78
from time import time
89
import pytz
910

@@ -15,8 +16,12 @@
1516
from .Timestep import Timestep
1617
from .Element import Element
1718

19+
if (sys.version_info > (3, 0)):
20+
long = int
21+
1822
API_URL = "http://datapoint.metoffice.gov.uk/public/data/val/wxfcs/all/json"
1923
DATE_FORMAT = "%Y-%m-%dZ"
24+
DATA_DATE_FORMAT = "%Y-%m-%dT%XZ"
2025
FORECAST_DATE_FORMAT = "%Y-%m-%dT%H:%M:%SZ"
2126
ELEMENTS = {
2227
"Day":
@@ -201,7 +206,8 @@ def get_forecast_for_site(self, site_id, frequency="daily"):
201206
params = data['SiteRep']['Wx']['Param']
202207

203208
forecast = Forecast()
204-
forecast.data_date = datetime.strptime(data['SiteRep']['DV']['dataDate'], FORECAST_DATE_FORMAT).replace(tzinfo=pytz.UTC)
209+
forecast.data_date = data['SiteRep']['DV']['dataDate']
210+
forecast.data_date = datetime.strptime(data['SiteRep']['DV']['dataDate'], DATA_DATE_FORMAT).replace(tzinfo=pytz.UTC)
205211
forecast.continent = data['SiteRep']['DV']['Location']['continent']
206212
forecast.country = data['SiteRep']['DV']['Location']['country']
207213
forecast.name = data['SiteRep']['DV']['Location']['name']

setup.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,5 +65,6 @@
6565
'Development Status :: 3 - Alpha',
6666
'Programming Language :: Python :: 2.6',
6767
'Programming Language :: Python :: 2.7',
68+
'Programming Language :: Python :: 3.4',
6869
]
6970
)

tests/integration/manager_test.py

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import datetime
12
import os
23
from types import *
34
from nose.tools import *
@@ -13,3 +14,91 @@ def test_site(self):
1314
site = self.manager.get_nearest_site(-0.124626, 51.500728)
1415
assert site.name == 'London'
1516

17+
def test_get_all_sites(self):
18+
sites = self.manager.get_all_sites()
19+
assert isinstance(sites, list)
20+
assert sites
21+
22+
def test_get_daily_forecast(self):
23+
site = self.manager.get_nearest_site(-0.124626, 51.500728)
24+
forecast = self.manager.get_forecast_for_site(site.id, 'daily')
25+
assert isinstance(forecast, datapoint.Forecast.Forecast)
26+
assert forecast.continent.upper() == 'EUROPE'
27+
assert forecast.country.upper() == 'ENGLAND'
28+
assert forecast.name.upper() == 'LONDON'
29+
assert abs(float(forecast.longitude) - (-0.124626)) < 0.1
30+
assert abs(float(forecast.latitude) - 51.500728) < 0.1
31+
# Forecast should have been made within last 3 hours
32+
tz = forecast.data_date.tzinfo
33+
assert (forecast.data_date
34+
- datetime.datetime.now(tz=tz) < datetime.timedelta(hours=3))
35+
# First forecast should be less than 12 hours away
36+
tz = forecast.days[0].timesteps[0].date.tzinfo
37+
assert (forecast.days[0].timesteps[0].date -
38+
datetime.datetime.now(tz=tz) < datetime.timedelta(hours=12))
39+
for day in forecast.days:
40+
for timestep in day.timesteps:
41+
assert timestep.name in ['Day', 'Night']
42+
assert self.manager._weather_to_text(
43+
int(timestep.weather.value)) == timestep.weather.text
44+
assert -100 < timestep.temperature.value < 100
45+
assert timestep.temperature.units == 'C'
46+
assert -100 < timestep.feels_like_temperature.value < 100
47+
assert timestep.feels_like_temperature.units == 'C'
48+
assert 0 <= timestep.wind_speed.value < 300
49+
assert timestep.wind_speed.units == 'mph'
50+
for char in timestep.wind_direction.value:
51+
assert char in ['N', 'E', 'S', 'W']
52+
assert timestep.wind_direction.units == 'compass'
53+
assert 0 <= timestep.wind_gust.value < 300
54+
assert timestep.wind_gust.units == 'mph'
55+
assert (timestep.visibility.value in
56+
['UN', 'VP', 'PO', 'MO', 'GO', 'VG', 'EX'])
57+
assert 0 <= timestep.precipitation.value <= 100
58+
assert timestep.precipitation.units == '%'
59+
assert 0 <= timestep.humidity.value <= 100
60+
assert timestep.humidity.units == '%'
61+
if hasattr(timestep.uv, 'value'):
62+
assert 0 < int(timestep.uv.value) < 20
63+
64+
def test_get_3hour_forecast(self):
65+
site = self.manager.get_nearest_site(-0.124626, 51.500728)
66+
forecast = self.manager.get_forecast_for_site(site.id, '3hourly')
67+
assert isinstance(forecast, datapoint.Forecast.Forecast)
68+
assert forecast.continent.upper() == 'EUROPE'
69+
assert forecast.country.upper() == 'ENGLAND'
70+
assert forecast.name.upper() == 'LONDON'
71+
assert abs(float(forecast.longitude) - (-0.124626)) < 0.1
72+
assert abs(float(forecast.latitude) - 51.500728) < 0.1
73+
# Forecast should have been made within last 3 hours
74+
tz = forecast.data_date.tzinfo
75+
assert (forecast.data_date
76+
- datetime.datetime.now(tz=tz) < datetime.timedelta(hours=3))
77+
# First forecast should be less than 12 hours away
78+
tz = forecast.days[0].timesteps[0].date.tzinfo
79+
assert (forecast.days[0].timesteps[0].date -
80+
datetime.datetime.now(tz=tz) < datetime.timedelta(hours=3))
81+
for day in forecast.days:
82+
for timestep in day.timesteps:
83+
assert isinstance(timestep.name, int)
84+
assert self.manager._weather_to_text(
85+
int(timestep.weather.value)) == timestep.weather.text
86+
assert -100 < timestep.temperature.value < 100
87+
assert timestep.temperature.units == 'C'
88+
assert -100 < timestep.feels_like_temperature.value < 100
89+
assert timestep.feels_like_temperature.units == 'C'
90+
assert 0 <= timestep.wind_speed.value < 300
91+
assert timestep.wind_speed.units == 'mph'
92+
for char in timestep.wind_direction.value:
93+
assert char in ['N', 'E', 'S', 'W']
94+
assert timestep.wind_direction.units == 'compass'
95+
assert 0 <= timestep.wind_gust.value < 300
96+
assert timestep.wind_gust.units == 'mph'
97+
assert (timestep.visibility.value in
98+
['UN', 'VP', 'PO', 'MO', 'GO', 'VG', 'EX'])
99+
assert 0 <= timestep.precipitation.value <= 100
100+
assert timestep.precipitation.units == '%'
101+
assert 0 <= timestep.humidity.value <= 100
102+
assert timestep.humidity.units == '%'
103+
if hasattr(timestep.uv, 'value'):
104+
assert 0 <= int(timestep.uv.value) < 20

tests/unit/manager_test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ def __init__(self):
1010

1111
def test_weather_to_text_is_string(self):
1212
weather_text = self.manager._weather_to_text(0)
13-
assert type(weather_text) is StringType
13+
assert isinstance(weather_text, type(""))
1414

1515
@raises(ValueError)
1616
def test_weather_to_text_invalid_input_None(self):

0 commit comments

Comments
 (0)