barometer 0.3.2 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. data/README.rdoc +78 -70
  2. data/VERSION.yml +2 -2
  3. data/bin/barometer +100 -37
  4. data/lib/barometer.rb +12 -8
  5. data/lib/barometer/base.rb +48 -20
  6. data/lib/barometer/data.rb +5 -1
  7. data/lib/barometer/data/current.rb +23 -15
  8. data/lib/barometer/data/distance.rb +15 -5
  9. data/lib/barometer/data/forecast.rb +23 -5
  10. data/lib/barometer/data/geo.rb +16 -54
  11. data/lib/barometer/data/local_datetime.rb +137 -0
  12. data/lib/barometer/data/local_time.rb +134 -0
  13. data/lib/barometer/data/location.rb +6 -1
  14. data/lib/barometer/data/measurement.rb +71 -42
  15. data/lib/barometer/data/night.rb +69 -0
  16. data/lib/barometer/data/pressure.rb +15 -5
  17. data/lib/barometer/data/speed.rb +16 -5
  18. data/lib/barometer/data/sun.rb +8 -20
  19. data/lib/barometer/data/temperature.rb +22 -9
  20. data/lib/barometer/data/units.rb +10 -19
  21. data/lib/barometer/data/zone.rb +135 -9
  22. data/lib/barometer/formats.rb +12 -0
  23. data/lib/barometer/formats/coordinates.rb +42 -0
  24. data/lib/barometer/formats/format.rb +46 -0
  25. data/lib/barometer/formats/geocode.rb +51 -0
  26. data/lib/barometer/formats/icao.rb +37 -0
  27. data/lib/barometer/formats/postalcode.rb +22 -0
  28. data/lib/barometer/formats/short_zipcode.rb +17 -0
  29. data/lib/barometer/formats/weather_id.rb +107 -0
  30. data/lib/barometer/formats/zipcode.rb +31 -0
  31. data/lib/barometer/query.rb +61 -232
  32. data/lib/barometer/services.rb +14 -4
  33. data/lib/barometer/translations/icao_country_codes.yml +9 -0
  34. data/lib/barometer/translations/weather_country_codes.yml +17 -0
  35. data/lib/barometer/weather.rb +51 -30
  36. data/lib/barometer/{services → weather_services}/google.rb +23 -26
  37. data/lib/barometer/weather_services/noaa.rb +6 -0
  38. data/lib/barometer/{services → weather_services}/service.rb +101 -92
  39. data/lib/barometer/weather_services/weather_bug.rb +6 -0
  40. data/lib/barometer/weather_services/weather_dot_com.rb +261 -0
  41. data/lib/barometer/{services → weather_services}/wunderground.rb +58 -76
  42. data/lib/barometer/{services → weather_services}/yahoo.rb +91 -121
  43. data/lib/barometer/web_services/geocode.rb +33 -0
  44. data/lib/barometer/web_services/weather_id.rb +37 -0
  45. data/lib/barometer/web_services/web_service.rb +32 -0
  46. data/lib/demometer/demometer.rb +31 -4
  47. data/lib/demometer/views/forecast.erb +20 -0
  48. data/lib/demometer/views/index.erb +10 -3
  49. data/lib/demometer/views/measurement.erb +8 -3
  50. data/lib/demometer/views/readme.erb +63 -24
  51. data/spec/barometer_spec.rb +18 -36
  52. data/spec/{data_current_spec.rb → data/current_spec.rb} +73 -49
  53. data/spec/{data_distance_spec.rb → data/distance_spec.rb} +30 -30
  54. data/spec/{data_forecast_spec.rb → data/forecast_spec.rb} +57 -15
  55. data/spec/data/geo_spec.rb +91 -0
  56. data/spec/data/local_datetime_spec.rb +269 -0
  57. data/spec/data/local_time_spec.rb +239 -0
  58. data/spec/{data_location_spec.rb → data/location_spec.rb} +12 -1
  59. data/spec/{data_measurement_spec.rb → data/measurement_spec.rb} +135 -66
  60. data/spec/data/night_measurement_spec.rb +136 -0
  61. data/spec/{data_pressure_spec.rb → data/pressure_spec.rb} +29 -29
  62. data/spec/{data_speed_spec.rb → data/speed_spec.rb} +30 -30
  63. data/spec/data/sun_spec.rb +49 -0
  64. data/spec/{data_temperature_spec.rb → data/temperature_spec.rb} +44 -44
  65. data/spec/{units_spec.rb → data/units_spec.rb} +6 -6
  66. data/spec/{data_zone_spec.rb → data/zone_spec.rb} +15 -15
  67. data/spec/fixtures/formats/weather_id/90210.xml +1 -0
  68. data/spec/fixtures/formats/weather_id/atlanta.xml +1 -0
  69. data/spec/fixtures/formats/weather_id/from_USGA0028.xml +1 -0
  70. data/spec/fixtures/formats/weather_id/new_york.xml +1 -0
  71. data/spec/fixtures/{geocode_40_73.xml → geocode/40_73.xml} +0 -0
  72. data/spec/fixtures/{geocode_90210.xml → geocode/90210.xml} +0 -0
  73. data/spec/fixtures/{geocode_T5B4M9.xml → geocode/T5B4M9.xml} +0 -0
  74. data/spec/fixtures/geocode/atlanta.xml +1 -0
  75. data/spec/fixtures/{geocode_calgary_ab.xml → geocode/calgary_ab.xml} +0 -0
  76. data/spec/fixtures/{geocode_ksfo.xml → geocode/ksfo.xml} +0 -0
  77. data/spec/fixtures/{geocode_newyork_ny.xml → geocode/newyork_ny.xml} +0 -0
  78. data/spec/fixtures/{google_calgary_ab.xml → services/google/calgary_ab.xml} +0 -0
  79. data/spec/fixtures/services/weather_dot_com/90210.xml +1 -0
  80. data/spec/fixtures/{current_calgary_ab.xml → services/wunderground/current_calgary_ab.xml} +0 -0
  81. data/spec/fixtures/{forecast_calgary_ab.xml → services/wunderground/forecast_calgary_ab.xml} +0 -0
  82. data/spec/fixtures/{yahoo_90210.xml → services/yahoo/90210.xml} +0 -0
  83. data/spec/formats/coordinates_spec.rb +158 -0
  84. data/spec/formats/format_spec.rb +73 -0
  85. data/spec/formats/geocode_spec.rb +179 -0
  86. data/spec/formats/icao_spec.rb +61 -0
  87. data/spec/formats/postalcode_spec.rb +59 -0
  88. data/spec/formats/short_zipcode_spec.rb +53 -0
  89. data/spec/formats/weather_id_spec.rb +191 -0
  90. data/spec/formats/zipcode_spec.rb +111 -0
  91. data/spec/query_spec.rb +261 -288
  92. data/spec/spec_helper.rb +128 -4
  93. data/spec/{service_google_spec.rb → weather_services/google_spec.rb} +46 -46
  94. data/spec/weather_services/services_spec.rb +1118 -0
  95. data/spec/weather_services/weather_dot_com_spec.rb +327 -0
  96. data/spec/weather_services/wunderground_spec.rb +332 -0
  97. data/spec/{service_yahoo_spec.rb → weather_services/yahoo_spec.rb} +65 -81
  98. data/spec/weather_spec.rb +73 -61
  99. data/spec/web_services/geocode_spec.rb +45 -0
  100. data/spec/web_services/web_services_spec.rb +26 -0
  101. metadata +88 -36
  102. data/lib/barometer/services/noaa.rb +0 -6
  103. data/lib/barometer/services/weather_bug.rb +0 -6
  104. data/lib/barometer/services/weather_dot_com.rb +0 -6
  105. data/spec/data_geo_spec.rb +0 -94
  106. data/spec/data_sun_spec.rb +0 -76
  107. data/spec/service_wunderground_spec.rb +0 -330
  108. data/spec/services_spec.rb +0 -1106
