noaa_weather_client 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.rspec +1 -0
  4. data/.ruby-gemset +1 -0
  5. data/.ruby-version +1 -0
  6. data/.travis.yml +7 -0
  7. data/.yardopts +2 -0
  8. data/Gemfile +8 -0
  9. data/LICENSE.txt +22 -0
  10. data/README.md +107 -0
  11. data/Rakefile +8 -0
  12. data/bin/noaa_weather_client +43 -0
  13. data/data/xml/current_observation.xsd +79 -0
  14. data/data/xml/dwml.xsd +97 -0
  15. data/data/xml/location.xsd +142 -0
  16. data/data/xml/meta_data.xsd +100 -0
  17. data/data/xml/moreWeatherInformation.xsd +23 -0
  18. data/data/xml/ndfd_data.xsd +43 -0
  19. data/data/xml/parameters.xsd +1173 -0
  20. data/data/xml/summarizationType.xsd +29 -0
  21. data/data/xml/time_layout.xsd +51 -0
  22. data/lib/noaa_weather_client.rb +9 -0
  23. data/lib/noaa_weather_client/cli.rb +53 -0
  24. data/lib/noaa_weather_client/cli/templates.rb +53 -0
  25. data/lib/noaa_weather_client/client.rb +61 -0
  26. data/lib/noaa_weather_client/errors.rb +7 -0
  27. data/lib/noaa_weather_client/responses/current_observation.rb +93 -0
  28. data/lib/noaa_weather_client/responses/forecast.rb +84 -0
  29. data/lib/noaa_weather_client/responses/generic_response.rb +9 -0
  30. data/lib/noaa_weather_client/responses/lat_lon_list.rb +25 -0
  31. data/lib/noaa_weather_client/responses/reactive_xml_response.rb +29 -0
  32. data/lib/noaa_weather_client/responses/station.rb +28 -0
  33. data/lib/noaa_weather_client/responses/stations.rb +41 -0
  34. data/lib/noaa_weather_client/responses/validatable_xml_response.rb +22 -0
  35. data/lib/noaa_weather_client/rest_client_factory.rb +12 -0
  36. data/lib/noaa_weather_client/services/calculate_distance_between_lat_lon.rb +20 -0
  37. data/lib/noaa_weather_client/services/current_observations.rb +32 -0
  38. data/lib/noaa_weather_client/services/find_nearest_station.rb +16 -0
  39. data/lib/noaa_weather_client/services/forecast_by_day.rb +52 -0
  40. data/lib/noaa_weather_client/services/postal_code_to_coordinate.rb +36 -0
  41. data/lib/noaa_weather_client/services/rest_service.rb +28 -0
  42. data/lib/noaa_weather_client/services/soap_service.rb +16 -0
  43. data/lib/noaa_weather_client/services/weather_stations.rb +32 -0
  44. data/lib/noaa_weather_client/soap_client_factory.rb +17 -0
  45. data/lib/noaa_weather_client/station_filters.rb +8 -0
  46. data/lib/noaa_weather_client/version.rb +3 -0
  47. data/lib/noaa_weather_client/xml_parser_factory.rb +9 -0
  48. data/noaa_weather_client.gemspec +27 -0
  49. data/spec/fixtures/vcr_cassettes/current_observations.yml +25890 -0
  50. data/spec/fixtures/vcr_cassettes/forecast_by_day_3.yml +772 -0
  51. data/spec/fixtures/vcr_cassettes/forecast_by_day_7.yml +829 -0
  52. data/spec/fixtures/vcr_cassettes/nearest_weather_station.yml +25842 -0
  53. data/spec/fixtures/vcr_cassettes/postal_code_to_coordinate.yml +75 -0
  54. data/spec/fixtures/vcr_cassettes/weather_stations.yml +25842 -0
  55. data/spec/fixtures/xml/forecast.xml +144 -0
  56. data/spec/lib/noaa_client/client_spec.rb +93 -0
  57. data/spec/lib/noaa_client/responses/current_observation_spec.rb +122 -0
  58. data/spec/lib/noaa_client/responses/forecast_spec.rb +66 -0
  59. data/spec/lib/noaa_client/responses/lat_lon_list_spec.rb +30 -0
  60. data/spec/lib/noaa_client/responses/station_spec.rb +53 -0
  61. data/spec/lib/noaa_client/responses/stations_spec.rb +86 -0
  62. data/spec/lib/noaa_client/rest_client_factory_spec.rb +15 -0
  63. data/spec/lib/noaa_client/services/calculate_distance_between_lat_lon_spec.rb +16 -0
  64. data/spec/lib/noaa_client/services/current_observations_spec.rb +47 -0
  65. data/spec/lib/noaa_client/services/find_nearest_station_spec.rb +36 -0
  66. data/spec/lib/noaa_client/services/forecast_by_day_spec.rb +62 -0
  67. data/spec/lib/noaa_client/services/postal_code_to_coordinate_spec.rb +41 -0
  68. data/spec/lib/noaa_client/services/rest_service_spec.rb +45 -0
  69. data/spec/lib/noaa_client/services/soap_service_spec.rb +56 -0
  70. data/spec/lib/noaa_client/services/weather_stations_spec.rb +40 -0
  71. data/spec/lib/noaa_client/soap_client_factory_spec.rb +13 -0
  72. data/spec/lib/noaa_client/xml_parser_factory_spec.rb +14 -0
  73. data/spec/spec_helper.rb +31 -0
  74. metadata +228 -0
