barometer 0.1.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 (61) hide show
  1. data/LICENSE +20 -0
  2. data/README.rdoc +266 -0
  3. data/VERSION.yml +4 -0
  4. data/bin/barometer +63 -0
  5. data/lib/barometer.rb +52 -0
  6. data/lib/barometer/base.rb +52 -0
  7. data/lib/barometer/data.rb +15 -0
  8. data/lib/barometer/data/current.rb +93 -0
  9. data/lib/barometer/data/distance.rb +131 -0
  10. data/lib/barometer/data/forecast.rb +66 -0
  11. data/lib/barometer/data/geo.rb +98 -0
  12. data/lib/barometer/data/location.rb +20 -0
  13. data/lib/barometer/data/measurement.rb +161 -0
  14. data/lib/barometer/data/pressure.rb +133 -0
  15. data/lib/barometer/data/speed.rb +147 -0
  16. data/lib/barometer/data/sun.rb +35 -0
  17. data/lib/barometer/data/temperature.rb +164 -0
  18. data/lib/barometer/data/units.rb +55 -0
  19. data/lib/barometer/data/zone.rb +124 -0
  20. data/lib/barometer/extensions/graticule.rb +50 -0
  21. data/lib/barometer/extensions/httparty.rb +21 -0
  22. data/lib/barometer/query.rb +228 -0
  23. data/lib/barometer/services.rb +6 -0
  24. data/lib/barometer/services/google.rb +146 -0
  25. data/lib/barometer/services/noaa.rb +6 -0
  26. data/lib/barometer/services/service.rb +324 -0
  27. data/lib/barometer/services/weather_bug.rb +6 -0
  28. data/lib/barometer/services/weather_dot_com.rb +6 -0
  29. data/lib/barometer/services/wunderground.rb +285 -0
  30. data/lib/barometer/services/yahoo.rb +274 -0
  31. data/lib/barometer/weather.rb +187 -0
  32. data/spec/barometer_spec.rb +162 -0
  33. data/spec/data_current_spec.rb +225 -0
  34. data/spec/data_distance_spec.rb +336 -0
  35. data/spec/data_forecast_spec.rb +150 -0
  36. data/spec/data_geo_spec.rb +90 -0
  37. data/spec/data_location_spec.rb +59 -0
  38. data/spec/data_measurement_spec.rb +411 -0
  39. data/spec/data_pressure_spec.rb +336 -0
  40. data/spec/data_speed_spec.rb +374 -0
  41. data/spec/data_sun_spec.rb +76 -0
  42. data/spec/data_temperature_spec.rb +396 -0
  43. data/spec/data_zone_spec.rb +133 -0
  44. data/spec/fixtures/current_calgary_ab.xml +1 -0
  45. data/spec/fixtures/forecast_calgary_ab.xml +1 -0
  46. data/spec/fixtures/geocode_40_73.xml +1 -0
  47. data/spec/fixtures/geocode_90210.xml +1 -0
  48. data/spec/fixtures/geocode_T5B4M9.xml +1 -0
  49. data/spec/fixtures/geocode_calgary_ab.xml +1 -0
  50. data/spec/fixtures/geocode_newyork_ny.xml +1 -0
  51. data/spec/fixtures/google_calgary_ab.xml +1 -0
  52. data/spec/fixtures/yahoo_90210.xml +1 -0
  53. data/spec/query_spec.rb +469 -0
  54. data/spec/service_google_spec.rb +144 -0
  55. data/spec/service_wunderground_spec.rb +330 -0
  56. data/spec/service_yahoo_spec.rb +299 -0
  57. data/spec/services_spec.rb +1106 -0
  58. data/spec/spec_helper.rb +14 -0
  59. data/spec/units_spec.rb +101 -0
  60. data/spec/weather_spec.rb +265 -0
  61. metadata +119 -0
