barometer 0.7.3 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/.travis.yml +7 -0
- data/LICENSE +1 -1
- data/{README.rdoc → README.md} +124 -110
- data/Rakefile +1 -21
- data/TODO +8 -9
- data/barometer.gemspec +20 -19
- data/bin/barometer +36 -83
- data/lib/barometer.rb +13 -11
- data/lib/barometer/base.rb +10 -10
- data/lib/barometer/data.rb +1 -1
- data/lib/barometer/data/distance.rb +25 -25
- data/lib/barometer/data/geo.rb +9 -9
- data/lib/barometer/data/local_datetime.rb +24 -20
- data/lib/barometer/data/local_time.rb +13 -13
- data/lib/barometer/data/location.rb +6 -6
- data/lib/barometer/data/pressure.rb +24 -24
- data/lib/barometer/data/speed.rb +28 -28
- data/lib/barometer/data/sun.rb +7 -7
- data/lib/barometer/data/temperature.rb +29 -29
- data/lib/barometer/data/units.rb +9 -9
- data/lib/barometer/data/zone.rb +19 -19
- data/lib/barometer/formats.rb +1 -1
- data/lib/barometer/formats/coordinates.rb +7 -7
- data/lib/barometer/formats/format.rb +6 -6
- data/lib/barometer/formats/geocode.rb +5 -5
- data/lib/barometer/formats/icao.rb +6 -6
- data/lib/barometer/formats/postalcode.rb +3 -3
- data/lib/barometer/formats/short_zipcode.rb +2 -2
- data/lib/barometer/formats/weather_id.rb +10 -10
- data/lib/barometer/formats/woe_id.rb +20 -20
- data/lib/barometer/formats/zipcode.rb +3 -3
- data/lib/barometer/key_file_parser.rb +20 -0
- data/lib/barometer/measurements/measurement.rb +32 -32
- data/lib/barometer/measurements/result.rb +39 -39
- data/lib/barometer/measurements/result_array.rb +12 -12
- data/lib/barometer/query.rb +15 -15
- data/lib/barometer/services.rb +3 -3
- data/lib/barometer/translations/icao_country_codes.yml +20 -20
- data/lib/barometer/translations/weather_country_codes.yml +1 -1
- data/lib/barometer/translations/zone_codes.yml +2 -2
- data/lib/barometer/version.rb +3 -0
- data/lib/barometer/weather.rb +27 -27
- data/lib/barometer/weather_services/noaa.rb +314 -3
- data/lib/barometer/weather_services/service.rb +32 -30
- data/lib/barometer/weather_services/weather_bug.rb +35 -33
- data/lib/barometer/weather_services/wunderground.rb +31 -29
- data/lib/barometer/weather_services/yahoo.rb +36 -35
- data/lib/barometer/web_services/geocode.rb +5 -7
- data/lib/barometer/web_services/noaa_station_id.rb +53 -0
- data/lib/barometer/web_services/placemaker.rb +11 -13
- data/lib/barometer/web_services/timezone.rb +5 -7
- data/lib/barometer/web_services/weather_id.rb +4 -6
- data/lib/barometer/web_services/web_service.rb +4 -4
- data/spec/barometer_spec.rb +25 -27
- data/spec/cassettes/Barometer.json +1 -0
- data/spec/cassettes/Query.json +1 -0
- data/spec/cassettes/Query_Format_Coordinates.json +1 -0
- data/spec/cassettes/Query_Format_Geocode.json +1 -0
- data/spec/cassettes/Query_Format_WeatherID.json +1 -0
- data/spec/cassettes/Query_Format_WoeID.json +1 -0
- data/spec/cassettes/WeatherService.json +1 -0
- data/spec/cassettes/WeatherService_Noaa.json +1 -0
- data/spec/cassettes/WeatherService_WeatherBug.json +1 -0
- data/spec/cassettes/WeatherService_Wunderground.json +1 -0
- data/spec/cassettes/WeatherService_Yahoo.json +1 -0
- data/spec/cassettes/WebService_Geocode.json +1 -0
- data/spec/cassettes/WebService_NoaaStation.json +1 -0
- data/spec/data/distance_spec.rb +60 -60
- data/spec/data/geo_spec.rb +23 -23
- data/spec/data/local_datetime_spec.rb +44 -44
- data/spec/data/local_time_spec.rb +47 -47
- data/spec/data/location_spec.rb +16 -16
- data/spec/data/pressure_spec.rb +61 -61
- data/spec/data/speed_spec.rb +69 -69
- data/spec/data/sun_spec.rb +25 -25
- data/spec/data/temperature_spec.rb +68 -68
- data/spec/data/units_spec.rb +21 -21
- data/spec/data/zone_spec.rb +35 -35
- data/spec/formats/coordinates_spec.rb +27 -27
- data/spec/formats/format_spec.rb +17 -25
- data/spec/formats/geocode_spec.rb +23 -31
- data/spec/formats/icao_spec.rb +26 -32
- data/spec/formats/postalcode_spec.rb +22 -28
- data/spec/formats/short_zipcode_spec.rb +20 -26
- data/spec/formats/weather_id_spec.rb +57 -67
- data/spec/formats/woe_id_spec.rb +59 -59
- data/spec/formats/zipcode_spec.rb +39 -47
- data/spec/key_file_parser_spec.rb +28 -0
- data/spec/measurements/measurement_spec.rb +79 -133
- data/spec/measurements/result_array_spec.rb +23 -38
- data/spec/measurements/result_spec.rb +100 -128
- data/spec/query_spec.rb +83 -100
- data/spec/spec_helper.rb +24 -6
- data/spec/weather_services/noaa_spec.rb +179 -0
- data/spec/weather_services/services_spec.rb +28 -36
- data/spec/weather_services/weather_bug_spec.rb +57 -77
- data/spec/weather_services/wunderground_spec.rb +36 -65
- data/spec/weather_services/yahoo_spec.rb +38 -60
- data/spec/weather_spec.rb +79 -79
- data/spec/web_services/geocode_spec.rb +7 -11
- data/spec/web_services/noaa_station_id_spec.rb +33 -0
- data/spec/web_services/placemaker_spec.rb +7 -12
- data/spec/web_services/web_services_spec.rb +3 -9
- metadata +214 -163
- data/VERSION.yml +0 -5
- data/lib/barometer/weather_services/google.rb +0 -142
- data/lib/barometer/weather_services/weather_dot_com.rb +0 -279
- data/spec/fakeweb_helper.rb +0 -179
- data/spec/fixtures/formats/weather_id/90210.xml +0 -7
- data/spec/fixtures/formats/weather_id/from_USGA0028.xml +0 -3
- data/spec/fixtures/formats/weather_id/ksfo.xml +0 -1
- data/spec/fixtures/formats/weather_id/manhattan.xml +0 -7
- data/spec/fixtures/formats/weather_id/new_york.xml +0 -1
- data/spec/fixtures/formats/weather_id/the_hills.xml +0 -1
- data/spec/fixtures/geocode/40_73_v3.json +0 -497
- data/spec/fixtures/geocode/90210_v3.json +0 -63
- data/spec/fixtures/geocode/T5B4M9_v3.json +0 -68
- data/spec/fixtures/geocode/atlanta_v3.json +0 -58
- data/spec/fixtures/geocode/calgary_ab_v3.json +0 -58
- data/spec/fixtures/geocode/ksfo_v3.json +0 -73
- data/spec/fixtures/geocode/newyork_ny_v3.json +0 -58
- data/spec/fixtures/services/google/calgary_ab.xml +0 -1
- data/spec/fixtures/services/placemaker/T5B4M9.xml +0 -65
- data/spec/fixtures/services/placemaker/atlanta.xml +0 -65
- data/spec/fixtures/services/placemaker/coords.xml +0 -65
- data/spec/fixtures/services/placemaker/ksfo.xml +0 -65
- data/spec/fixtures/services/placemaker/new_york.xml +0 -65
- data/spec/fixtures/services/placemaker/the_hills.xml +0 -65
- data/spec/fixtures/services/placemaker/w615702.xml +0 -47
- data/spec/fixtures/services/weather_bug/90210_current.xml +0 -93
- data/spec/fixtures/services/weather_bug/90210_forecast.xml +0 -76
- data/spec/fixtures/services/weather_dot_com/90210.xml +0 -1
- data/spec/fixtures/services/wunderground/current_calgary_ab.xml +0 -9
- data/spec/fixtures/services/wunderground/forecast_calgary_ab.xml +0 -13
- data/spec/fixtures/services/yahoo/90210.xml +0 -3
- data/spec/weather_services/google_spec.rb +0 -181
- data/spec/weather_services/weather_dot_com_spec.rb +0 -224
data/spec/spec_helper.rb
CHANGED
@@ -1,16 +1,34 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'rspec'
|
3
|
-
require 'mocha'
|
4
3
|
require 'cgi'
|
5
|
-
|
6
|
-
require
|
4
|
+
require 'pry'
|
5
|
+
require 'vcr'
|
6
|
+
require 'fakefs/spec_helpers'
|
7
7
|
|
8
8
|
$:.unshift((File.join(File.dirname(__FILE__), '..', 'lib')))
|
9
9
|
require 'barometer'
|
10
10
|
|
11
|
-
|
12
|
-
Barometer.
|
11
|
+
WEATHERBUG_CODE = Barometer::KeyFileParser.find(:weather_bug, :code) || 'weatherbug'
|
12
|
+
YAHOO_KEY = Barometer::KeyFileParser.find(:yahoo, :app_id) || 'yahoo'
|
13
|
+
downcased_weatherbug_code = WEATHERBUG_CODE.to_s
|
14
|
+
downcased_weatherbug_code[0] = WEATHERBUG_CODE.to_s[0..0].downcase
|
15
|
+
|
16
|
+
# Barometer.debug!
|
17
|
+
Barometer.yahoo_placemaker_app_id = 'placemaker'
|
18
|
+
|
19
|
+
VCR.configure do |config|
|
20
|
+
config.cassette_library_dir = 'spec/cassettes'
|
21
|
+
config.hook_into :webmock
|
22
|
+
config.default_cassette_options = { :record => :none, :serialize_with => :json }
|
23
|
+
|
24
|
+
config.filter_sensitive_data('WEATHERBUG_CODE') { WEATHERBUG_CODE.to_s }
|
25
|
+
config.filter_sensitive_data('WEATHERBUG_CODE') { downcased_weatherbug_code }
|
26
|
+
config.filter_sensitive_data('<YAHOO_KEY>') { YAHOO_KEY.to_s }
|
27
|
+
config.filter_sensitive_data('<PLACEMAKER_KEY>') { Barometer.yahoo_placemaker_app_id.to_s }
|
28
|
+
|
29
|
+
config.configure_rspec_metadata!
|
30
|
+
end
|
13
31
|
|
14
32
|
RSpec.configure do |config|
|
15
|
-
|
33
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
16
34
|
end
|
@@ -0,0 +1,179 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
include Barometer
|
3
|
+
|
4
|
+
describe Barometer::WeatherService::Noaa, :vcr => {
|
5
|
+
:cassette_name => "WeatherService::Noaa"
|
6
|
+
} do
|
7
|
+
before(:each) do
|
8
|
+
@accepted_formats = [:zipcode, :coordinates]
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "the class methods" do
|
12
|
+
it "defines accepted_formats" do
|
13
|
+
WeatherService::Noaa._accepted_formats.should == @accepted_formats
|
14
|
+
end
|
15
|
+
|
16
|
+
it "defines source_name" do
|
17
|
+
WeatherService::Noaa._source_name.should == :noaa
|
18
|
+
end
|
19
|
+
|
20
|
+
it "defines fetch_current" do
|
21
|
+
WeatherService::Noaa.respond_to?("_fetch_current").should be_true
|
22
|
+
end
|
23
|
+
|
24
|
+
it "defines fetch_forecast" do
|
25
|
+
WeatherService::Noaa.respond_to?("_fetch_forecast").should be_true
|
26
|
+
end
|
27
|
+
|
28
|
+
it "defines get_all" do
|
29
|
+
WeatherService::Noaa.respond_to?("_fetch").should be_true
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "acceptable countries" do
|
33
|
+
before(:each) do
|
34
|
+
@query = Barometer::Query.new("90210")
|
35
|
+
@measurement = Barometer::Measurement.new
|
36
|
+
end
|
37
|
+
|
38
|
+
it "accepts nil" do
|
39
|
+
@query.country_code = nil
|
40
|
+
WeatherService::Noaa._supports_country?(@query).should be_true
|
41
|
+
end
|
42
|
+
|
43
|
+
it "accepts blank" do
|
44
|
+
@query.country_code = ""
|
45
|
+
WeatherService::Noaa._supports_country?(@query).should be_true
|
46
|
+
end
|
47
|
+
|
48
|
+
it "accepts US" do
|
49
|
+
@query.country_code = "US"
|
50
|
+
WeatherService::Noaa._supports_country?(@query).should be_true
|
51
|
+
end
|
52
|
+
|
53
|
+
it "rejects other" do
|
54
|
+
@query.country_code = "CA"
|
55
|
+
WeatherService::Noaa._supports_country?(@query).should be_false
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe "building the current data" do
|
61
|
+
it "defines the build method" do
|
62
|
+
WeatherService::Noaa.respond_to?("_build_current").should be_true
|
63
|
+
end
|
64
|
+
|
65
|
+
it "requires Hash input" do
|
66
|
+
lambda { WeatherService::Noaa._build_current }.should raise_error(ArgumentError)
|
67
|
+
lambda { WeatherService::Noaa._build_current({}) }.should_not raise_error(ArgumentError)
|
68
|
+
end
|
69
|
+
|
70
|
+
it "returns Barometer::CurrentMeasurement object" do
|
71
|
+
current = WeatherService::Noaa._build_current({})
|
72
|
+
current.is_a?(Measurement::Result).should be_true
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe "building the forecast data" do
|
77
|
+
it "defines the build method" do
|
78
|
+
WeatherService::Noaa.respond_to?("_build_forecast").should be_true
|
79
|
+
end
|
80
|
+
|
81
|
+
it "requires Hash input" do
|
82
|
+
lambda { WeatherService::Noaa._build_forecast }.should raise_error(ArgumentError)
|
83
|
+
lambda { WeatherService::Noaa._build_forecast({}) }.should_not raise_error(ArgumentError)
|
84
|
+
end
|
85
|
+
|
86
|
+
it "returns Array object" do
|
87
|
+
current = WeatherService::Noaa._build_forecast({})
|
88
|
+
current.is_a?(Array).should be_true
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
describe "when measuring" do
|
93
|
+
before(:each) do
|
94
|
+
@query = Barometer::Query.new("90210")
|
95
|
+
@measurement = Barometer::Measurement.new
|
96
|
+
end
|
97
|
+
|
98
|
+
describe "all" do
|
99
|
+
it "responds to _measure" do
|
100
|
+
Barometer::WeatherService::Noaa.respond_to?("_measure").should be_true
|
101
|
+
end
|
102
|
+
|
103
|
+
it "requires a Barometer::Measurement object" do
|
104
|
+
lambda { Barometer::WeatherService::Noaa._measure(nil, @query) }.should raise_error(ArgumentError)
|
105
|
+
lambda { Barometer::WeatherService::Noaa._measure("invalid", @query) }.should raise_error(ArgumentError)
|
106
|
+
|
107
|
+
lambda { Barometer::WeatherService::Noaa._measure(@measurement, @query) }.should_not raise_error(ArgumentError)
|
108
|
+
end
|
109
|
+
|
110
|
+
it "requires a Barometer::Query query" do
|
111
|
+
lambda { Barometer::WeatherService::Noaa._measure }.should raise_error(ArgumentError)
|
112
|
+
lambda { Barometer::WeatherService::Noaa._measure(@measurement, 1) }.should raise_error(ArgumentError)
|
113
|
+
|
114
|
+
lambda { Barometer::WeatherService::Noaa._measure(@measurement, @query) }.should_not raise_error(ArgumentError)
|
115
|
+
end
|
116
|
+
|
117
|
+
it "returns a Barometer::Measurement object" do
|
118
|
+
result = Barometer::WeatherService::Noaa._measure(@measurement, @query)
|
119
|
+
result.is_a?(Barometer::Measurement).should be_true
|
120
|
+
result.current.is_a?(Barometer::Measurement::Result).should be_true
|
121
|
+
result.forecast.is_a?(Barometer::Measurement::ResultArray).should be_true
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
describe "overall data correctness" do
|
127
|
+
before(:each) do
|
128
|
+
@query = Barometer::Query.new("90210")
|
129
|
+
@measurement = Barometer::Measurement.new
|
130
|
+
end
|
131
|
+
|
132
|
+
it "should correctly build the data" do
|
133
|
+
result = WeatherService::Noaa._measure(@measurement, @query)
|
134
|
+
|
135
|
+
# build current
|
136
|
+
@measurement.current.humidity.to_s.should match(/^\d{0,2}$/i)
|
137
|
+
@measurement.current.condition.should match(/^[\w ]{2,}$/i)
|
138
|
+
@measurement.current.icon.to_s.should match(/^\w{1,4}$/i)
|
139
|
+
@measurement.current.temperature.to_s.should match(/^\d{1,3}[ ]?[cfCF]?$/i)
|
140
|
+
@measurement.current.dew_point.to_s.should match(/^\d{1,3}[ ]?[cfCF]?$/i)
|
141
|
+
@measurement.current.wind_chill.to_s.should match(/^\d{0,3}[ ]?[cfCF]?$/i)
|
142
|
+
@measurement.current.wind.to_s.should match(/^\d{1,3}[ ]?[a-zA-Z]{0,3}$/i)
|
143
|
+
@measurement.current.wind.direction.to_s.should match(/^[neswNESW][\w ]{3,}$/i)
|
144
|
+
@measurement.current.wind.degrees.to_s.should match(/^\d{1,3}$/i)
|
145
|
+
@measurement.current.pressure.to_s.should match(/^\d{1,4}[ ]?[a-zA-Z]{0,3}$/i)
|
146
|
+
|
147
|
+
# build station
|
148
|
+
@measurement.station.id.should == "KSMO"
|
149
|
+
@measurement.station.name.should == "Santa Monica Muni, CA"
|
150
|
+
@measurement.station.city.should == "Santa Monica Muni"
|
151
|
+
@measurement.station.state_code.should == "CA"
|
152
|
+
@measurement.station.country_code.should == "US"
|
153
|
+
@measurement.station.latitude.to_f.should == 34.03
|
154
|
+
@measurement.station.longitude.to_f.should == -118.45
|
155
|
+
|
156
|
+
# builds location
|
157
|
+
@measurement.location.city.should == "Santa Monica Muni"
|
158
|
+
@measurement.location.state_code.should == "CA"
|
159
|
+
@measurement.location.country_code.should == "US"
|
160
|
+
|
161
|
+
# builds forecasts
|
162
|
+
@measurement.forecast.size.should == 7
|
163
|
+
|
164
|
+
@measurement.forecast[0].valid_start_date.to_s.should match(/^\d{2,4}-\d{1,2}-\d{1,2}/i)
|
165
|
+
@measurement.forecast[0].valid_end_date.to_s.should match(/^\d{2,4}-\d{1,2}-\d{1,2}/i)
|
166
|
+
@measurement.forecast[0].condition.should match(/^[\w ]+$/i)
|
167
|
+
@measurement.forecast[0].icon.should match(/^[\w ]+$/i)
|
168
|
+
@measurement.forecast[0].high.f.to_s.should match(/^\d{1,3}[ ]?[cfCF]?$/i)
|
169
|
+
@measurement.forecast[0].low.f.to_s.should match(/^\d{1,3}[ ]?[cfCF]?$/i)
|
170
|
+
|
171
|
+
# builds local time
|
172
|
+
@measurement.measured_at.to_s.should match(/^\d{1,2}:\d{1,2}[ ]?[apmAPM]{0,2}$/i)
|
173
|
+
@measurement.current.current_at.to_s.should match(/^\d{1,2}:\d{1,2}[ ]?[apmAPM]{0,2}$/i)
|
174
|
+
|
175
|
+
# builds timezone
|
176
|
+
@measurement.timezone.code.should match(/(PDT|PST)/i)
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
@@ -1,56 +1,52 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
2
|
|
3
|
-
describe
|
4
|
-
|
3
|
+
describe Barometer::WeatherService, :vcr => {
|
4
|
+
:cassette_name => "WeatherService"
|
5
|
+
} do
|
5
6
|
before(:each) do
|
6
7
|
query_term = "Calgary,AB"
|
7
8
|
@query = Barometer::Query.new(query_term)
|
8
9
|
@service = Barometer::WeatherService.source(:wunderground)
|
9
10
|
@time = Time.now
|
10
11
|
end
|
11
|
-
|
12
|
+
|
12
13
|
describe "and the class method" do
|
13
|
-
|
14
14
|
describe "source" do
|
15
|
-
|
16
15
|
it "responds" do
|
17
16
|
Barometer::WeatherService.respond_to?("source").should be_true
|
18
17
|
end
|
19
|
-
|
18
|
+
|
20
19
|
it "requires a Symbol or String" do
|
21
20
|
lambda { Barometer::WeatherService.source }.should raise_error(ArgumentError)
|
22
21
|
lambda { Barometer::WeatherService.source(1) }.should raise_error(ArgumentError)
|
23
|
-
|
22
|
+
|
24
23
|
lambda { Barometer::WeatherService.source("wunderground") }.should_not raise_error(ArgumentError)
|
25
24
|
lambda { Barometer::WeatherService.source(:wunderground) }.should_not raise_error(ArgumentError)
|
26
25
|
end
|
27
|
-
|
26
|
+
|
28
27
|
it "raises an error if source doesn't exist" do
|
29
28
|
lambda { Barometer::WeatherService.source(:not_valid) }.should raise_error(ArgumentError)
|
30
29
|
lambda { Barometer::WeatherService.source(:wunderground) }.should_not raise_error(ArgumentError)
|
31
30
|
end
|
32
|
-
|
31
|
+
|
33
32
|
it "returns the corresponding Service object" do
|
34
33
|
Barometer::WeatherService.source(:wunderground).should == Barometer::WeatherService::Wunderground
|
35
34
|
Barometer::WeatherService.source(:wunderground).superclass.should == Barometer::WeatherService
|
36
35
|
end
|
37
|
-
|
36
|
+
|
38
37
|
it "raises an error when retrieving the wrong class" do
|
39
38
|
lambda { Barometer::WeatherService.source(:temperature) }.should raise_error(ArgumentError)
|
40
39
|
end
|
41
|
-
|
42
40
|
end
|
43
|
-
|
44
41
|
end
|
45
|
-
|
42
|
+
|
46
43
|
describe "when initialized" do
|
47
|
-
|
48
44
|
before(:each) do
|
49
45
|
@service = Barometer::WeatherService.new
|
50
46
|
@measurement = Barometer::Measurement.new
|
51
47
|
@query = Barometer::Query.new("test")
|
52
48
|
end
|
53
|
-
|
49
|
+
|
54
50
|
it "defaults _meets_requirements?" do
|
55
51
|
Barometer::WeatherService.send("_meets_requirements?").should be_true
|
56
52
|
end
|
@@ -62,82 +58,78 @@ describe "WeatherServices" do
|
|
62
58
|
it "stubs _accepted_formats" do
|
63
59
|
lambda { Barometer::WeatherService.send("_accepted_formats") }.should raise_error(NotImplementedError)
|
64
60
|
end
|
65
|
-
|
61
|
+
|
66
62
|
it "stubs _measure" do
|
67
63
|
Barometer::WeatherService._measure(@measurement,@query,true).is_a?(Barometer::Measurement).should be_true
|
68
64
|
end
|
69
|
-
|
65
|
+
|
70
66
|
it "stubs _build_extra" do
|
71
67
|
Barometer::WeatherService._build_extra.should be_nil
|
72
68
|
end
|
73
|
-
|
69
|
+
|
74
70
|
it "stubs _fetch" do
|
75
71
|
Barometer::WeatherService._fetch.should be_nil
|
76
72
|
end
|
77
|
-
|
73
|
+
|
78
74
|
it "stubs _build_current" do
|
79
75
|
Barometer::WeatherService._build_current.should be_nil
|
80
76
|
end
|
81
|
-
|
77
|
+
|
82
78
|
it "stubs _build_forecast" do
|
83
79
|
Barometer::WeatherService._build_forecast.should be_nil
|
84
80
|
end
|
85
|
-
|
81
|
+
|
86
82
|
it "stubs _build_location" do
|
87
83
|
Barometer::WeatherService._build_location.should be_nil
|
88
84
|
end
|
89
|
-
|
85
|
+
|
90
86
|
it "stubs _build_sun" do
|
91
87
|
Barometer::WeatherService._build_sun.should be_nil
|
92
88
|
end
|
93
|
-
|
89
|
+
|
94
90
|
it "stubs _build_links" do
|
95
91
|
Barometer::WeatherService._build_links.should == {}
|
96
92
|
end
|
97
|
-
|
93
|
+
|
98
94
|
it "defaults _supports_country?" do
|
99
95
|
Barometer::WeatherService._supports_country?.should be_true
|
100
96
|
end
|
101
|
-
|
97
|
+
|
102
98
|
it "defaults _requires_keys?" do
|
103
99
|
Barometer::WeatherService._requires_keys?.should be_false
|
104
100
|
end
|
105
|
-
|
101
|
+
|
106
102
|
it "defaults _has_keys?" do
|
107
103
|
lambda { Barometer::WeatherService._has_keys? }.should raise_error(NotImplementedError)
|
108
104
|
end
|
109
|
-
|
110
105
|
end
|
111
|
-
|
106
|
+
|
112
107
|
describe "when measuring," do
|
113
|
-
|
114
108
|
it "responds to measure" do
|
115
109
|
Barometer::WeatherService.respond_to?("measure").should be_true
|
116
110
|
end
|
117
|
-
|
111
|
+
|
118
112
|
# since Barometer::WeatherService defines the measure method, you could actually just
|
119
113
|
# call Barometer::WeatherService.measure ... but this will not invoke a specific
|
120
114
|
# weather API driver. Make sure this usage raises an error.
|
121
115
|
it "requires an actuall driver" do
|
122
116
|
lambda { Barometer::WeatherService.measure(@query) }.should raise_error(NotImplementedError)
|
123
117
|
end
|
124
|
-
|
118
|
+
|
125
119
|
it "requires a Barometer::Query object" do
|
126
120
|
lambda { Barometer::WeatherService.measure("invalid") }.should raise_error(ArgumentError)
|
127
121
|
@query.is_a?(Barometer::Query).should be_true
|
128
122
|
lambda { Barometer::WeatherService.measure(@query) }.should_not raise_error(ArgumentError)
|
129
123
|
end
|
130
|
-
|
124
|
+
|
131
125
|
it "returns a Barometer::Measurement object" do
|
132
126
|
@service.measure(@query).is_a?(Barometer::Measurement).should be_true
|
133
127
|
end
|
134
|
-
|
128
|
+
|
135
129
|
it "returns current and future" do
|
136
130
|
measurement = @service.measure(@query)
|
137
131
|
measurement.current.is_a?(Barometer::Measurement::Result).should be_true
|
138
132
|
measurement.forecast.is_a?(Array).should be_true
|
139
133
|
end
|
140
|
-
|
141
134
|
end
|
142
|
-
|
143
|
-
end
|
135
|
+
end
|
@@ -1,178 +1,162 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
2
|
include Barometer
|
3
3
|
|
4
|
-
describe
|
5
|
-
|
4
|
+
describe Barometer::WeatherService::WeatherBug, :vcr => {
|
5
|
+
:cassette_name => "WeatherService::WeatherBug"
|
6
|
+
} do
|
6
7
|
before(:each) do
|
7
8
|
@accepted_formats = [:short_zipcode, :coordinates]
|
8
9
|
end
|
9
|
-
|
10
|
+
|
10
11
|
describe "the class methods" do
|
11
|
-
|
12
12
|
it "defines accepted_formats" do
|
13
13
|
WeatherService::WeatherBug._accepted_formats.should == @accepted_formats
|
14
14
|
end
|
15
|
-
|
15
|
+
|
16
16
|
it "defines source_name" do
|
17
17
|
WeatherService::WeatherBug._source_name.should == :weather_bug
|
18
18
|
end
|
19
|
-
|
19
|
+
|
20
20
|
it "defines fetch_current" do
|
21
21
|
WeatherService::WeatherBug.respond_to?("_fetch_current").should be_true
|
22
22
|
end
|
23
|
-
|
23
|
+
|
24
24
|
it "defines fetch_forecast" do
|
25
25
|
WeatherService::WeatherBug.respond_to?("_fetch_forecast").should be_true
|
26
26
|
end
|
27
|
-
|
27
|
+
|
28
28
|
it "defines _requires_keys?" do
|
29
29
|
WeatherService::WeatherBug.respond_to?("_requires_keys?").should be_true
|
30
30
|
WeatherService::WeatherBug._requires_keys?.should be_true
|
31
31
|
end
|
32
|
-
|
32
|
+
|
33
33
|
it "defines _has_keys?" do
|
34
34
|
WeatherService::WeatherBug.respond_to?("_has_keys?").should be_true
|
35
35
|
WeatherService::WeatherBug._has_keys?.should be_false
|
36
36
|
WeatherService::WeatherBug.keys = { :code => WEATHERBUG_CODE }
|
37
37
|
WeatherService::WeatherBug._has_keys?.should be_true
|
38
38
|
end
|
39
|
-
|
40
39
|
end
|
41
|
-
|
40
|
+
|
42
41
|
describe "building the current data" do
|
43
|
-
|
44
42
|
it "defines the build method" do
|
45
43
|
WeatherService::WeatherBug.respond_to?("_build_current").should be_true
|
46
44
|
end
|
47
|
-
|
45
|
+
|
48
46
|
it "requires Hash input" do
|
49
47
|
lambda { WeatherService::WeatherBug._build_current }.should raise_error(ArgumentError)
|
50
48
|
lambda { WeatherService::WeatherBug._build_current({}) }.should_not raise_error(ArgumentError)
|
51
49
|
end
|
52
|
-
|
50
|
+
|
53
51
|
it "returns Measurement::Current object" do
|
54
52
|
current = WeatherService::WeatherBug._build_current({})
|
55
53
|
current.is_a?(Measurement::Result).should be_true
|
56
54
|
end
|
57
|
-
|
58
55
|
end
|
59
|
-
|
56
|
+
|
60
57
|
describe "building the forecast data" do
|
61
|
-
|
62
58
|
it "defines the build method" do
|
63
59
|
WeatherService::WeatherBug.respond_to?("_build_forecast").should be_true
|
64
60
|
end
|
65
|
-
|
61
|
+
|
66
62
|
it "requires Hash input" do
|
67
63
|
lambda { WeatherService::WeatherBug._build_forecast }.should raise_error(ArgumentError)
|
68
64
|
lambda { WeatherService::WeatherBug._build_forecast({}) }.should_not raise_error(ArgumentError)
|
69
65
|
end
|
70
|
-
|
66
|
+
|
71
67
|
it "returns Array object" do
|
72
68
|
current = WeatherService::WeatherBug._build_forecast({})
|
73
69
|
current.is_a?(Array).should be_true
|
74
70
|
end
|
75
|
-
|
76
71
|
end
|
77
|
-
|
72
|
+
|
78
73
|
describe "building the location data" do
|
79
|
-
|
80
74
|
it "defines the build method" do
|
81
75
|
WeatherService::WeatherBug.respond_to?("_build_location").should be_true
|
82
76
|
end
|
83
|
-
|
77
|
+
|
84
78
|
it "requires Hash input" do
|
85
79
|
lambda { WeatherService::WeatherBug._build_location }.should raise_error(ArgumentError)
|
86
80
|
lambda { WeatherService::WeatherBug._build_location({}) }.should_not raise_error(ArgumentError)
|
87
81
|
end
|
88
|
-
|
82
|
+
|
89
83
|
it "requires Barometer::Geo input" do
|
90
84
|
geo = Data::Geo.new({})
|
91
85
|
lambda { WeatherService::WeatherBug._build_location({}, {}) }.should raise_error(ArgumentError)
|
92
86
|
lambda { WeatherService::WeatherBug._build_location({}, geo) }.should_not raise_error(ArgumentError)
|
93
87
|
end
|
94
|
-
|
88
|
+
|
95
89
|
it "returns Barometer::Location object" do
|
96
90
|
location = WeatherService::WeatherBug._build_location({})
|
97
91
|
location.is_a?(Data::Location).should be_true
|
98
92
|
end
|
99
|
-
|
100
93
|
end
|
101
|
-
|
94
|
+
|
102
95
|
describe "building the sun data" do
|
103
|
-
|
104
96
|
it "defines the build method" do
|
105
97
|
WeatherService::WeatherBug.respond_to?("_build_sun").should be_true
|
106
98
|
end
|
107
|
-
|
99
|
+
|
108
100
|
it "requires Hash input" do
|
109
101
|
lambda { WeatherService::WeatherBug._build_sun }.should raise_error(ArgumentError)
|
110
102
|
lambda { WeatherService::WeatherBug._build_sun({}) }.should_not raise_error(ArgumentError)
|
111
103
|
end
|
112
|
-
|
104
|
+
|
113
105
|
it "returns Barometer::Sun object" do
|
114
106
|
sun = WeatherService::WeatherBug._build_sun({})
|
115
107
|
sun.is_a?(Data::Sun).should be_true
|
116
108
|
end
|
117
|
-
|
118
109
|
end
|
119
|
-
|
110
|
+
|
120
111
|
describe "builds other data" do
|
121
|
-
|
122
112
|
it "defines _build_extra" do
|
123
113
|
WeatherService::WeatherBug.respond_to?("_build_extra").should be_true
|
124
114
|
end
|
125
|
-
|
115
|
+
|
126
116
|
it "defines _parse_local_time" do
|
127
117
|
WeatherService::WeatherBug.respond_to?("_parse_local_time").should be_true
|
128
118
|
end
|
129
|
-
|
119
|
+
|
130
120
|
it "defines _build_timezone" do
|
131
121
|
WeatherService::WeatherBug.respond_to?("_build_timezone").should be_true
|
132
122
|
end
|
133
|
-
|
134
123
|
end
|
135
124
|
|
136
125
|
describe "when measuring" do
|
137
|
-
|
138
126
|
before(:each) do
|
139
127
|
@query = Barometer::Query.new("90210")
|
140
128
|
@measurement = Barometer::Measurement.new
|
141
129
|
end
|
142
|
-
|
130
|
+
|
143
131
|
describe "all" do
|
144
|
-
|
145
132
|
it "responds to _measure" do
|
146
133
|
WeatherService::WeatherBug.respond_to?("_measure").should be_true
|
147
134
|
end
|
148
|
-
|
135
|
+
|
149
136
|
it "requires a Barometer::Measurement object" do
|
150
137
|
lambda { WeatherService::WeatherBug._measure(nil, @query) }.should raise_error(ArgumentError)
|
151
138
|
lambda { WeatherService::WeatherBug._measure("invalid", @query) }.should raise_error(ArgumentError)
|
152
139
|
|
153
140
|
lambda { WeatherService::WeatherBug._measure(@measurement, @query) }.should_not raise_error(ArgumentError)
|
154
141
|
end
|
155
|
-
|
142
|
+
|
156
143
|
it "requires a Barometer::Query query" do
|
157
144
|
lambda { WeatherService::WeatherBug._measure }.should raise_error(ArgumentError)
|
158
145
|
lambda { WeatherService::WeatherBug._measure(@measurement, 1) }.should raise_error(ArgumentError)
|
159
|
-
|
146
|
+
|
160
147
|
lambda { WeatherService::WeatherBug._measure(@measurement, @query) }.should_not raise_error(ArgumentError)
|
161
148
|
end
|
162
|
-
|
149
|
+
|
163
150
|
it "returns a Barometer::Measurement object" do
|
164
151
|
result = WeatherService::WeatherBug._measure(@measurement, @query)
|
165
152
|
result.is_a?(Barometer::Measurement).should be_true
|
166
153
|
result.current.is_a?(Measurement::Result).should be_true
|
167
154
|
result.forecast.is_a?(Measurement::ResultArray).should be_true
|
168
155
|
end
|
169
|
-
|
170
156
|
end
|
171
|
-
|
172
157
|
end
|
173
|
-
|
174
|
-
describe "overall data correctness" do
|
175
158
|
|
159
|
+
describe "overall data correctness" do
|
176
160
|
before(:each) do
|
177
161
|
@query = Barometer::Query.new("90210")
|
178
162
|
@measurement = Barometer::Measurement.new
|
@@ -182,20 +166,20 @@ describe "WeatherBug" do
|
|
182
166
|
result = WeatherService::WeatherBug._measure(@measurement, @query)
|
183
167
|
|
184
168
|
# build current
|
185
|
-
@measurement.current.humidity.
|
186
|
-
@measurement.current.condition.should
|
187
|
-
@measurement.current.icon.should
|
188
|
-
@measurement.current.temperature.
|
189
|
-
@measurement.current.dew_point.
|
190
|
-
@measurement.current.wind_chill.
|
191
|
-
@measurement.current.wind.
|
192
|
-
@measurement.current.wind.direction.should
|
193
|
-
@measurement.current.pressure.
|
169
|
+
@measurement.current.humidity.to_s.should match(/^\d{1,2}$/i)
|
170
|
+
@measurement.current.condition.should match(/^[\w ]+$/i)
|
171
|
+
@measurement.current.icon.to_s.should match(/^\d{1,3}$/i)
|
172
|
+
@measurement.current.temperature.to_s.should match(/^\d{1,3}[ ]?[cfCF]?$/i)
|
173
|
+
@measurement.current.dew_point.to_s.should match(/^\d{1,3}[ ]?[cfCF]?$/i)
|
174
|
+
@measurement.current.wind_chill.to_s.should match(/^\d{1,3}[ ]?[cfCF]?$/i)
|
175
|
+
@measurement.current.wind.to_s.should match(/^\d{1,3}[ ]?[a-zA-Z]{0,3}$/i)
|
176
|
+
@measurement.current.wind.direction.to_s.should match(/^[neswNESW]{0,3}$/i)
|
177
|
+
@measurement.current.pressure.to_s.should match(/^\d{1,4}[ ]?[a-zA-Z]{0,3}$/i)
|
194
178
|
|
195
179
|
# build sun
|
196
|
-
@measurement.current.sun.rise.to_s.should
|
197
|
-
@measurement.current.sun.set.to_s.should
|
198
|
-
|
180
|
+
@measurement.current.sun.rise.to_s.should match(/^\d{1,2}:\d{1,2}[ ]?[apmAPM]{0,2}$/i)
|
181
|
+
@measurement.current.sun.set.to_s.should match(/^\d{1,2}:\d{1,2}[ ]?[apmAPM]{0,2}$/i)
|
182
|
+
|
199
183
|
# build station
|
200
184
|
@measurement.station.id.should == "LSNGN"
|
201
185
|
@measurement.station.name.should == "Alexander Hamilton Senior HS"
|
@@ -205,7 +189,7 @@ describe "WeatherBug" do
|
|
205
189
|
@measurement.station.zip_code.should == "90034"
|
206
190
|
@measurement.station.latitude.to_f.should == 34.0336112976074
|
207
191
|
@measurement.station.longitude.to_f.should == -118.389999389648
|
208
|
-
|
192
|
+
|
209
193
|
# builds location
|
210
194
|
@measurement.location.city.should == "Beverly Hills"
|
211
195
|
@measurement.location.state_code.should == "CA"
|
@@ -214,25 +198,21 @@ describe "WeatherBug" do
|
|
214
198
|
# builds forecasts
|
215
199
|
@measurement.forecast.size.should == 7
|
216
200
|
|
217
|
-
@measurement.forecast[0].date.should
|
218
|
-
@measurement.forecast[0].condition.should
|
219
|
-
@measurement.forecast[0].icon.should
|
220
|
-
@measurement.forecast[0].high.
|
221
|
-
@measurement.forecast[0].low.
|
201
|
+
@measurement.forecast[0].date.to_s.should match(/^\d{1,4}-\d{1,2}-\d{1,2}$/i)
|
202
|
+
@measurement.forecast[0].condition.should match(/^[\w ]+$/i)
|
203
|
+
@measurement.forecast[0].icon.to_s.should match(/^\d{1,3}$/i)
|
204
|
+
@measurement.forecast[0].high.to_s.should match(/^\d{1,3}[ ]?[cfCF]?$/i)
|
205
|
+
@measurement.forecast[0].low.to_s.should match(/^\d{1,3}[ ]?[cfCF]?$/i)
|
206
|
+
|
207
|
+
@measurement.forecast[0].sun.rise.to_s.should match(/^\d{1,2}:\d{1,2}[ ]?[apmAPM]{0,2}$/i)
|
208
|
+
@measurement.forecast[0].sun.set.to_s.should match(/^\d{1,2}:\d{1,2}[ ]?[apmAPM]{0,2}$/i)
|
222
209
|
|
223
|
-
@measurement.forecast[0].sun.rise.to_s.should == "05:42 am"
|
224
|
-
@measurement.forecast[0].sun.set.to_s.should == "08:00 pm"
|
225
|
-
|
226
210
|
# builds local time
|
227
|
-
@measurement.measured_at.to_s.should
|
228
|
-
@measurement.current.current_at.to_s.should
|
229
|
-
|
211
|
+
@measurement.measured_at.to_s.should match(/^\d{1,2}:\d{1,2}[ ]?[apmAPM]{0,2}$/i)
|
212
|
+
@measurement.current.current_at.to_s.should match(/^\d{1,2}:\d{1,2}[ ]?[apmAPM]{0,2}$/i)
|
213
|
+
|
230
214
|
# builds timezone
|
231
|
-
@measurement.timezone.code.should
|
232
|
-
@measurement.timezone.offset.should == Data::Zone.new("PDT").offset
|
233
|
-
@measurement.timezone.today.should == Data::Zone.new("PDT").today
|
215
|
+
@measurement.timezone.code.should match(/^P[DS]T$/i)
|
234
216
|
end
|
235
|
-
|
236
217
|
end
|
237
|
-
|
238
|
-
end
|
218
|
+
end
|