barometer 0.7.3 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (138) hide show
  1. data/.gitignore +1 -0
  2. data/.travis.yml +7 -0
  3. data/LICENSE +1 -1
  4. data/{README.rdoc → README.md} +124 -110
  5. data/Rakefile +1 -21
  6. data/TODO +8 -9
  7. data/barometer.gemspec +20 -19
  8. data/bin/barometer +36 -83
  9. data/lib/barometer.rb +13 -11
  10. data/lib/barometer/base.rb +10 -10
  11. data/lib/barometer/data.rb +1 -1
  12. data/lib/barometer/data/distance.rb +25 -25
  13. data/lib/barometer/data/geo.rb +9 -9
  14. data/lib/barometer/data/local_datetime.rb +24 -20
  15. data/lib/barometer/data/local_time.rb +13 -13
  16. data/lib/barometer/data/location.rb +6 -6
  17. data/lib/barometer/data/pressure.rb +24 -24
  18. data/lib/barometer/data/speed.rb +28 -28
  19. data/lib/barometer/data/sun.rb +7 -7
  20. data/lib/barometer/data/temperature.rb +29 -29
  21. data/lib/barometer/data/units.rb +9 -9
  22. data/lib/barometer/data/zone.rb +19 -19
  23. data/lib/barometer/formats.rb +1 -1
  24. data/lib/barometer/formats/coordinates.rb +7 -7
  25. data/lib/barometer/formats/format.rb +6 -6
  26. data/lib/barometer/formats/geocode.rb +5 -5
  27. data/lib/barometer/formats/icao.rb +6 -6
  28. data/lib/barometer/formats/postalcode.rb +3 -3
  29. data/lib/barometer/formats/short_zipcode.rb +2 -2
  30. data/lib/barometer/formats/weather_id.rb +10 -10
  31. data/lib/barometer/formats/woe_id.rb +20 -20
  32. data/lib/barometer/formats/zipcode.rb +3 -3
  33. data/lib/barometer/key_file_parser.rb +20 -0
  34. data/lib/barometer/measurements/measurement.rb +32 -32
  35. data/lib/barometer/measurements/result.rb +39 -39
  36. data/lib/barometer/measurements/result_array.rb +12 -12
  37. data/lib/barometer/query.rb +15 -15
  38. data/lib/barometer/services.rb +3 -3
  39. data/lib/barometer/translations/icao_country_codes.yml +20 -20
  40. data/lib/barometer/translations/weather_country_codes.yml +1 -1
  41. data/lib/barometer/translations/zone_codes.yml +2 -2
  42. data/lib/barometer/version.rb +3 -0
  43. data/lib/barometer/weather.rb +27 -27
  44. data/lib/barometer/weather_services/noaa.rb +314 -3
  45. data/lib/barometer/weather_services/service.rb +32 -30
  46. data/lib/barometer/weather_services/weather_bug.rb +35 -33
  47. data/lib/barometer/weather_services/wunderground.rb +31 -29
  48. data/lib/barometer/weather_services/yahoo.rb +36 -35
  49. data/lib/barometer/web_services/geocode.rb +5 -7
  50. data/lib/barometer/web_services/noaa_station_id.rb +53 -0
  51. data/lib/barometer/web_services/placemaker.rb +11 -13
  52. data/lib/barometer/web_services/timezone.rb +5 -7
  53. data/lib/barometer/web_services/weather_id.rb +4 -6
  54. data/lib/barometer/web_services/web_service.rb +4 -4
  55. data/spec/barometer_spec.rb +25 -27
  56. data/spec/cassettes/Barometer.json +1 -0
  57. data/spec/cassettes/Query.json +1 -0
  58. data/spec/cassettes/Query_Format_Coordinates.json +1 -0
  59. data/spec/cassettes/Query_Format_Geocode.json +1 -0
  60. data/spec/cassettes/Query_Format_WeatherID.json +1 -0
  61. data/spec/cassettes/Query_Format_WoeID.json +1 -0
  62. data/spec/cassettes/WeatherService.json +1 -0
  63. data/spec/cassettes/WeatherService_Noaa.json +1 -0
  64. data/spec/cassettes/WeatherService_WeatherBug.json +1 -0
  65. data/spec/cassettes/WeatherService_Wunderground.json +1 -0
  66. data/spec/cassettes/WeatherService_Yahoo.json +1 -0
  67. data/spec/cassettes/WebService_Geocode.json +1 -0
  68. data/spec/cassettes/WebService_NoaaStation.json +1 -0
  69. data/spec/data/distance_spec.rb +60 -60
  70. data/spec/data/geo_spec.rb +23 -23
  71. data/spec/data/local_datetime_spec.rb +44 -44
  72. data/spec/data/local_time_spec.rb +47 -47
  73. data/spec/data/location_spec.rb +16 -16
  74. data/spec/data/pressure_spec.rb +61 -61
  75. data/spec/data/speed_spec.rb +69 -69
  76. data/spec/data/sun_spec.rb +25 -25
  77. data/spec/data/temperature_spec.rb +68 -68
  78. data/spec/data/units_spec.rb +21 -21
  79. data/spec/data/zone_spec.rb +35 -35
  80. data/spec/formats/coordinates_spec.rb +27 -27
  81. data/spec/formats/format_spec.rb +17 -25
  82. data/spec/formats/geocode_spec.rb +23 -31
  83. data/spec/formats/icao_spec.rb +26 -32
  84. data/spec/formats/postalcode_spec.rb +22 -28
  85. data/spec/formats/short_zipcode_spec.rb +20 -26
  86. data/spec/formats/weather_id_spec.rb +57 -67
  87. data/spec/formats/woe_id_spec.rb +59 -59
  88. data/spec/formats/zipcode_spec.rb +39 -47
  89. data/spec/key_file_parser_spec.rb +28 -0
  90. data/spec/measurements/measurement_spec.rb +79 -133
  91. data/spec/measurements/result_array_spec.rb +23 -38
  92. data/spec/measurements/result_spec.rb +100 -128
  93. data/spec/query_spec.rb +83 -100
  94. data/spec/spec_helper.rb +24 -6
  95. data/spec/weather_services/noaa_spec.rb +179 -0
  96. data/spec/weather_services/services_spec.rb +28 -36
  97. data/spec/weather_services/weather_bug_spec.rb +57 -77
  98. data/spec/weather_services/wunderground_spec.rb +36 -65
  99. data/spec/weather_services/yahoo_spec.rb +38 -60
  100. data/spec/weather_spec.rb +79 -79
  101. data/spec/web_services/geocode_spec.rb +7 -11
  102. data/spec/web_services/noaa_station_id_spec.rb +33 -0
  103. data/spec/web_services/placemaker_spec.rb +7 -12
  104. data/spec/web_services/web_services_spec.rb +3 -9
  105. metadata +214 -163
  106. data/VERSION.yml +0 -5
  107. data/lib/barometer/weather_services/google.rb +0 -142
  108. data/lib/barometer/weather_services/weather_dot_com.rb +0 -279
  109. data/spec/fakeweb_helper.rb +0 -179
  110. data/spec/fixtures/formats/weather_id/90210.xml +0 -7
  111. data/spec/fixtures/formats/weather_id/from_USGA0028.xml +0 -3
  112. data/spec/fixtures/formats/weather_id/ksfo.xml +0 -1
  113. data/spec/fixtures/formats/weather_id/manhattan.xml +0 -7
  114. data/spec/fixtures/formats/weather_id/new_york.xml +0 -1
  115. data/spec/fixtures/formats/weather_id/the_hills.xml +0 -1
  116. data/spec/fixtures/geocode/40_73_v3.json +0 -497
  117. data/spec/fixtures/geocode/90210_v3.json +0 -63
  118. data/spec/fixtures/geocode/T5B4M9_v3.json +0 -68
  119. data/spec/fixtures/geocode/atlanta_v3.json +0 -58
  120. data/spec/fixtures/geocode/calgary_ab_v3.json +0 -58
  121. data/spec/fixtures/geocode/ksfo_v3.json +0 -73
  122. data/spec/fixtures/geocode/newyork_ny_v3.json +0 -58
  123. data/spec/fixtures/services/google/calgary_ab.xml +0 -1
  124. data/spec/fixtures/services/placemaker/T5B4M9.xml +0 -65
  125. data/spec/fixtures/services/placemaker/atlanta.xml +0 -65
  126. data/spec/fixtures/services/placemaker/coords.xml +0 -65
  127. data/spec/fixtures/services/placemaker/ksfo.xml +0 -65
  128. data/spec/fixtures/services/placemaker/new_york.xml +0 -65
  129. data/spec/fixtures/services/placemaker/the_hills.xml +0 -65
  130. data/spec/fixtures/services/placemaker/w615702.xml +0 -47
  131. data/spec/fixtures/services/weather_bug/90210_current.xml +0 -93
  132. data/spec/fixtures/services/weather_bug/90210_forecast.xml +0 -76
  133. data/spec/fixtures/services/weather_dot_com/90210.xml +0 -1
  134. data/spec/fixtures/services/wunderground/current_calgary_ab.xml +0 -9
  135. data/spec/fixtures/services/wunderground/forecast_calgary_ab.xml +0 -13
  136. data/spec/fixtures/services/yahoo/90210.xml +0 -3
  137. data/spec/weather_services/google_spec.rb +0 -181
  138. 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 File.expand_path(File.dirname(__FILE__) + '/fakeweb_helper')
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
- #Barometer.debug!
12
- Barometer.yahoo_placemaker_app_id = "YAHOO"
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 "WeatherServices" do
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 "WeatherBug" do
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.to_i.should == 79
186
- @measurement.current.condition.should == "Sunny"
187
- @measurement.current.icon.should == "7"
188
- @measurement.current.temperature.to_i.should == 13
189
- @measurement.current.dew_point.to_i.should == 10
190
- @measurement.current.wind_chill.to_i.should == 14
191
- @measurement.current.wind.to_i.should == 0
192
- @measurement.current.wind.direction.should == "SE"
193
- @measurement.current.pressure.to_f.should == 1017.61
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 == "05:42 am"
197
- @measurement.current.sun.set.to_s.should == "08:00 pm"
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 == Date.parse("Jun 2 2011")
218
- @measurement.forecast[0].condition.should == "Sunny"
219
- @measurement.forecast[0].icon.should == "7"
220
- @measurement.forecast[0].high.to_i.should == 24
221
- @measurement.forecast[0].low.to_i.should == 11
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 == "07:01 am"
228
- @measurement.current.current_at.to_s.should == "07:01 am"
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 == Data::Zone.new("PDT").code
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