@@ -0,0 +1,144 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Google" do
4
+
5
+ before(:each) do
6
+ @accepted_formats = [:zipcode, :postalcode, :geocode]
7
+ @base_uri = "http://google.com"
8
+ end
9
+
10
+ describe "the class methods" do
11
+
12
+ it "defines accepted_formats" do
13
+ Barometer::Google.accepted_formats.should == @accepted_formats
14
+ end
15
+
16
+ # it "defines base_uri" do
17
+ # Barometer::Google.base_uri.should == @base_uri
18
+ # end
19
+
20
+ it "defines get_all" do
21
+ Barometer::Google.respond_to?("get_all").should be_true
22
+ end
23
+
24
+ end
25
+
26
+ describe "building the current data" do
27
+
28
+ it "defines the build method" do
29
+ Barometer::Google.respond_to?("build_current").should be_true
30
+ end
31
+
32
+ it "requires Hash input" do
33
+ lambda { Barometer::Google.build_current }.should raise_error(ArgumentError)
34
+ lambda { Barometer::Google.build_current({}) }.should_not raise_error(ArgumentError)
35
+ end
36
+
37
+ it "returns Barometer::CurrentMeasurement object" do
38
+ current = Barometer::Google.build_current({})
39
+ current.is_a?(Barometer::CurrentMeasurement).should be_true
40
+ end
41
+
42
+ end
43
+
44
+ describe "building the forecast data" do
45
+
46
+ it "defines the build method" do
47
+ Barometer::Google.respond_to?("build_forecast").should be_true
48
+ end
49
+
50
+ it "requires Hash input" do
51
+ lambda { Barometer::Google.build_forecast }.should raise_error(ArgumentError)
52
+ lambda { Barometer::Google.build_forecast({}) }.should_not raise_error(ArgumentError)
53
+ end
54
+
55
+ it "returns Array object" do
56
+ current = Barometer::Google.build_forecast({})
57
+ current.is_a?(Array).should be_true
58
+ end
59
+
60
+ end
61
+
62
+ describe "building the location data" do
63
+
64
+ it "defines the build method" do
65
+ Barometer::Google.respond_to?("build_location").should be_true
66
+ end
67
+
68
+ it "requires Barometer::Geo input" do
69
+ geo = Barometer::Geo.new({})
70
+ lambda { Barometer::Google.build_location({}) }.should raise_error(ArgumentError)
71
+ lambda { Barometer::Google.build_location(geo) }.should_not raise_error(ArgumentError)
72
+ end
73
+
74
+ it "returns Barometer::Location object" do
75
+ geo = Barometer::Geo.new({})
76
+ location = Barometer::Google.build_location(geo)
77
+ location.is_a?(Barometer::Location).should be_true
78
+ end
79
+
80
+ end
81
+
82
+ # describe "building the timezone" do
83
+ #
84
+ # it "defines the build method" do
85
+ # Barometer::Google.respond_to?("build_timezone").should be_true
86
+ # end
87
+ #
88
+ # it "requires Hash input" do
89
+ # lambda { Barometer::Google.build_timezone }.should raise_error(ArgumentError)
90
+ # lambda { Barometer::Google.build_timezone({}) }.should_not raise_error(ArgumentError)
91
+ # end
92
+ #
93
+ # end
94
+
95
+ describe "when measuring" do
96
+
97
+ before(:each) do
98
+ @query = Barometer::Query.new("Calgary,AB")
99
+ @query.preferred = "Calgary,AB"
100
+ @measurement = Barometer::Measurement.new
101
+
102
+ FakeWeb.register_uri(:get,
103
+ "http://google.com/ig/api?weather=#{CGI.escape(@query.preferred)}&hl=en-GB",
104
+ :string => File.read(File.join(File.dirname(__FILE__),
105
+ 'fixtures',
106
+ 'google_calgary_ab.xml')
107
+ )
108
+ )
109
+ end
110
+
111
+ describe "all" do
112
+
113
+ it "responds to _measure" do
114
+ Barometer::Google.respond_to?("_measure").should be_true
115
+ end
116
+
117
+ it "requires a Barometer::Measurement object" do
118
+ lambda { Barometer::Google._measure(nil, @query) }.should raise_error(ArgumentError)
119
+ lambda { Barometer::Google._measure("invlaid", @query) }.should raise_error(ArgumentError)
120
+
121
+ lambda { Barometer::Google._measure(@measurement, @query) }.should_not raise_error(ArgumentError)
122
+ end
123
+
124
+ it "requires a Barometer::Query query" do
125
+ lambda { Barometer::Google._measure }.should raise_error(ArgumentError)
126
+ lambda { Barometer::Google._measure(@measurement, 1) }.should raise_error(ArgumentError)
127
+
128
+ lambda { Barometer::Google._measure(@measurement, @query) }.should_not raise_error(ArgumentError)
129
+ end
130
+
131
+ it "returns a Barometer::Measurement object" do
132
+ result = Barometer::Google._measure(@measurement, @query)
133
+ result.is_a?(Barometer::Measurement).should be_true
134
+ result.current.is_a?(Barometer::CurrentMeasurement).should be_true
135
+ result.forecast.is_a?(Array).should be_true
136
+
137
+ result.source.should == :google
138
+ end
139
+
140
+ end
141
+
142
+ end
143
+
144
+ end
@@ -0,0 +1,330 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Wunderground" do
4
+
5
+ before(:each) do
6
+ @accepted_formats = [:zipcode, :postalcode, :coordinates, :geocode]
7
+ @base_uri = "http://api.wunderground.com/auto/wui/geo"
8
+ end
9
+
10
+ describe "the class methods" do
11
+
12
+ it "defines accepted_formats" do
13
+ Barometer::Wunderground.accepted_formats.should == @accepted_formats
14
+ end
15
+
16
+ it "defines get_current" do
17
+ Barometer::Wunderground.respond_to?("get_current").should be_true
18
+ end
19
+
20
+ it "defines get_forecast" do
21
+ Barometer::Wunderground.respond_to?("get_forecast").should be_true
22
+ end
23
+
24
+ end
25
+
26
+ describe "building the current data" do
27
+
28
+ it "defines the build method" do
29
+ Barometer::Wunderground.respond_to?("build_current").should be_true
30
+ end
31
+
32
+ it "requires Hash input" do
33
+ lambda { Barometer::Wunderground.build_current }.should raise_error(ArgumentError)
34
+ lambda { Barometer::Wunderground.build_current({}) }.should_not raise_error(ArgumentError)
35
+ end
36
+
37
+ it "returns Barometer::CurrentMeasurement object" do
38
+ current = Barometer::Wunderground.build_current({})
39
+ current.is_a?(Barometer::CurrentMeasurement).should be_true
40
+ end
41
+
42
+ end
43
+
44
+ describe "building the forecast data" do
45
+
46
+ it "defines the build method" do
47
+ Barometer::Wunderground.respond_to?("build_forecast").should be_true
48
+ end
49
+
50
+ it "requires Hash input" do
51
+ lambda { Barometer::Wunderground.build_forecast }.should raise_error(ArgumentError)
52
+ lambda { Barometer::Wunderground.build_forecast({}) }.should_not raise_error(ArgumentError)
53
+ end
54
+
55
+ it "returns Array object" do
56
+ current = Barometer::Wunderground.build_forecast({})
57
+ current.is_a?(Array).should be_true
58
+ end
59
+
60
+ end
61
+
62
+ describe "building the station data" do
63
+
64
+ it "defines the build method" do
65
+ Barometer::Wunderground.respond_to?("build_station").should be_true
66
+ end
67
+
68
+ it "requires Hash input" do
69
+ lambda { Barometer::Wunderground.build_station }.should raise_error(ArgumentError)
70
+ lambda { Barometer::Wunderground.build_station({}) }.should_not raise_error(ArgumentError)
71
+ end
72
+
73
+ it "returns Barometer::Location object" do
74
+ station = Barometer::Wunderground.build_station({})
75
+ station.is_a?(Barometer::Location).should be_true
76
+ end
77
+
78
+ end
79
+
80
+ describe "building the location data" do
81
+
82
+ it "defines the build method" do
83
+ Barometer::Wunderground.respond_to?("build_location").should be_true
84
+ end
85
+
86
+ it "requires Hash input" do
87
+ lambda { Barometer::Wunderground.build_location }.should raise_error(ArgumentError)
88
+ lambda { Barometer::Wunderground.build_location({}) }.should_not raise_error(ArgumentError)
89
+ end
90
+
91
+ it "returns Barometer::Location object" do
92
+ location = Barometer::Wunderground.build_location({})
93
+ location.is_a?(Barometer::Location).should be_true
94
+ end
95
+
96
+ end
97
+
98
+ describe "building the timezone" do
99
+
100
+ it "defines the build method" do
101
+ Barometer::Wunderground.respond_to?("build_timezone").should be_true
102
+ end
103
+
104
+ it "requires Hash input" do
105
+ lambda { Barometer::Wunderground.build_timezone }.should raise_error(ArgumentError)
106
+ lambda { Barometer::Wunderground.build_timezone({}) }.should_not raise_error(ArgumentError)
107
+ end
108
+
109
+ end
110
+
111
+ describe "building the sun data" do
112
+
113
+ before(:each) do
114
+ @zone = Barometer::Zone.new("Europe/Paris")
115
+ end
116
+
117
+ it "defines the build method" do
118
+ Barometer::Wunderground.respond_to?("build_sun").should be_true
119
+ end
120
+
121
+ it "requires Hash input" do
122
+ lambda { Barometer::Wunderground.build_sun }.should raise_error(ArgumentError)
123
+ lambda { Barometer::Wunderground.build_sun({},@zone) }.should_not raise_error(ArgumentError)
124
+ end
125
+
126
+ it "requires Barometer::Zone input" do
127
+ lambda { Barometer::Wunderground.build_sun({}) }.should raise_error(ArgumentError)
128
+ lambda { Barometer::Wunderground.build_sun({}, "invalid") }.should raise_error(ArgumentError)
129
+ lambda { Barometer::Wunderground.build_sun({},@zone) }.should_not raise_error(ArgumentError)
130
+ end
131
+
132
+ it "returns Barometer::Sun object" do
133
+ sun = Barometer::Wunderground.build_sun({},@zone)
134
+ sun.is_a?(Barometer::Sun).should be_true
135
+ end
136
+
137
+ end
138
+
139
+ describe "when measuring" do
140
+
141
+ before(:each) do
142
+ @query = Barometer::Query.new("Calgary,AB")
143
+ @query.preferred = "Calgary,AB"
144
+ @measurement = Barometer::Measurement.new
145
+
146
+ FakeWeb.register_uri(:get,
147
+ "http://api.wunderground.com/auto/wui/geo/WXCurrentObXML/index.xml?query=#{CGI.escape(@query.preferred)}",
148
+ :string => File.read(File.join(File.dirname(__FILE__),
149
+ 'fixtures',
150
+ 'current_calgary_ab.xml')
151
+ )
152
+ )
153
+ FakeWeb.register_uri(:get,
154
+ "http://api.wunderground.com/auto/wui/geo/ForecastXML/index.xml?query=#{CGI.escape(@query.preferred)}",
155
+ :string => File.read(File.join(File.dirname(__FILE__),
156
+ 'fixtures',
157
+ 'forecast_calgary_ab.xml')
158
+ )
159
+ )
160
+ end
161
+
162
+ describe "all" do
163
+
164
+ it "responds to _measure" do
165
+ Barometer::Wunderground.respond_to?("_measure").should be_true
166
+ end
167
+
168
+ it "requires a Barometer::Measurement object" do
169
+ lambda { Barometer::Wunderground._measure(nil, @query) }.should raise_error(ArgumentError)
170
+ lambda { Barometer::Wunderground._measure("invlaid", @query) }.should raise_error(ArgumentError)
171
+
172
+ lambda { Barometer::Wunderground._measure(@measurement, @query) }.should_not raise_error(ArgumentError)
173
+ end
174
+
175
+ it "requires a Barometer::Query query" do
176
+ lambda { Barometer::Wunderground._measure }.should raise_error(ArgumentError)
177
+ lambda { Barometer::Wunderground._measure(@measurement, 1) }.should raise_error(ArgumentError)
178
+
179
+ lambda { Barometer::Wunderground._measure(@measurement, @query) }.should_not raise_error(ArgumentError)
180
+ end
181
+
182
+ it "returns a Barometer::Measurement object" do
183
+ result = Barometer::Wunderground._measure(@measurement, @query)
184
+ result.is_a?(Barometer::Measurement).should be_true
185
+ result.current.is_a?(Barometer::CurrentMeasurement).should be_true
186
+ result.forecast.is_a?(Array).should be_true
187
+
188
+ result.source.should == :wunderground
189
+ end
190
+
191
+ end
192
+
193
+ end
194
+
195
+ describe "when answering the simple questions," do
196
+
197
+ before(:each) do
198
+ @measurement = Barometer::Measurement.new
199
+ end
200
+
201
+ describe "currently_wet_by_icon?" do
202
+
203
+ before(:each) do
204
+ @measurement.current = Barometer::CurrentMeasurement.new
205
+ end
206
+
207
+ it "returns true if matching icon code" do
208
+ @measurement.current.icon = "rain"
209
+ @measurement.current.icon?.should be_true
210
+ Barometer::Wunderground.currently_wet_by_icon?(@measurement.current).should be_true
211
+ end
212
+
213
+ it "returns false if NO matching icon code" do
214
+ @measurement.current.icon = "sunny"
215
+ @measurement.current.icon?.should be_true
216
+ Barometer::Wunderground.currently_wet_by_icon?(@measurement.current).should be_false
217
+ end
218
+
219
+ end
220
+
221
+ describe "forecasted_wet_by_icon?" do
222
+
223
+ before(:each) do
224
+ @measurement.forecast = [Barometer::ForecastMeasurement.new]
225
+ @measurement.forecast.first.date = Date.today
226
+ @measurement.forecast.size.should == 1
227
+ end
228
+
229
+ it "returns true if matching icon code" do
230
+ @measurement.forecast.first.icon = "rain"
231
+ @measurement.forecast.first.icon?.should be_true
232
+ Barometer::Wunderground.forecasted_wet_by_icon?(@measurement.forecast.first).should be_true
233
+ end
234
+
235
+ it "returns false if NO matching icon code" do
236
+ @measurement.forecast.first.icon = "sunny"
237
+ @measurement.forecast.first.icon?.should be_true
238
+ Barometer::Wunderground.forecasted_wet_by_icon?(@measurement.forecast.first).should be_false
239
+ end
240
+
241
+ end
242
+
243
+ describe "currently_sunny_by_icon?" do
244
+
245
+ before(:each) do
246
+ @measurement.current = Barometer::CurrentMeasurement.new
247
+ end
248
+
249
+ it "returns true if matching icon code" do
250
+ @measurement.current.icon = "sunny"
251
+ @measurement.current.icon?.should be_true
252
+ Barometer::Wunderground.currently_sunny_by_icon?(@measurement.current).should be_true
253
+ end
254
+
255
+ it "returns false if NO matching icon code" do
256
+ @measurement.current.icon = "rain"
257
+ @measurement.current.icon?.should be_true
258
+ Barometer::Wunderground.currently_sunny_by_icon?(@measurement.current).should be_false
259
+ end
260
+
261
+ end
262
+
263
+ describe "forecasted_sunny_by_icon?" do
264
+
265
+ before(:each) do
266
+ @measurement.forecast = [Barometer::ForecastMeasurement.new]
267
+ @measurement.forecast.first.date = Date.today
268
+ @measurement.forecast.size.should == 1
269
+ end
270
+
271
+ it "returns true if matching icon code" do
272
+ @measurement.forecast.first.icon = "sunny"
273
+ @measurement.forecast.first.icon?.should be_true
274
+ Barometer::Wunderground.forecasted_sunny_by_icon?(@measurement.forecast.first).should be_true
275
+ end
276
+
277
+ it "returns false if NO matching icon code" do
278
+ @measurement.forecast.first.icon = "rain"
279
+ @measurement.forecast.first.icon?.should be_true
280
+ Barometer::Wunderground.forecasted_sunny_by_icon?(@measurement.forecast.first).should be_false
281
+ end
282
+
283
+ end
284
+
285
+ end
286
+
287
+ describe "overall data correctness" do
288
+
289
+ before(:each) do
290
+ @query = Barometer::Query.new("Calgary,AB")
291
+ @query.preferred = "Calgary,AB"
292
+ @measurement = Barometer::Measurement.new
293
+
294
+ FakeWeb.register_uri(:get,
295
+ "http://api.wunderground.com/auto/wui/geo/WXCurrentObXML/index.xml?query=#{CGI.escape(@query.preferred)}",
296
+ :string => File.read(File.join(File.dirname(__FILE__),
297
+ 'fixtures',
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.preferred)}",
303
+ :string => File.read(File.join(File.dirname(__FILE__),
304
+ 'fixtures',
305
+ 'forecast_calgary_ab.xml')
306
+ )
307
+ )
308
+ end
309
+
310
+ # TODO: complete this
311
+ it "should correctly build the data" do
312
+ result = Barometer::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
+ end
327
+
328
+ end
329
+
330
+ end