barometer 0.7.3 → 0.8.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.
- 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
|