@@ -0,0 +1,327 @@
1
+ require 'spec_helper'
2
+ include Barometer
3
+
4
+ describe "WeatherDotCom" do
5
+
6
+ before(:each) do
7
+ @accepted_formats = [:short_zipcode, :weather_id]
8
+ #Barometer.config = { 1 => { :weather => { :keys => { :partner => WEATHER_PARTNER_KEY, :license => WEATHER_LICENSE_KEY }}}}
9
+ WeatherService::WeatherDotCom.keys = { :partner => WEATHER_PARTNER_KEY, :license => WEATHER_LICENSE_KEY }
10
+ end
11
+
12
+ describe "the class methods" do
13
+
14
+ it "defines accepted_formats" do
15
+ WeatherService::WeatherDotCom.accepted_formats.should == @accepted_formats
16
+ end
17
+
18
+ it "defines get_all" do
19
+ WeatherService::WeatherDotCom.respond_to?("fetch").should be_true
20
+ end
21
+
22
+ end
23
+
24
+ describe "building the current data" do
25
+
26
+ it "defines the build method" do
27
+ WeatherService::WeatherDotCom.respond_to?("build_current").should be_true
28
+ end
29
+
30
+ it "requires Hash input" do
31
+ lambda { WeatherService::WeatherDotCom.build_current }.should raise_error(ArgumentError)
32
+ lambda { WeatherService::WeatherDotCom.build_current({}) }.should_not raise_error(ArgumentError)
33
+ end
34
+
35
+ it "returns Data::CurrentMeasurement object" do
36
+ current = WeatherService::WeatherDotCom.build_current({})
37
+ current.is_a?(Data::CurrentMeasurement).should be_true
38
+ end
39
+
40
+ end
41
+
42
+ describe "building the forecast data" do
43
+
44
+ it "defines the build method" do
45
+ WeatherService::WeatherDotCom.respond_to?("build_forecast").should be_true
46
+ end
47
+
48
+ it "requires Hash input" do
49
+ lambda { WeatherService::WeatherDotCom.build_forecast }.should raise_error(ArgumentError)
50
+ lambda { WeatherService::WeatherDotCom.build_forecast({}) }.should_not raise_error(ArgumentError)
51
+ end
52
+
53
+ it "returns Array object" do
54
+ current = WeatherService::WeatherDotCom.build_forecast({})
55
+ current.is_a?(Array).should be_true
56
+ end
57
+
58
+ end
59
+
60
+ describe "building the location data" do
61
+
62
+ it "defines the build method" do
63
+ WeatherService::WeatherDotCom.respond_to?("build_location").should be_true
64
+ end
65
+
66
+ it "requires Hash input" do
67
+ lambda { WeatherService::WeatherDotCom.build_location }.should raise_error(ArgumentError)
68
+ lambda { WeatherService::WeatherDotCom.build_location({}) }.should_not raise_error(ArgumentError)
69
+ end
70
+
71
+ it "requires Barometer::Geo input" do
72
+ geo = Data::Geo.new({})
73
+ lambda { WeatherService::WeatherDotCom.build_location({}, {}) }.should raise_error(ArgumentError)
74
+ lambda { WeatherService::WeatherDotCom.build_location({}, geo) }.should_not raise_error(ArgumentError)
75
+ end
76
+
77
+ it "returns Barometer::Location object" do
78
+ location = WeatherService::WeatherDotCom.build_location({})
79
+ location.is_a?(Data::Location).should be_true
80
+ end
81
+
82
+ end
83
+
84
+ describe "building the sun data" do
85
+
86
+ it "defines the build method" do
87
+ WeatherService::WeatherDotCom.respond_to?("build_sun").should be_true
88
+ end
89
+
90
+ it "requires Hash input" do
91
+ lambda { WeatherService::WeatherDotCom.build_sun }.should raise_error(ArgumentError)
92
+ lambda { WeatherService::WeatherDotCom.build_sun({}) }.should_not raise_error(ArgumentError)
93
+ end
94
+
95
+ it "returns Barometer::Sun object" do
96
+ sun = WeatherService::WeatherDotCom.build_sun({})
97
+ sun.is_a?(Data::Sun).should be_true
98
+ end
99
+
100
+ end
101
+
102
+ describe "when measuring" do
103
+
104
+ before(:each) do
105
+ @query = Barometer::Query.new("90210")
106
+ @measurement = Data::Measurement.new
107
+
108
+ url = "http://xoap.weather.com:80/weather/local/"
109
+
110
+ FakeWeb.register_uri(:get,
111
+ "#{url}90210?dayf=5&unit=m&link=xoap&par=#{WEATHER_PARTNER_KEY}&prod=xoap&key=#{WEATHER_LICENSE_KEY}&cc=*",
112
+ :string => File.read(File.join(File.dirname(__FILE__),
113
+ '../fixtures/services/weather_dot_com',
114
+ '90210.xml')
115
+ )
116
+ )
117
+ end
118
+
119
+ describe "all" do
120
+
121
+ it "responds to _measure" do
122
+ WeatherService::WeatherDotCom.respond_to?("_measure").should be_true
123
+ end
124
+
125
+ it "requires a Barometer::Measurement object" do
126
+ lambda { WeatherService::WeatherDotCom._measure(nil, @query) }.should raise_error(ArgumentError)
127
+ lambda { WeatherService::WeatherDotCom._measure("invlaid", @query) }.should raise_error(ArgumentError)
128
+
129
+ lambda { WeatherService::WeatherDotCom._measure(@measurement, @query) }.should_not raise_error(ArgumentError)
130
+ end
131
+
132
+ it "requires a Barometer::Query query" do
133
+ lambda { WeatherService::WeatherDotCom._measure }.should raise_error(ArgumentError)
134
+ lambda { WeatherService::WeatherDotCom._measure(@measurement, 1) }.should raise_error(ArgumentError)
135
+
136
+ lambda { WeatherService::WeatherDotCom._measure(@measurement, @query) }.should_not raise_error(ArgumentError)
137
+ end
138
+
139
+ it "returns a Barometer::Measurement object" do
140
+ result = WeatherService::WeatherDotCom._measure(@measurement, @query)
141
+ result.is_a?(Data::Measurement).should be_true
142
+ result.current.is_a?(Data::CurrentMeasurement).should be_true
143
+ result.forecast.is_a?(Array).should be_true
144
+
145
+ result.source.should == :weather_dot_com
146
+ end
147
+
148
+ end
149
+
150
+ end
151
+
152
+ describe "when answering the simple questions," do
153
+
154
+ before(:each) do
155
+ @measurement = Data::Measurement.new
156
+ end
157
+
158
+ describe "currently_wet_by_icon?" do
159
+
160
+ before(:each) do
161
+ @measurement.current = Data::CurrentMeasurement.new
162
+ end
163
+
164
+ it "returns true if matching icon code" do
165
+ @measurement.current.icon = "4"
166
+ @measurement.current.icon?.should be_true
167
+ WeatherService::WeatherDotCom.currently_wet_by_icon?(@measurement.current).should be_true
168
+ end
169
+
170
+ it "returns false if NO matching icon code" do
171
+ @measurement.current.icon = "32"
172
+ @measurement.current.icon?.should be_true
173
+ WeatherService::WeatherDotCom.currently_wet_by_icon?(@measurement.current).should be_false
174
+ end
175
+
176
+ end
177
+
178
+ describe "forecasted_wet_by_icon?" do
179
+
180
+ before(:each) do
181
+ @measurement.forecast = [Data::ForecastMeasurement.new]
182
+ @measurement.forecast.first.date = Date.today
183
+ @measurement.forecast.size.should == 1
184
+ end
185
+
186
+ it "returns true if matching icon code" do
187
+ @measurement.forecast.first.icon = "4"
188
+ @measurement.forecast.first.icon?.should be_true
189
+ WeatherService::WeatherDotCom.forecasted_wet_by_icon?(@measurement.forecast.first).should be_true
190
+ end
191
+
192
+ it "returns false if NO matching icon code" do
193
+ @measurement.forecast.first.icon = "32"
194
+ @measurement.forecast.first.icon?.should be_true
195
+ WeatherService::WeatherDotCom.forecasted_wet_by_icon?(@measurement.forecast.first).should be_false
196
+ end
197
+
198
+ end
199
+
200
+ describe "currently_sunny_by_icon?" do
201
+
202
+ before(:each) do
203
+ @measurement.current = Data::CurrentMeasurement.new
204
+ end
205
+
206
+ it "returns true if matching icon code" do
207
+ @measurement.current.icon = "32"
208
+ @measurement.current.icon?.should be_true
209
+ WeatherService::WeatherDotCom.currently_sunny_by_icon?(@measurement.current).should be_true
210
+ end
211
+
212
+ it "returns false if NO matching icon code" do
213
+ @measurement.current.icon = "4"
214
+ @measurement.current.icon?.should be_true
215
+ WeatherService::WeatherDotCom.currently_sunny_by_icon?(@measurement.current).should be_false
216
+ end
217
+
218
+ end
219
+
220
+ describe "forecasted_sunny_by_icon?" do
221
+
222
+ before(:each) do
223
+ @measurement.forecast = [Data::ForecastMeasurement.new]
224
+ @measurement.forecast.first.date = Date.today
225
+ @measurement.forecast.size.should == 1
226
+ end
227
+
228
+ it "returns true if matching icon code" do
229
+ @measurement.forecast.first.icon = "32"
230
+ @measurement.forecast.first.icon?.should be_true
231
+ WeatherService::WeatherDotCom.forecasted_sunny_by_icon?(@measurement.forecast.first).should be_true
232
+ end
233
+
234
+ it "returns false if NO matching icon code" do
235
+ @measurement.forecast.first.icon = "4"
236
+ @measurement.forecast.first.icon?.should be_true
237
+ WeatherService::WeatherDotCom.forecasted_sunny_by_icon?(@measurement.forecast.first).should be_false
238
+ end
239
+
240
+ end
241
+
242
+ end
243
+
244
+ describe "overall data correctness" do
245
+
246
+ before(:each) do
247
+ @query = Barometer::Query.new("90210")
248
+ @measurement = Data::Measurement.new
249
+
250
+ url = "http://xoap.weather.com:80/weather/local/"
251
+
252
+ FakeWeb.register_uri(:get,
253
+ "#{url}90210?dayf=5&unit=m&link=xoap&par=#{WEATHER_PARTNER_KEY}&prod=xoap&key=#{WEATHER_LICENSE_KEY}&cc=*",
254
+ :string => File.read(File.join(File.dirname(__FILE__),
255
+ '../fixtures/services/weather_dot_com',
256
+ '90210.xml')
257
+ )
258
+ )
259
+ end
260
+
261
+ it "should correctly build the data" do
262
+ result = WeatherService::WeatherDotCom._measure(@measurement, @query)
263
+
264
+ # build current
265
+ @measurement.current.humidity.to_i.should == 75
266
+ @measurement.current.icon.should == "33"
267
+ @measurement.current.condition.should == "Fair"
268
+ @measurement.current.temperature.to_i.should == 16
269
+ @measurement.current.dew_point.to_i.should == 12
270
+ @measurement.current.wind_chill.to_i.should == 16
271
+ @measurement.current.wind.to_i.should == 5
272
+ @measurement.current.wind.degrees.to_i.should == 80
273
+ @measurement.current.wind.direction.should == "E"
274
+ @measurement.current.pressure.to_f.should == 1016.6
275
+ @measurement.current.visibility.to_f.should == 16.1
276
+
277
+ # build sun
278
+ # sun_rise = Barometer::Zone.merge("6:01 am", "5/4/09 12:51 AM PDT", -7)
279
+ # sun_set = Barometer::Zone.merge("7:40 pm", "5/4/09 12:51 AM PDT", -7)
280
+ # @measurement.current.sun.rise.should == sun_rise
281
+ # @measurement.current.sun.set.should == sun_set
282
+ @measurement.current.sun.rise.to_s.should == "06:01 am"
283
+ @measurement.current.sun.set.to_s.should == "07:40 pm"
284
+
285
+ # builds location
286
+ @measurement.location.name.should == "Beverly Hills, CA (90210)"
287
+ @measurement.location.latitude.to_f.should == 34.10
288
+ @measurement.location.longitude.to_f.should == -118.41
289
+
290
+ # builds forecasts
291
+ @measurement.forecast.size.should == 5
292
+
293
+ @measurement.forecast[0].date.should == Date.parse("May 3")
294
+ @measurement.forecast[0].condition.should == "Partly Cloudy"
295
+ @measurement.forecast[0].icon.should == "30"
296
+ @measurement.forecast[0].high.should be_nil
297
+ @measurement.forecast[0].low.to_i.should == 14
298
+ @measurement.forecast[0].pop.to_i.should == 10
299
+ @measurement.forecast[0].humidity.to_i.should == 65
300
+
301
+ @measurement.forecast[0].wind.should_not be_nil
302
+ @measurement.forecast[0].wind.to_i.should == 16
303
+ @measurement.forecast[0].wind.degrees.to_i.should == 288
304
+ @measurement.forecast[0].wind.direction.should == "WNW"
305
+
306
+ # sun_rise = Barometer::Zone.merge("6:02 am", "5/4/09 12:25 AM PDT", -7)
307
+ # sun_set = Barometer::Zone.merge("7:40 pm", "5/4/09 12:25 AM PDT", -7)
308
+ # @measurement.forecast[0].sun.rise.should == sun_rise
309
+ # @measurement.forecast[0].sun.set.should == sun_set
310
+ @measurement.forecast[0].sun.rise.to_s.should == "06:02 am"
311
+ @measurement.forecast[0].sun.set.to_s.should == "07:40 pm"
312
+
313
+ @measurement.forecast[0].night.should_not be_nil
314
+ @measurement.forecast[0].night.condition.should == "Partly Cloudy"
315
+ @measurement.forecast[0].night.icon.should == "29"
316
+ @measurement.forecast[0].night.pop.to_i.should == 10
317
+ @measurement.forecast[0].night.humidity.to_i.should == 71
318
+
319
+ @measurement.forecast[0].night.wind.should_not be_nil
320
+ @measurement.forecast[0].night.wind.to_i.should == 14
321
+ @measurement.forecast[0].night.wind.degrees.to_i.should == 335
322
+ @measurement.forecast[0].night.wind.direction.should == "NNW"
323
+ end
324
+
325
+ end
326
+
327
+ end
@@ -0,0 +1,332 @@
1
+ require 'spec_helper'
2
+ include Barometer
3
+
4
+ describe "Wunderground" do
5
+
6
+ before(:each) do
7
+ @accepted_formats = [:zipcode, :postalcode, :icao, :coordinates, :geocode]
8
+ @base_uri = "http://api.wunderground.com/auto/wui/geo"
9
+ end
10
+
11
+ describe "the class methods" do
12
+
13
+ it "defines accepted_formats" do
14
+ WeatherService::Wunderground.accepted_formats.should == @accepted_formats
15
+ end
16
+
17
+ it "defines get_current" do
18
+ WeatherService::Wunderground.respond_to?("get_current").should be_true
19
+ end
20
+
21
+ it "defines get_forecast" do
22
+ WeatherService::Wunderground.respond_to?("get_forecast").should be_true
23
+ end
24
+
25
+ end
26
+
27
+ describe "building the current data" do
28
+
29
+ it "defines the build method" do
30
+ WeatherService::Wunderground.respond_to?("build_current").should be_true
31
+ end
32
+
33
+ it "requires Hash input" do
34
+ lambda { WeatherService::Wunderground.build_current }.should raise_error(ArgumentError)
35
+ WeatherService::Wunderground.build_current({})
36
+ lambda { WeatherService::Wunderground.build_current({}) }.should_not raise_error(ArgumentError)
37
+ end
38
+
39
+ it "returns Barometer::CurrentMeasurement object" do
40
+ current = WeatherService::Wunderground.build_current({})
41
+ current.is_a?(Data::CurrentMeasurement).should be_true
42
+ end
43
+
44
+ end
45
+
46
+ describe "building the forecast data" do
47
+
48
+ it "defines the build method" do
49
+ WeatherService::Wunderground.respond_to?("build_forecast").should be_true
50
+ end
51
+
52
+ it "requires Hash input" do
53
+ lambda { WeatherService::Wunderground.build_forecast }.should raise_error(ArgumentError)
54
+ lambda { WeatherService::Wunderground.build_forecast({}) }.should_not raise_error(ArgumentError)
55
+ end
56
+
57
+ it "returns Array object" do
58
+ current = WeatherService::Wunderground.build_forecast({})
59
+ current.is_a?(Array).should be_true
60
+ end
61
+
62
+ end
63
+
64
+ describe "building the station data" do
65
+
66
+ it "defines the build method" do
67
+ WeatherService::Wunderground.respond_to?("build_station").should be_true
68
+ end
69
+
70
+ it "requires Hash input" do
71
+ lambda { WeatherService::Wunderground.build_station }.should raise_error(ArgumentError)
72
+ lambda { WeatherService::Wunderground.build_station({}) }.should_not raise_error(ArgumentError)
73
+ end
74
+
75
+ it "returns Barometer::Location object" do
76
+ station = WeatherService::Wunderground.build_station({})
77
+ station.is_a?(Data::Location).should be_true
78
+ end
79
+
80
+ end
81
+
82
+ describe "building the location data" do
83
+
84
+ it "defines the build method" do
85
+ WeatherService::Wunderground.respond_to?("build_location").should be_true
86
+ end
87
+
88
+ it "requires Hash input" do
89
+ lambda { WeatherService::Wunderground.build_location }.should raise_error(ArgumentError)
90
+ lambda { WeatherService::Wunderground.build_location({}) }.should_not raise_error(ArgumentError)
91
+ end
92
+
93
+ it "returns Barometer::Location object" do
94
+ location = WeatherService::Wunderground.build_location({})
95
+ location.is_a?(Data::Location).should be_true
96
+ end
97
+
98
+ end
99
+
100
+ describe "building the timezone" do
101
+
102
+ it "defines the build method" do
103
+ WeatherService::Wunderground.respond_to?("build_timezone").should be_true
104
+ end
105
+
106
+ it "requires Hash input" do
107
+ lambda { WeatherService::Wunderground.build_timezone }.should raise_error(ArgumentError)
108
+ lambda { WeatherService::Wunderground.build_timezone({}) }.should_not raise_error(ArgumentError)
109
+ end
110
+
111
+ end
112
+
113
+ describe "building the sun data" do
114
+
115
+ before(:each) do
116
+ @zone = Data::Zone.new("Europe/Paris")
117
+ end
118
+
119
+ it "defines the build method" do
120
+ WeatherService::Wunderground.respond_to?("build_sun").should be_true
121
+ end
122
+
123
+ it "requires Hash input" do
124
+ lambda { WeatherService::Wunderground.build_sun }.should raise_error(ArgumentError)
125
+ lambda { WeatherService::Wunderground.build_sun({},@zone) }.should_not raise_error(ArgumentError)
126
+ end
127
+
128
+ it "requires Barometer::Zone input" do
129
+ lambda { WeatherService::Wunderground.build_sun({}) }.should raise_error(ArgumentError)
130
+ lambda { WeatherService::Wunderground.build_sun({}, "invalid") }.should raise_error(ArgumentError)
131
+ lambda { WeatherService::Wunderground.build_sun({},@zone) }.should_not raise_error(ArgumentError)
132
+ end
133
+
134
+ it "returns Barometer::Sun object" do
135
+ sun = WeatherService::Wunderground.build_sun({},@zone)
136
+ sun.is_a?(Data::Sun).should be_true
137
+ end
138
+
139
+ end
140
+
141
+ describe "when measuring" do
142
+
143
+ before(:each) do
144
+ @query = Barometer::Query.new("Calgary,AB")
145
+ @measurement = Data::Measurement.new
146
+
147
+ FakeWeb.register_uri(:get,
148
+ "http://api.wunderground.com/auto/wui/geo/WXCurrentObXML/index.xml?query=#{CGI.escape(@query.q)}",
149
+ :string => File.read(File.join(File.dirname(__FILE__),
150
+ '../fixtures/services/wunderground',
151
+ 'current_calgary_ab.xml')
152
+ )
153
+ )
154
+ FakeWeb.register_uri(:get,
155
+ "http://api.wunderground.com/auto/wui/geo/ForecastXML/index.xml?query=#{CGI.escape(@query.q)}",
156
+ :string => File.read(File.join(File.dirname(__FILE__),
157
+ '../fixtures/services/wunderground',
158
+ 'forecast_calgary_ab.xml')
159
+ )
160
+ )
161
+ end
162
+
163
+ describe "all" do
164
+
165
+ it "responds to _measure" do
166
+ WeatherService::Wunderground.respond_to?("_measure").should be_true
167
+ end
168
+
169
+ it "requires a Barometer::Measurement object" do
170
+ lambda { WeatherService::Wunderground._measure(nil, @query) }.should raise_error(ArgumentError)
171
+ lambda { WeatherService::Wunderground._measure("invlaid", @query) }.should raise_error(ArgumentError)
172
+
173
+ lambda { WeatherService::Wunderground._measure(@measurement, @query) }.should_not raise_error(ArgumentError)
174
+ end
175
+
176
+ it "requires a Barometer::Query query" do
177
+ lambda { WeatherService::Wunderground._measure }.should raise_error(ArgumentError)
178
+ lambda { WeatherService::Wunderground._measure(@measurement, 1) }.should raise_error(ArgumentError)
179
+
180
+ lambda { WeatherService::Wunderground._measure(@measurement, @query) }.should_not raise_error(ArgumentError)
181
+ end
182
+
183
+ it "returns a Barometer::Measurement object" do
184
+ result = WeatherService::Wunderground._measure(@measurement, @query)
185
+ result.is_a?(Data::Measurement).should be_true
186
+ result.current.is_a?(Data::CurrentMeasurement).should be_true
187
+ result.forecast.is_a?(Array).should be_true
188
+
189
+ result.source.should == :wunderground
190
+ end
191
+
192
+ end
193
+
194
+ end
195
+
196
+ describe "when answering the simple questions," do
197
+
198
+ before(:each) do
199
+ @measurement = Data::Measurement.new
200
+ end
201
+
202
+ describe "currently_wet_by_icon?" do
203
+
204
+ before(:each) do
205
+ @measurement.current = Data::CurrentMeasurement.new
206
+ end
207
+
208
+ it "returns true if matching icon code" do
209
+ @measurement.current.icon = "rain"
210
+ @measurement.current.icon?.should be_true
211
+ WeatherService::Wunderground.currently_wet_by_icon?(@measurement.current).should be_true
212
+ end
213
+
214
+ it "returns false if NO matching icon code" do
215
+ @measurement.current.icon = "sunny"
216
+ @measurement.current.icon?.should be_true
217
+ WeatherService::Wunderground.currently_wet_by_icon?(@measurement.current).should be_false
218
+ end
219
+
220
+ end
221
+
222
+ describe "forecasted_wet_by_icon?" do
223
+
224
+ before(:each) do
225
+ @measurement.forecast = [Data::ForecastMeasurement.new]
226
+ @measurement.forecast.first.date = Date.today
227
+ @measurement.forecast.size.should == 1
228
+ end
229
+
230
+ it "returns true if matching icon code" do
231
+ @measurement.forecast.first.icon = "rain"
232
+ @measurement.forecast.first.icon?.should be_true
233
+ WeatherService::Wunderground.forecasted_wet_by_icon?(@measurement.forecast.first).should be_true
234
+ end
235
+
236
+ it "returns false if NO matching icon code" do
237
+ @measurement.forecast.first.icon = "sunny"
238
+ @measurement.forecast.first.icon?.should be_true
239
+ WeatherService::Wunderground.forecasted_wet_by_icon?(@measurement.forecast.first).should be_false
240
+ end
241
+
242
+ end
243
+
244
+ describe "currently_sunny_by_icon?" do
245
+
246
+ before(:each) do
247
+ @measurement.current = Data::CurrentMeasurement.new
248
+ end
249
+
250
+ it "returns true if matching icon code" do
251
+ @measurement.current.icon = "sunny"
252
+ @measurement.current.icon?.should be_true
253
+ WeatherService::Wunderground.currently_sunny_by_icon?(@measurement.current).should be_true
254
+ end
255
+
256
+ it "returns false if NO matching icon code" do
257
+ @measurement.current.icon = "rain"
258
+ @measurement.current.icon?.should be_true
259
+ WeatherService::Wunderground.currently_sunny_by_icon?(@measurement.current).should be_false
260
+ end
261
+
262
+ end
263
+
264
+ describe "forecasted_sunny_by_icon?" do
265
+
266
+ before(:each) do
267
+ @measurement.forecast = [Data::ForecastMeasurement.new]
268
+ @measurement.forecast.first.date = Date.today
269
+ @measurement.forecast.size.should == 1
270
+ end
271
+
272
+ it "returns true if matching icon code" do
273
+ @measurement.forecast.first.icon = "sunny"
274
+ @measurement.forecast.first.icon?.should be_true
275
+ WeatherService::Wunderground.forecasted_sunny_by_icon?(@measurement.forecast.first).should be_true
276
+ end
277
+
278
+ it "returns false if NO matching icon code" do
279
+ @measurement.forecast.first.icon = "rain"
280
+ @measurement.forecast.first.icon?.should be_true
281
+ WeatherService::Wunderground.forecasted_sunny_by_icon?(@measurement.forecast.first).should be_false
282
+ end
283
+
284
+ end
285
+
286
+ end
287
+
288
+ describe "overall data correctness" do
289
+
290
+ before(:each) do
291
+ @query = Barometer::Query.new("Calgary,AB")
292
+ @measurement = Data::Measurement.new
293
+
294
+ FakeWeb.register_uri(:get,
295
+ "http://api.wunderground.com/auto/wui/geo/WXCurrentObXML/index.xml?query=#{CGI.escape(@query.q)}",
296
+ :string => File.read(File.join(File.dirname(__FILE__),
297
+ '../fixtures/services/wunderground',
298
+ 'current_calgary_ab.xml')
299
+ )
300
+ )
301
+ FakeWeb.register_uri(:get,
302
+ "http://api.wunderground.com/auto/wui/geo/ForecastXML/index.xml?query=#{CGI.escape(@query.q)}",
303
+ :string => File.read(File.join(File.dirname(__FILE__),
304
+ '../fixtures/services/wunderground',
305
+ 'forecast_calgary_ab.xml')
306
+ )
307
+ )
308
+ end
309
+
310
+ # TODO: complete this
311
+ it "should correctly build the data" do
312
+ result = WeatherService::Wunderground._measure(@measurement, @query)
313
+
314
+ # build timezone
315
+ @measurement.timezone.timezone.should == "America/Edmonton"
316
+
317
+ # time = Time.local(2009, 4, 23, 18, 00, 0)
318
+ # rise = Time.local(time.year, time.month, time.day, 6, 23)
319
+ # set = Time.local(time.year, time.month, time.day, 20, 45)
320
+ # sun_rise = @measurement.timezone.tz.local_to_utc(rise)
321
+ # sun_set = @measurement.timezone.tz.local_to_utc(set)
322
+
323
+ # build current
324
+ #@measurement.current.sun.rise.should == sun_rise
325
+ #@measurement.current.sun.set.should == sun_set
326
+ @measurement.current.sun.rise.to_s.should == "06:23 am"
327
+ @measurement.current.sun.set.to_s.should == "08:45 pm"
328
+ end
329
+
330
+ end
331
+
332
+ end