@@ -0,0 +1,144 @@
1
+ <?xml version="1.0"?>
2
+ <dwml version="1.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://graphical.weather.gov/xml/DWMLgen/schema/DWML.xsd">
3
+ <head>
4
+ <product srsName="WGS 1984" concise-name="dwmlByDay" operational-mode="official">
5
+ <title>NOAA's National Weather Service Forecast by 24 Hour Period</title>
6
+ <field>meteorological</field>
7
+ <category>forecast</category>
8
+ <creation-date refresh-frequency="PT1H">2013-08-12T03:47:26Z</creation-date>
9
+ </product>
10
+ <source>
11
+ <more-information>http://graphical.weather.gov/xml/</more-information>
12
+ <production-center>Meteorological Development Laboratory<sub-center>Product Generation Branch</sub-center></production-center>
13
+ <disclaimer>http://www.nws.noaa.gov/disclaimer.html</disclaimer>
14
+ <credit>http://www.weather.gov/</credit>
15
+ <credit-logo>http://www.weather.gov/images/xml_logo.gif</credit-logo>
16
+ <feedback>http://www.weather.gov/feedback.php</feedback>
17
+ </source>
18
+ </head>
19
+ <data>
20
+ <location>
21
+ <location-key>point1</location-key>
22
+ <point latitude="37.20" longitude="-93.29"/>
23
+ </location>
24
+ <moreWeatherInformation applicable-location="point1">http://forecast.weather.gov/MapClick.php?textField1=37.20&amp;textField2=-93.29</moreWeatherInformation>
25
+ <time-layout time-coordinate="local" summarization="24hourly">
26
+ <layout-key>k-p24h-n7-1</layout-key>
27
+ <start-valid-time period-name="Today">2013-08-12T06:00:00-05:00</start-valid-time>
28
+ <end-valid-time>2013-08-13T06:00:00-05:00</end-valid-time>
29
+ <start-valid-time period-name="Tomorrow">2013-08-13T06:00:00-05:00</start-valid-time>
30
+ <end-valid-time>2013-08-14T06:00:00-05:00</end-valid-time>
31
+ <start-valid-time period-name="Monday">2013-08-14T06:00:00-05:00</start-valid-time>
32
+ <end-valid-time>2013-08-15T06:00:00-05:00</end-valid-time>
33
+ <start-valid-time period-name="Tuesday">2013-08-15T06:00:00-05:00</start-valid-time>
34
+ <end-valid-time>2013-08-16T06:00:00-05:00</end-valid-time>
35
+ <start-valid-time period-name="Wednesday">2013-08-16T06:00:00-05:00</start-valid-time>
36
+ <end-valid-time>2013-08-17T06:00:00-05:00</end-valid-time>
37
+ <start-valid-time period-name="Thursday">2013-08-17T06:00:00-05:00</start-valid-time>
38
+ <end-valid-time>2013-08-18T06:00:00-05:00</end-valid-time>
39
+ <start-valid-time period-name="Friday">2013-08-18T06:00:00-05:00</start-valid-time>
40
+ <end-valid-time>2013-08-19T06:00:00-05:00</end-valid-time>
41
+ </time-layout>
42
+ <time-layout time-coordinate="local" summarization="12hourly">
43
+ <layout-key>k-p12h-n14-2</layout-key>
44
+ <start-valid-time>2013-08-12T06:00:00-05:00</start-valid-time>
45
+ <end-valid-time>2013-08-12T18:00:00-05:00</end-valid-time>
46
+ <start-valid-time>2013-08-12T18:00:00-05:00</start-valid-time>
47
+ <end-valid-time>2013-08-13T06:00:00-05:00</end-valid-time>
48
+ <start-valid-time>2013-08-13T06:00:00-05:00</start-valid-time>
49
+ <end-valid-time>2013-08-13T18:00:00-05:00</end-valid-time>
50
+ <start-valid-time>2013-08-13T18:00:00-05:00</start-valid-time>
51
+ <end-valid-time>2013-08-14T06:00:00-05:00</end-valid-time>
52
+ <start-valid-time>2013-08-14T06:00:00-05:00</start-valid-time>
53
+ <end-valid-time>2013-08-14T18:00:00-05:00</end-valid-time>
54
+ <start-valid-time>2013-08-14T18:00:00-05:00</start-valid-time>
55
+ <end-valid-time>2013-08-15T06:00:00-05:00</end-valid-time>
56
+ <start-valid-time>2013-08-15T06:00:00-05:00</start-valid-time>
57
+ <end-valid-time>2013-08-15T18:00:00-05:00</end-valid-time>
58
+ <start-valid-time>2013-08-15T18:00:00-05:00</start-valid-time>
59
+ <end-valid-time>2013-08-16T06:00:00-05:00</end-valid-time>
60
+ <start-valid-time>2013-08-16T06:00:00-05:00</start-valid-time>
61
+ <end-valid-time>2013-08-16T18:00:00-05:00</end-valid-time>
62
+ <start-valid-time>2013-08-16T18:00:00-05:00</start-valid-time>
63
+ <end-valid-time>2013-08-17T06:00:00-05:00</end-valid-time>
64
+ <start-valid-time>2013-08-17T06:00:00-05:00</start-valid-time>
65
+ <end-valid-time>2013-08-17T18:00:00-05:00</end-valid-time>
66
+ <start-valid-time>2013-08-17T18:00:00-05:00</start-valid-time>
67
+ <end-valid-time>2013-08-18T06:00:00-05:00</end-valid-time>
68
+ <start-valid-time>2013-08-18T06:00:00-05:00</start-valid-time>
69
+ <end-valid-time>2013-08-18T18:00:00-05:00</end-valid-time>
70
+ <start-valid-time>2013-08-18T18:00:00-05:00</start-valid-time>
71
+ <end-valid-time>2013-08-19T06:00:00-05:00</end-valid-time>
72
+ </time-layout>
73
+ <time-layout time-coordinate="local" summarization="24hourly">
74
+ <layout-key>k-p7d-n1-3</layout-key>
75
+ <start-valid-time>2013-08-12T06:00:00-05:00</start-valid-time>
76
+ <end-valid-time>2013-08-19T06:00:00-05:00</end-valid-time>
77
+ </time-layout>
78
+ <parameters applicable-location="point1">
79
+ <temperature type="maximum" units="Fahrenheit" time-layout="k-p24h-n7-1">
80
+ <name>Daily Maximum Temperature</name>
81
+ <value>86</value>
82
+ <value>81</value>
83
+ <value>78</value>
84
+ <value>77</value>
85
+ <value>78</value>
86
+ <value>81</value>
87
+ <value>83</value>
88
+ </temperature>
89
+ <temperature type="minimum" units="Fahrenheit" time-layout="k-p24h-n7-1">
90
+ <name>Daily Minimum Temperature</name>
91
+ <value>69</value>
92
+ <value>65</value>
93
+ <value>57</value>
94
+ <value>57</value>
95
+ <value>59</value>
96
+ <value>61</value>
97
+ <value xsi:nil="true"/>
98
+ </temperature>
99
+ <probability-of-precipitation type="12 hour" units="percent" time-layout="k-p12h-n14-2">
100
+ <name>12 Hourly Probability of Precipitation</name>
101
+ <value>46</value>
102
+ <value>46</value>
103
+ <value>54</value>
104
+ <value>32</value>
105
+ <value>12</value>
106
+ <value>4</value>
107
+ <value>6</value>
108
+ <value>6</value>
109
+ <value>7</value>
110
+ <value>5</value>
111
+ <value>4</value>
112
+ <value>5</value>
113
+ <value>5</value>
114
+ <value xsi:nil="true"/>
115
+ </probability-of-precipitation>
116
+ <weather time-layout="k-p24h-n7-1">
117
+ <name>Weather Type, Coverage, and Intensity</name>
118
+ <weather-conditions weather-summary="Chance Thunderstorms">
119
+ <value coverage="chance" intensity="none" weather-type="thunderstorms" qualifier="none"/>
120
+ <value coverage="chance" intensity="light" additive="and" weather-type="rain showers" qualifier="none"/>
121
+ </weather-conditions>
122
+ <weather-conditions weather-summary="Chance Thunderstorms">
123
+ <value coverage="chance" intensity="none" weather-type="thunderstorms" qualifier="none"/>
124
+ <value coverage="chance" intensity="light" additive="and" weather-type="rain showers" qualifier="none"/>
125
+ </weather-conditions>
126
+ <weather-conditions weather-summary="Partly Sunny"/>
127
+ <weather-conditions weather-summary="Partly Sunny"/>
128
+ <weather-conditions weather-summary="Mostly Sunny"/>
129
+ <weather-conditions weather-summary="Mostly Sunny"/>
130
+ <weather-conditions weather-summary="Mostly Sunny"/>
131
+ </weather>
132
+ <conditions-icon type="forecast-NWS" time-layout="k-p24h-n7-1">
133
+ <name>Conditions Icons</name>
134
+ <icon-link>http://www.nws.noaa.gov/weather/images/fcicons/tsra50.jpg</icon-link>
135
+ <icon-link>http://www.nws.noaa.gov/weather/images/fcicons/tsra50.jpg</icon-link>
136
+ <icon-link>http://www.nws.noaa.gov/weather/images/fcicons/sct.jpg</icon-link>
137
+ <icon-link>http://www.nws.noaa.gov/weather/images/fcicons/sct.jpg</icon-link>
138
+ <icon-link>http://www.nws.noaa.gov/weather/images/fcicons/few.jpg</icon-link>
139
+ <icon-link>http://www.nws.noaa.gov/weather/images/fcicons/few.jpg</icon-link>
140
+ <icon-link>http://www.nws.noaa.gov/weather/images/fcicons/few.jpg</icon-link>
141
+ </conditions-icon>
142
+ </parameters>
143
+ </data>
144
+ </dwml>
@@ -0,0 +1,93 @@
1
+ require_relative '../../spec_helper'
2
+ require_relative '../../../lib/noaa_weather_client/client'
3
+
4
+ module NoaaWeatherClient
5
+ describe Client do
6
+ let(:client) { Client.new }
7
+
8
+ it "requires no arguments" do
9
+ Client.new
10
+ end
11
+
12
+ context "#forecast_by_day" do
13
+ it "fetches a 7 day forecast by default" do
14
+ VCR.use_cassette(:forecast_by_day_7) do
15
+ expect(client.forecast_by_day(37.1962, -93.2861).size).to eq(7)
16
+ end
17
+ end
18
+
19
+ it "fetches less than 7 day forecast if requested" do
20
+ VCR.use_cassette(:forecast_by_day_3) do
21
+ expect(client.forecast_by_day(37.1962, -93.2861, days: 3).size).to eq(3)
22
+ end
23
+ end
24
+ end
25
+
26
+ context "#weather_stations" do
27
+ it "fetches a list of all weather stations" do
28
+ VCR.use_cassette(:weather_stations) do
29
+ expect(client.weather_stations.size).to be > 2500
30
+ end
31
+ end
32
+
33
+ it "caches weather stations" do
34
+ VCR.use_cassette(:weather_stations) do
35
+ stations = client.weather_stations
36
+ expect(client.weather_stations.object_id).to eq(stations.object_id)
37
+ end
38
+ end
39
+
40
+ it "reloads stations with :reload flag" do
41
+ VCR.use_cassette(:weather_stations) do
42
+ stations = client.weather_stations
43
+ client.instance_variable_set('@weather_stations', double)
44
+ expect(client.weather_stations(relaod: true).object_id).to_not eq(stations.object_id)
45
+ end
46
+ end
47
+ end
48
+
49
+ context "#current_observations" do
50
+ it "fetches the current weather observation from the station nearest the coordinates" do
51
+ VCR.use_cassette(:current_observations) do
52
+ expect(client.current_observations(37.1962, -93.2861).station_id).to eq('KSGF')
53
+ end
54
+ end
55
+
56
+ it "fetches the current weather observation with temp in f" do
57
+ VCR.use_cassette(:current_observations) do
58
+ expect(client.current_observations(37.1962, -93.2861).temp_f).to be
59
+ end
60
+ end
61
+
62
+ it "fetches the current weather observation with weather condition" do
63
+ VCR.use_cassette(:current_observations) do
64
+ expect(client.current_observations(37.1962, -93.2861).weather).to be
65
+ end
66
+ end
67
+ end
68
+
69
+ context "#nearest_weather_station" do
70
+ it "fetches the station nearest the coordinates" do
71
+ VCR.use_cassette(:nearest_weather_station) do
72
+ expect(client.nearest_weather_station(37.1962, -93.2861).station_id).to eq('KSGF')
73
+ end
74
+ end
75
+
76
+ it "uses a cached set of stations if provided" do
77
+ stations = [ double(latitude: 38.3456, longitude: -97.3345, station_id: 'cached_station') ]
78
+ expect(
79
+ client.nearest_weather_station(37.1962, -93.2861, stations: stations).station_id
80
+ ).to eq('cached_station')
81
+ end
82
+ end
83
+
84
+ context "#postal_code_to_coordinate" do
85
+ it "resolves a postal code to coordinate" do
86
+ VCR.use_cassette(:postal_code_to_coordinate) do
87
+ expect(client.postal_code_to_coordinate(65804).latitude).to eq(37.1962)
88
+ expect(client.postal_code_to_coordinate(65804).longitude).to eq(-93.2861)
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,122 @@
1
+
2
+ require_relative '../../../spec_helper'
3
+ require_relative '../../../../lib/noaa_weather_client/responses/current_observation'
4
+
5
+ module NoaaWeatherClient
6
+ module Responses
7
+ describe CurrentObservation do
8
+ let(:body) {
9
+ VCR.use_cassette(:current_observations, match_requests_on: [:method, :uri]) { |c|
10
+ c.http_interactions.response_for(
11
+ VCR::Request.new.tap { |r|
12
+ r.method = :get
13
+ r.uri = 'http://w1.weather.gov/xml/current_obs/KSGF.xml'
14
+ }).body
15
+ }
16
+ }
17
+ let(:current_observation) { CurrentObservation.new body }
18
+
19
+ it "requires a response" do
20
+ current_observation
21
+ expect { CurrentObservation.new }.to raise_error(ArgumentError)
22
+ end
23
+
24
+ context "when the response is invalid" do
25
+ it "raises an ArgumentError" do
26
+ expect { CurrentObservation.new '<invalid></invalid>' }.to raise_error(Errors::InvalidXmlError)
27
+ end
28
+ end
29
+
30
+ it "exposes location" do
31
+ expect(current_observation.location).to eq('Springfield-Branson National Airport, MO')
32
+ end
33
+ it "exposes station_id" do
34
+ expect(current_observation.station_id).to eq('KSGF')
35
+ end
36
+ it "exposes latitude" do
37
+ expect(current_observation.latitude).to eq(37.23)
38
+ end
39
+ it "exposes longitude" do
40
+ expect(current_observation.longitude).to eq(-93.38)
41
+ end
42
+ it "exposes observation_time_string" do
43
+ expect(current_observation.observation_time_string).to eq('Last Updated on Aug 12 2013, 8:52 pm CDT')
44
+ end
45
+ it "exposes observation_time" do
46
+ expect(current_observation.observation_time).to eq(Time.parse '2013-08-12 20:52:00 -0500')
47
+ end
48
+ it "exposes weather" do
49
+ expect(current_observation.weather).to eq('Fair')
50
+ end
51
+ it "exposes temperature_string" do
52
+ expect(current_observation.temperature_string).to eq('74.0 F (23.3 C)')
53
+ end
54
+ it "exposes temperature_fahrenheit" do
55
+ expect(current_observation.temperature_fahrenheit).to eq(74.0)
56
+ end
57
+ it "exposes temperature_celsius" do
58
+ expect(current_observation.temperature_celsius).to eq(23.3)
59
+ end
60
+ it "exposes relative_humidity" do
61
+ expect(current_observation.relative_humidity).to eq(85)
62
+ end
63
+ it "exposes wind_string" do
64
+ expect(current_observation.wind_string).to eq('Calm')
65
+ end
66
+ it "exposes wind_dir" do
67
+ expect(current_observation.wind_dir).to eq('North')
68
+ end
69
+ it "exposes wind_degrees" do
70
+ expect(current_observation.wind_degrees).to eq(0)
71
+ end
72
+ it "exposes wind_mph" do
73
+ expect(current_observation.wind_mph).to eq(0.0)
74
+ end
75
+ it "exposes wind_kt" do
76
+ expect(current_observation.wind_kt).to eq(0)
77
+ end
78
+ it "exposes pressure_string" do
79
+ expect(current_observation.pressure_string).to eq('1014.7 mb')
80
+ end
81
+ it "exposes pressure_mb" do
82
+ expect(current_observation.pressure_mb).to eq(1014.7)
83
+ end
84
+ it "exposes pressure_in" do
85
+ expect(current_observation.pressure_in).to eq(30.00)
86
+ end
87
+ it "exposes dewpoint_string" do
88
+ expect(current_observation.dewpoint_string).to eq('69.1 F (20.6 C)')
89
+ end
90
+ it "exposes dewpoint_fahrenheit" do
91
+ expect(current_observation.dewpoint_fahrenheit).to eq(69.1)
92
+ end
93
+ it "exposes dewpoint_celsius" do
94
+ expect(current_observation.dewpoint_celsius).to eq(20.6)
95
+ end
96
+ it "exposes visibility_mi" do
97
+ expect(current_observation.visibility_mi).to eq(10.00)
98
+ end
99
+ it "exposes icon_url_base" do
100
+ expect(current_observation.icon_url_base).to eq('http://forecast.weather.gov/images/wtf/small/')
101
+ end
102
+ it "exposes two_day_history_url" do
103
+ expect(current_observation.two_day_history_url).to eq('http://www.weather.gov/data/obhistory/KSGF.html')
104
+ end
105
+ it "exposes icon_url_name" do
106
+ expect(current_observation.icon_url_name).to eq('nskc.png')
107
+ end
108
+ it "exposes ob_url" do
109
+ expect(current_observation.ob_url).to eq('http://www.weather.gov/data/METAR/KSGF.1.txt')
110
+ end
111
+ it "exposes disclaimer_url" do
112
+ expect(current_observation.disclaimer_url).to eq('http://weather.gov/disclaimer.html')
113
+ end
114
+ it "exposes copyright_url" do
115
+ expect(current_observation.copyright_url).to eq('http://weather.gov/disclaimer.html')
116
+ end
117
+ it "exposes privacy_policy_url" do
118
+ expect(current_observation.privacy_policy_url).to eq('http://weather.gov/notice.html')
119
+ end
120
+ end
121
+ end
122
+ end
@@ -0,0 +1,66 @@
1
+ require_relative '../../../spec_helper'
2
+ require_relative '../../../../lib/noaa_weather_client/responses/forecast'
3
+
4
+ module NoaaWeatherClient
5
+ module Responses
6
+ describe Forecast do
7
+ let(:fake_response) { { ndf_dgen_by_day_response: { dwml_by_day_out: load_xml_fixture(:forecast) } } }
8
+ let(:fake_invalid_response) { { ndf_dgen_by_day_response: { dwml_by_day_out: '<invalid></invalid>' } } }
9
+ let(:forecast) { Forecast.new fake_response }
10
+
11
+ it "requires a response" do
12
+ forecast
13
+ expect { Forecast.new }.to raise_error(ArgumentError)
14
+ end
15
+
16
+ context "when the response is invalid" do
17
+ it "raises an ArgumentError" do
18
+ expect { Forecast.new fake_invalid_response }.to raise_error(Errors::InvalidXmlError)
19
+ end
20
+ end
21
+
22
+ it "exposes a list of days via enumerable" do
23
+ count = 0
24
+ expect { forecast.each { |d| count += 1 } }.to change { count }.by(7)
25
+ end
26
+
27
+ it "exposes number of stations via size" do
28
+ expect(forecast.size).to eq(7)
29
+ end
30
+
31
+ describe '#days' do
32
+ let(:period) { double(start_time: Time.parse('2013-08-12 06:00:00 -0500'),
33
+ end_time: Time.parse('2013-08-13 06:00:00 -0500'),
34
+ name: 'Today') }
35
+ let(:max) { 86.0 }
36
+ let(:min) { 69.0 }
37
+ let(:weather_summary) { 'Chance Thunderstorms' }
38
+ let(:day) { forecast.days.first }
39
+
40
+ it "exposes start_time from period" do
41
+ expect(day.start_time).to eq(period.start_time)
42
+ end
43
+
44
+ it "exposes end_time from period" do
45
+ expect(day.end_time).to eq(period.end_time)
46
+ end
47
+
48
+ it "exposes weekday name" do
49
+ expect(day.name).to eq("Monday")
50
+ end
51
+
52
+ it "fetches max temp" do
53
+ expect(day.maximum_temperature).to eq(max)
54
+ end
55
+
56
+ it "fetches min temp" do
57
+ expect(day.minimum_temperature).to eq(min)
58
+ end
59
+
60
+ it "fetches weather summary from parameters" do
61
+ expect(day.weather_summary).to eq(weather_summary)
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,30 @@
1
+ require_relative '../../../spec_helper'
2
+ require_relative '../../../../lib/noaa_weather_client/responses/lat_lon_list'
3
+
4
+ module NoaaWeatherClient
5
+ module Responses
6
+ describe LatLonList do
7
+ let(:fake_response) { ZIP_XML }
8
+ let(:lat_lon_list) { LatLonList.new fake_response }
9
+
10
+ it "requires a response" do
11
+ lat_lon_list
12
+ expect { LatLonList.new }.to raise_error(ArgumentError)
13
+ end
14
+
15
+ it "exposes latitude as float" do
16
+ expect(lat_lon_list.latitude).to eq(37.1962)
17
+ end
18
+
19
+ it "exposes longitude as float" do
20
+ expect(lat_lon_list.longitude).to eq(-93.2861)
21
+ end
22
+
23
+ ZIP_XML = <<-xml
24
+ <?xml version='1.0'?><dwml version='1.0' xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:noNamespaceSchemaLocation='http://graphical.weather.gov/xml/DWMLgen/schema/DWML.xsd'><latLonList>37.1962,-93.2861</latLonList></dwml>
25
+ xml
26
+ end
27
+ end
28
+ end
29
+
30
+