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.
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