barometer 0.3.2 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (108) hide show
  1. data/README.rdoc +78 -70
  2. data/VERSION.yml +2 -2
  3. data/bin/barometer +100 -37
  4. data/lib/barometer.rb +12 -8
  5. data/lib/barometer/base.rb +48 -20
  6. data/lib/barometer/data.rb +5 -1
  7. data/lib/barometer/data/current.rb +23 -15
  8. data/lib/barometer/data/distance.rb +15 -5
  9. data/lib/barometer/data/forecast.rb +23 -5
  10. data/lib/barometer/data/geo.rb +16 -54
  11. data/lib/barometer/data/local_datetime.rb +137 -0
  12. data/lib/barometer/data/local_time.rb +134 -0
  13. data/lib/barometer/data/location.rb +6 -1
  14. data/lib/barometer/data/measurement.rb +71 -42
  15. data/lib/barometer/data/night.rb +69 -0
  16. data/lib/barometer/data/pressure.rb +15 -5
  17. data/lib/barometer/data/speed.rb +16 -5
  18. data/lib/barometer/data/sun.rb +8 -20
  19. data/lib/barometer/data/temperature.rb +22 -9
  20. data/lib/barometer/data/units.rb +10 -19
  21. data/lib/barometer/data/zone.rb +135 -9
  22. data/lib/barometer/formats.rb +12 -0
  23. data/lib/barometer/formats/coordinates.rb +42 -0
  24. data/lib/barometer/formats/format.rb +46 -0
  25. data/lib/barometer/formats/geocode.rb +51 -0
  26. data/lib/barometer/formats/icao.rb +37 -0
  27. data/lib/barometer/formats/postalcode.rb +22 -0
  28. data/lib/barometer/formats/short_zipcode.rb +17 -0
  29. data/lib/barometer/formats/weather_id.rb +107 -0
  30. data/lib/barometer/formats/zipcode.rb +31 -0
  31. data/lib/barometer/query.rb +61 -232
  32. data/lib/barometer/services.rb +14 -4
  33. data/lib/barometer/translations/icao_country_codes.yml +9 -0
  34. data/lib/barometer/translations/weather_country_codes.yml +17 -0
  35. data/lib/barometer/weather.rb +51 -30
  36. data/lib/barometer/{services → weather_services}/google.rb +23 -26
  37. data/lib/barometer/weather_services/noaa.rb +6 -0
  38. data/lib/barometer/{services → weather_services}/service.rb +101 -92
  39. data/lib/barometer/weather_services/weather_bug.rb +6 -0
  40. data/lib/barometer/weather_services/weather_dot_com.rb +261 -0
  41. data/lib/barometer/{services → weather_services}/wunderground.rb +58 -76
  42. data/lib/barometer/{services → weather_services}/yahoo.rb +91 -121
  43. data/lib/barometer/web_services/geocode.rb +33 -0
  44. data/lib/barometer/web_services/weather_id.rb +37 -0
  45. data/lib/barometer/web_services/web_service.rb +32 -0
  46. data/lib/demometer/demometer.rb +31 -4
  47. data/lib/demometer/views/forecast.erb +20 -0
  48. data/lib/demometer/views/index.erb +10 -3
  49. data/lib/demometer/views/measurement.erb +8 -3
  50. data/lib/demometer/views/readme.erb +63 -24
  51. data/spec/barometer_spec.rb +18 -36
  52. data/spec/{data_current_spec.rb → data/current_spec.rb} +73 -49
  53. data/spec/{data_distance_spec.rb → data/distance_spec.rb} +30 -30
  54. data/spec/{data_forecast_spec.rb → data/forecast_spec.rb} +57 -15
  55. data/spec/data/geo_spec.rb +91 -0
  56. data/spec/data/local_datetime_spec.rb +269 -0
  57. data/spec/data/local_time_spec.rb +239 -0
  58. data/spec/{data_location_spec.rb → data/location_spec.rb} +12 -1
  59. data/spec/{data_measurement_spec.rb → data/measurement_spec.rb} +135 -66
  60. data/spec/data/night_measurement_spec.rb +136 -0
  61. data/spec/{data_pressure_spec.rb → data/pressure_spec.rb} +29 -29
  62. data/spec/{data_speed_spec.rb → data/speed_spec.rb} +30 -30
  63. data/spec/data/sun_spec.rb +49 -0
  64. data/spec/{data_temperature_spec.rb → data/temperature_spec.rb} +44 -44
  65. data/spec/{units_spec.rb → data/units_spec.rb} +6 -6
  66. data/spec/{data_zone_spec.rb → data/zone_spec.rb} +15 -15
  67. data/spec/fixtures/formats/weather_id/90210.xml +1 -0
  68. data/spec/fixtures/formats/weather_id/atlanta.xml +1 -0
  69. data/spec/fixtures/formats/weather_id/from_USGA0028.xml +1 -0
  70. data/spec/fixtures/formats/weather_id/new_york.xml +1 -0
  71. data/spec/fixtures/{geocode_40_73.xml → geocode/40_73.xml} +0 -0
  72. data/spec/fixtures/{geocode_90210.xml → geocode/90210.xml} +0 -0
  73. data/spec/fixtures/{geocode_T5B4M9.xml → geocode/T5B4M9.xml} +0 -0
  74. data/spec/fixtures/geocode/atlanta.xml +1 -0
  75. data/spec/fixtures/{geocode_calgary_ab.xml → geocode/calgary_ab.xml} +0 -0
  76. data/spec/fixtures/{geocode_ksfo.xml → geocode/ksfo.xml} +0 -0
  77. data/spec/fixtures/{geocode_newyork_ny.xml → geocode/newyork_ny.xml} +0 -0
  78. data/spec/fixtures/{google_calgary_ab.xml → services/google/calgary_ab.xml} +0 -0
  79. data/spec/fixtures/services/weather_dot_com/90210.xml +1 -0
  80. data/spec/fixtures/{current_calgary_ab.xml → services/wunderground/current_calgary_ab.xml} +0 -0
  81. data/spec/fixtures/{forecast_calgary_ab.xml → services/wunderground/forecast_calgary_ab.xml} +0 -0
  82. data/spec/fixtures/{yahoo_90210.xml → services/yahoo/90210.xml} +0 -0
  83. data/spec/formats/coordinates_spec.rb +158 -0
  84. data/spec/formats/format_spec.rb +73 -0
  85. data/spec/formats/geocode_spec.rb +179 -0
  86. data/spec/formats/icao_spec.rb +61 -0
  87. data/spec/formats/postalcode_spec.rb +59 -0
  88. data/spec/formats/short_zipcode_spec.rb +53 -0
  89. data/spec/formats/weather_id_spec.rb +191 -0
  90. data/spec/formats/zipcode_spec.rb +111 -0
  91. data/spec/query_spec.rb +261 -288
  92. data/spec/spec_helper.rb +128 -4
  93. data/spec/{service_google_spec.rb → weather_services/google_spec.rb} +46 -46
  94. data/spec/weather_services/services_spec.rb +1118 -0
  95. data/spec/weather_services/weather_dot_com_spec.rb +327 -0
  96. data/spec/weather_services/wunderground_spec.rb +332 -0
  97. data/spec/{service_yahoo_spec.rb → weather_services/yahoo_spec.rb} +65 -81
  98. data/spec/weather_spec.rb +73 -61
  99. data/spec/web_services/geocode_spec.rb +45 -0
  100. data/spec/web_services/web_services_spec.rb +26 -0
  101. metadata +88 -36
  102. data/lib/barometer/services/noaa.rb +0 -6
  103. data/lib/barometer/services/weather_bug.rb +0 -6
  104. data/lib/barometer/services/weather_dot_com.rb +0 -6
  105. data/spec/data_geo_spec.rb +0 -94
  106. data/spec/data_sun_spec.rb +0 -76
  107. data/spec/service_wunderground_spec.rb +0 -330
  108. data/spec/services_spec.rb +0 -1106
@@ -16,24 +16,148 @@ def geocode_google_key_message
16
16
  puts
17
17
  puts "Please update the key_file '#{KEY_FILE}' with your google api key"
18
18
  puts "example:"
19
- puts "geocode_google: YOUR_KEY_KERE"
19
+ puts "google: geocode: YOUR_KEY_KERE"
20
20
  puts
21
21
  end
22
22
 
23
23
  if File.exists?(KEY_FILE)
24
24
  keys = YAML.load_file(KEY_FILE)
25
- if keys["geocode_google"]
26
- KEY = keys["geocode_google"]
25
+ if keys["google"]
26
+ KEY = keys["google"]["geocode"]
27
27
  else
28
28
  geocode_google_key_message
29
29
  exit
30
30
  end
31
+ if keys["weather"]
32
+ WEATHER_PARTNER_KEY = keys["weather"]["partner"]
33
+ WEATHER_LICENSE_KEY = keys["weather"]["license"]
34
+ end
35
+
31
36
  else
32
- File.open(KEY_FILE, 'w') {|f| f << "geocode_google: YOUR_KEY_KERE" }
37
+ File.open(KEY_FILE, 'w') {|f| f << "google: geocode: YOUR_KEY_KERE" }
33
38
  geocode_google_key_message
34
39
  exit
35
40
  end
36
41
 
42
+
43
+ #
44
+ # for geocoding
45
+ #
46
+ geo_url = "http://maps.google.com/maps/geo?"
47
+ FakeWeb.register_uri(:get,
48
+ "#{geo_url}gl=US&q=90210&output=xml&key=#{KEY}",
49
+ :string => File.read(File.join(File.dirname(__FILE__),
50
+ 'fixtures/geocode',
51
+ '90210.xml')
52
+ )
53
+ )
54
+ FakeWeb.register_uri(:get,
55
+ "#{geo_url}gl=&q=#{CGI.escape("40.756054,-73.986951")}&output=xml&key=#{KEY}",
56
+ :string => File.read(File.join(File.dirname(__FILE__),
57
+ 'fixtures/geocode',
58
+ '40_73.xml')
59
+ )
60
+ )
61
+
62
+ # FakeWeb.register_uri(:get,
63
+ # "#{geo_url}gl=&q=90210&output=xml&key=#{KEY}",
64
+ # :string => File.read(File.join(File.dirname(__FILE__),
65
+ # 'fixtures/geocode',
66
+ # '90210.xml')
67
+ # )
68
+ # )
69
+ FakeWeb.register_uri(:get,
70
+ "#{geo_url}gl=&q=New%20York%2C%20NY&output=xml&key=#{KEY}",
71
+ :string => File.read(File.join(File.dirname(__FILE__),
72
+ 'fixtures/geocode',
73
+ 'newyork_ny.xml')
74
+ )
75
+ )
76
+ FakeWeb.register_uri(:get,
77
+ "#{geo_url}gl=CA&key=#{@key}&output=xml&q=T5B%204M9",
78
+ :string => File.read(File.join(File.dirname(__FILE__),
79
+ 'fixtures/geocode',
80
+ 'T5B4M9.xml')
81
+ )
82
+ )
83
+
84
+ FakeWeb.register_uri(:get,
85
+ "#{geo_url}gl=&q=T5B%204M9&output=xml&key=#{KEY}",
86
+ :string => File.read(File.join(File.dirname(__FILE__),
87
+ 'fixtures/geocode',
88
+ 'T5B4M9.xml')
89
+ )
90
+ )
91
+ FakeWeb.register_uri(:get,
92
+ "#{geo_url}output=xml&q=T5B%204M9&gl=CA&key=#{KEY}",
93
+ :string => File.read(File.join(File.dirname(__FILE__),
94
+ 'fixtures/geocode',
95
+ 'T5B4M9.xml')
96
+ )
97
+ )
98
+ FakeWeb.register_uri(:get,
99
+ "#{geo_url}gl=US&q=KSFO&output=xml&key=#{KEY}",
100
+ :string => File.read(File.join(File.dirname(__FILE__),
101
+ 'fixtures/geocode',
102
+ 'ksfo.xml')
103
+ )
104
+ )
105
+ FakeWeb.register_uri(:get,
106
+ "#{geo_url}gl=&q=Atlanta%2C%20GA%2C%20US&output=xml&key=#{KEY}",
107
+ :string => File.read(File.join(File.dirname(__FILE__),
108
+ 'fixtures/geocode',
109
+ 'atlanta.xml')
110
+ )
111
+ )
112
+ FakeWeb.register_uri(:get,
113
+ "#{geo_url}output=xml&q=Atlanta%2C%20GA%2C%20US&gl=US&key=#{KEY}",
114
+ :string => File.read(File.join(File.dirname(__FILE__),
115
+ 'fixtures/geocode',
116
+ 'atlanta.xml')
117
+ )
118
+ )
119
+ #
120
+ # for weather.com searches
121
+ #
122
+ FakeWeb.register_uri(:get,
123
+ "http://xoap.weather.com:80/search/search?where=Beverly%20Hills%2C%20CA%2C%20USA",
124
+ :string => File.read(File.join(File.dirname(__FILE__),
125
+ 'fixtures/formats/weather_id',
126
+ '90210.xml')
127
+ )
128
+ )
129
+ FakeWeb.register_uri(:get,
130
+ "http://xoap.weather.com:80/search/search?where=New%20York%2C%20NY",
131
+ :string => File.read(File.join(File.dirname(__FILE__),
132
+ 'fixtures/formats/weather_id',
133
+ 'new_york.xml')
134
+ )
135
+ )
136
+ FakeWeb.register_uri(:get,
137
+ "http://xoap.weather.com:80/search/search?where=New%20York%2C%20NY%2C%20USA",
138
+ :string => File.read(File.join(File.dirname(__FILE__),
139
+ 'fixtures/formats/weather_id',
140
+ 'new_york.xml')
141
+ )
142
+ )
143
+ FakeWeb.register_uri(:get,
144
+ "http://xoap.weather.com:80/search/search?where=90210",
145
+ :string => File.read(File.join(File.dirname(__FILE__),
146
+ 'fixtures/formats/weather_id',
147
+ '90210.xml')
148
+ )
149
+ )
150
+ #
151
+ # for yahoo.com searches
152
+ #
153
+ FakeWeb.register_uri(:get,
154
+ "http://weather.yahooapis.com:80/forecastrss?p=USGA0028",
155
+ :string => File.read(File.join(File.dirname(__FILE__),
156
+ 'fixtures/formats/weather_id',
157
+ 'from_USGA0028.xml')
158
+ )
159
+ )
160
+
37
161
  Spec::Runner.configure do |config|
38
162
 
39
163
  end
@@ -1,4 +1,5 @@
1
1
  require 'spec_helper'
2
+ include Barometer
2
3
 
3
4
  describe "Google" do
4
5
 
@@ -10,7 +11,7 @@ describe "Google" do
10
11
  describe "the class methods" do
11
12
 
12
13
  it "defines accepted_formats" do
13
- Barometer::Google.accepted_formats.should == @accepted_formats
14
+ WeatherService::Google.accepted_formats.should == @accepted_formats
14
15
  end
15
16
 
16
17
  # it "defines base_uri" do
@@ -18,7 +19,7 @@ describe "Google" do
18
19
  # end
19
20
 
20
21
  it "defines get_all" do
21
- Barometer::Google.respond_to?("get_all").should be_true
22
+ WeatherService::Google.respond_to?("get_all").should be_true
22
23
  end
23
24
 
24
25
  end
@@ -26,17 +27,17 @@ describe "Google" do
26
27
  describe "building the current data" do
27
28
 
28
29
  it "defines the build method" do
29
- Barometer::Google.respond_to?("build_current").should be_true
30
+ WeatherService::Google.respond_to?("build_current").should be_true
30
31
  end
31
32
 
32
33
  it "requires Hash input" do
33
- lambda { Barometer::Google.build_current }.should raise_error(ArgumentError)
34
- lambda { Barometer::Google.build_current({}) }.should_not raise_error(ArgumentError)
34
+ lambda { WeatherService::Google.build_current }.should raise_error(ArgumentError)
35
+ lambda { WeatherService::Google.build_current({}) }.should_not raise_error(ArgumentError)
35
36
  end
36
37
 
37
38
  it "returns Barometer::CurrentMeasurement object" do
38
- current = Barometer::Google.build_current({})
39
- current.is_a?(Barometer::CurrentMeasurement).should be_true
39
+ current = WeatherService::Google.build_current({})
40
+ current.is_a?(Data::CurrentMeasurement).should be_true
40
41
  end
41
42
 
42
43
  end
@@ -44,16 +45,16 @@ describe "Google" do
44
45
  describe "building the forecast data" do
45
46
 
46
47
  it "defines the build method" do
47
- Barometer::Google.respond_to?("build_forecast").should be_true
48
+ WeatherService::Google.respond_to?("build_forecast").should be_true
48
49
  end
49
50
 
50
51
  it "requires Hash input" do
51
- lambda { Barometer::Google.build_forecast }.should raise_error(ArgumentError)
52
- lambda { Barometer::Google.build_forecast({}) }.should_not raise_error(ArgumentError)
52
+ lambda { WeatherService::Google.build_forecast }.should raise_error(ArgumentError)
53
+ lambda { WeatherService::Google.build_forecast({}) }.should_not raise_error(ArgumentError)
53
54
  end
54
55
 
55
56
  it "returns Array object" do
56
- current = Barometer::Google.build_forecast({})
57
+ current = WeatherService::Google.build_forecast({})
57
58
  current.is_a?(Array).should be_true
58
59
  end
59
60
 
@@ -62,19 +63,19 @@ describe "Google" do
62
63
  describe "building the location data" do
63
64
 
64
65
  it "defines the build method" do
65
- Barometer::Google.respond_to?("build_location").should be_true
66
+ WeatherService::Google.respond_to?("build_location").should be_true
66
67
  end
67
68
 
68
69
  it "requires Barometer::Geo input" do
69
- geo = Barometer::Geo.new({})
70
- lambda { Barometer::Google.build_location({}) }.should raise_error(ArgumentError)
71
- lambda { Barometer::Google.build_location(geo) }.should_not raise_error(ArgumentError)
70
+ geo = Data::Geo.new({})
71
+ lambda { WeatherService::Google.build_location({}) }.should raise_error(ArgumentError)
72
+ lambda { WeatherService::Google.build_location(geo) }.should_not raise_error(ArgumentError)
72
73
  end
73
74
 
74
75
  it "returns Barometer::Location object" do
75
- geo = Barometer::Geo.new({})
76
- location = Barometer::Google.build_location(geo)
77
- location.is_a?(Barometer::Location).should be_true
76
+ geo = Data::Geo.new({})
77
+ location = WeatherService::Google.build_location(geo)
78
+ location.is_a?(Data::Location).should be_true
78
79
  end
79
80
 
80
81
  end
@@ -96,14 +97,13 @@ describe "Google" do
96
97
 
97
98
  before(:each) do
98
99
  @query = Barometer::Query.new("Calgary,AB")
99
- @query.preferred = "Calgary,AB"
100
- @measurement = Barometer::Measurement.new
100
+ @measurement = Data::Measurement.new
101
101
 
102
102
  FakeWeb.register_uri(:get,
103
- "http://google.com/ig/api?weather=#{CGI.escape(@query.preferred)}&hl=en-GB",
103
+ "http://google.com/ig/api?weather=#{CGI.escape(@query.q)}&hl=en-GB",
104
104
  :string => File.read(File.join(File.dirname(__FILE__),
105
- 'fixtures',
106
- 'google_calgary_ab.xml')
105
+ '../fixtures/services/google',
106
+ 'calgary_ab.xml')
107
107
  )
108
108
  )
109
109
  end
@@ -111,27 +111,27 @@ describe "Google" do
111
111
  describe "all" do
112
112
 
113
113
  it "responds to _measure" do
114
- Barometer::Google.respond_to?("_measure").should be_true
114
+ Barometer::WeatherService::Google.respond_to?("_measure").should be_true
115
115
  end
116
116
 
117
117
  it "requires a Barometer::Measurement object" do
118
- lambda { Barometer::Google._measure(nil, @query) }.should raise_error(ArgumentError)
119
- lambda { Barometer::Google._measure("invlaid", @query) }.should raise_error(ArgumentError)
118
+ lambda { Barometer::WeatherService::Google._measure(nil, @query) }.should raise_error(ArgumentError)
119
+ lambda { Barometer::WeatherService::Google._measure("invlaid", @query) }.should raise_error(ArgumentError)
120
120
 
121
- lambda { Barometer::Google._measure(@measurement, @query) }.should_not raise_error(ArgumentError)
121
+ lambda { Barometer::WeatherService::Google._measure(@measurement, @query) }.should_not raise_error(ArgumentError)
122
122
  end
123
123
 
124
124
  it "requires a Barometer::Query query" do
125
- lambda { Barometer::Google._measure }.should raise_error(ArgumentError)
126
- lambda { Barometer::Google._measure(@measurement, 1) }.should raise_error(ArgumentError)
125
+ lambda { Barometer::WeatherService::Google._measure }.should raise_error(ArgumentError)
126
+ lambda { Barometer::WeatherService::Google._measure(@measurement, 1) }.should raise_error(ArgumentError)
127
127
 
128
- lambda { Barometer::Google._measure(@measurement, @query) }.should_not raise_error(ArgumentError)
128
+ lambda { Barometer::WeatherService::Google._measure(@measurement, @query) }.should_not raise_error(ArgumentError)
129
129
  end
130
130
 
131
131
  it "returns a Barometer::Measurement object" do
132
- result = Barometer::Google._measure(@measurement, @query)
133
- result.is_a?(Barometer::Measurement).should be_true
134
- result.current.is_a?(Barometer::CurrentMeasurement).should be_true
132
+ result = Barometer::WeatherService::Google._measure(@measurement, @query)
133
+ result.is_a?(Data::Measurement).should be_true
134
+ result.current.is_a?(Data::CurrentMeasurement).should be_true
135
135
  result.forecast.is_a?(Array).should be_true
136
136
 
137
137
  result.source.should == :google
@@ -144,25 +144,25 @@ describe "Google" do
144
144
  describe "when answering the simple questions," do
145
145
 
146
146
  before(:each) do
147
- @measurement = Barometer::Measurement.new
147
+ @measurement = Data::Measurement.new
148
148
  end
149
149
 
150
150
  describe "currently_wet_by_icon?" do
151
151
 
152
152
  before(:each) do
153
- @measurement.current = Barometer::CurrentMeasurement.new
153
+ @measurement.current = Data::CurrentMeasurement.new
154
154
  end
155
155
 
156
156
  it "returns true if matching icon code" do
157
157
  @measurement.current.icon = "rain"
158
158
  @measurement.current.icon?.should be_true
159
- Barometer::Google.currently_wet_by_icon?(@measurement.current).should be_true
159
+ WeatherService::Google.currently_wet_by_icon?(@measurement.current).should be_true
160
160
  end
161
161
 
162
162
  it "returns false if NO matching icon code" do
163
163
  @measurement.current.icon = "sunny"
164
164
  @measurement.current.icon?.should be_true
165
- Barometer::Google.currently_wet_by_icon?(@measurement.current).should be_false
165
+ WeatherService::Google.currently_wet_by_icon?(@measurement.current).should be_false
166
166
  end
167
167
 
168
168
  end
@@ -170,7 +170,7 @@ describe "Google" do
170
170
  describe "forecasted_wet_by_icon?" do
171
171
 
172
172
  before(:each) do
173
- @measurement.forecast = [Barometer::ForecastMeasurement.new]
173
+ @measurement.forecast = [Data::ForecastMeasurement.new]
174
174
  @measurement.forecast.first.date = Date.today
175
175
  @measurement.forecast.size.should == 1
176
176
  end
@@ -178,13 +178,13 @@ describe "Google" do
178
178
  it "returns true if matching icon code" do
179
179
  @measurement.forecast.first.icon = "rain"
180
180
  @measurement.forecast.first.icon?.should be_true
181
- Barometer::Google.forecasted_wet_by_icon?(@measurement.forecast.first).should be_true
181
+ WeatherService::Google.forecasted_wet_by_icon?(@measurement.forecast.first).should be_true
182
182
  end
183
183
 
184
184
  it "returns false if NO matching icon code" do
185
185
  @measurement.forecast.first.icon = "sunny"
186
186
  @measurement.forecast.first.icon?.should be_true
187
- Barometer::Google.forecasted_wet_by_icon?(@measurement.forecast.first).should be_false
187
+ WeatherService::Google.forecasted_wet_by_icon?(@measurement.forecast.first).should be_false
188
188
  end
189
189
 
190
190
  end
@@ -192,19 +192,19 @@ describe "Google" do
192
192
  describe "currently_sunny_by_icon?" do
193
193
 
194
194
  before(:each) do
195
- @measurement.current = Barometer::CurrentMeasurement.new
195
+ @measurement.current = Data::CurrentMeasurement.new
196
196
  end
197
197
 
198
198
  it "returns true if matching icon code" do
199
199
  @measurement.current.icon = "sunny"
200
200
  @measurement.current.icon?.should be_true
201
- Barometer::Google.currently_sunny_by_icon?(@measurement.current).should be_true
201
+ WeatherService::Google.currently_sunny_by_icon?(@measurement.current).should be_true
202
202
  end
203
203
 
204
204
  it "returns false if NO matching icon code" do
205
205
  @measurement.current.icon = "rain"
206
206
  @measurement.current.icon?.should be_true
207
- Barometer::Google.currently_sunny_by_icon?(@measurement.current).should be_false
207
+ WeatherService::Google.currently_sunny_by_icon?(@measurement.current).should be_false
208
208
  end
209
209
 
210
210
  end
@@ -212,7 +212,7 @@ describe "Google" do
212
212
  describe "forecasted_sunny_by_icon?" do
213
213
 
214
214
  before(:each) do
215
- @measurement.forecast = [Barometer::ForecastMeasurement.new]
215
+ @measurement.forecast = [Data::ForecastMeasurement.new]
216
216
  @measurement.forecast.first.date = Date.today
217
217
  @measurement.forecast.size.should == 1
218
218
  end
@@ -220,13 +220,13 @@ describe "Google" do
220
220
  it "returns true if matching icon code" do
221
221
  @measurement.forecast.first.icon = "sunny"
222
222
  @measurement.forecast.first.icon?.should be_true
223
- Barometer::Google.forecasted_sunny_by_icon?(@measurement.forecast.first).should be_true
223
+ WeatherService::Google.forecasted_sunny_by_icon?(@measurement.forecast.first).should be_true
224
224
  end
225
225
 
226
226
  it "returns false if NO matching icon code" do
227
227
  @measurement.forecast.first.icon = "rain"
228
228
  @measurement.forecast.first.icon?.should be_true
229
- Barometer::Google.forecasted_sunny_by_icon?(@measurement.forecast.first).should be_false
229
+ WeatherService::Google.forecasted_sunny_by_icon?(@measurement.forecast.first).should be_false
230
230
  end
231
231
 
232
232
  end
@@ -0,0 +1,1118 @@
1
+ require 'spec_helper'
2
+
3
+ describe "WeatherServices" do
4
+
5
+ before(:each) do
6
+ query_term = "Calgary,AB"
7
+ @query = Barometer::Query.new(query_term)
8
+ @service = Barometer::WeatherService.source(:wunderground)
9
+ @time = Time.now
10
+ end
11
+
12
+ describe "and the class method" do
13
+
14
+ describe "source" do
15
+
16
+ it "responds" do
17
+ Barometer::WeatherService.respond_to?("source").should be_true
18
+ end
19
+
20
+ it "requires a Symbol or String" do
21
+ lambda { Barometer::WeatherService.source }.should raise_error(ArgumentError)
22
+ lambda { Barometer::WeatherService.source(1) }.should raise_error(ArgumentError)
23
+
24
+ lambda { Barometer::WeatherService.source("wunderground") }.should_not raise_error(ArgumentError)
25
+ lambda { Barometer::WeatherService.source(:wunderground) }.should_not raise_error(ArgumentError)
26
+ end
27
+
28
+ it "raises an error if source doesn't exist" do
29
+ lambda { Barometer::WeatherService.source(:not_valid) }.should raise_error(ArgumentError)
30
+ lambda { Barometer::WeatherService.source(:wunderground) }.should_not raise_error(ArgumentError)
31
+ end
32
+
33
+ it "returns the corresponding Service object" do
34
+ Barometer::WeatherService.source(:wunderground).should == WeatherService::Wunderground
35
+ Barometer::WeatherService.source(:wunderground).superclass.should == Barometer::WeatherService
36
+ end
37
+
38
+ it "raises an error when retrieving the wrong class" do
39
+ lambda { Barometer::WeatherService.source(:temperature) }.should raise_error(ArgumentError)
40
+ end
41
+
42
+ end
43
+
44
+ end
45
+
46
+ describe "when initialized" do
47
+
48
+ before(:each) do
49
+ @service = Barometer::WeatherService.new
50
+ end
51
+
52
+ it "stubs _measure" do
53
+ lambda { Barometer::WeatherService._measure }.should raise_error(NotImplementedError)
54
+ end
55
+
56
+ it "stubs accepted_formats" do
57
+ lambda { Barometer::WeatherService.accepted_formats }.should raise_error(NotImplementedError)
58
+ end
59
+
60
+ it "defaults meets_requirements?" do
61
+ Barometer::WeatherService.meets_requirements?.should be_true
62
+ end
63
+
64
+ it "defaults supports_country?" do
65
+ Barometer::WeatherService.supports_country?.should be_true
66
+ end
67
+
68
+ it "defaults requires_keys?" do
69
+ Barometer::WeatherService.requires_keys?.should be_false
70
+ end
71
+
72
+ it "defaults has_keys?" do
73
+ lambda { Barometer::WeatherService.has_keys? }.should raise_error(NotImplementedError)
74
+ end
75
+
76
+ end
77
+
78
+ describe "when measuring," do
79
+
80
+ it "responds to measure" do
81
+ Barometer::WeatherService.respond_to?("measure").should be_true
82
+ end
83
+
84
+ # since Barometer::WeatherService defines the measure method, you could actuall just
85
+ # call Barometer::WeatherService.measure ... but this will not invoke a specific
86
+ # weather API driver. Make sure this usage raises an error.
87
+ it "requires an actuall driver" do
88
+ lambda { Barometer::WeatherService.measure(@query) }.should raise_error(NotImplementedError)
89
+ end
90
+
91
+ it "requires a Barometer::Query object" do
92
+ lambda { Barometer::WeatherService.measure("invalid") }.should raise_error(ArgumentError)
93
+ @query.is_a?(Barometer::Query).should be_true
94
+ lambda { Barometer::WeatherService.measure(@query) }.should_not raise_error(ArgumentError)
95
+ end
96
+
97
+ it "returns a Data::Measurement object" do
98
+ @service.measure(@query).is_a?(Data::Measurement).should be_true
99
+ end
100
+
101
+ it "returns current and future" do
102
+ measurement = @service.measure(@query)
103
+ measurement.current.is_a?(Data::CurrentMeasurement).should be_true
104
+ measurement.forecast.is_a?(Array).should be_true
105
+ end
106
+
107
+ end
108
+
109
+ describe "when answering the simple questions," do
110
+
111
+ before(:each) do
112
+ # the function being tested was monkey patched in an earlier test
113
+ # so the original file must be reloaded
114
+ load 'lib/barometer/weather_services/service.rb'
115
+
116
+ @measurement = Data::Measurement.new
117
+ @now = Data::LocalDateTime.parse("01-jan-2009 2:05 pm")
118
+ end
119
+
120
+ describe "windy?" do
121
+
122
+ it "requires a measurement object" do
123
+ lambda { Barometer::WeatherService.windy? }.should raise_error(ArgumentError)
124
+ lambda { Barometer::WeatherService.windy?("a") }.should raise_error(ArgumentError)
125
+ lambda { Barometer::WeatherService.windy?(@measurement) }.should_not raise_error(ArgumentError)
126
+ end
127
+
128
+ it "requires threshold as a number" do
129
+ lambda { Barometer::WeatherService.windy?(@measurement,"a") }.should raise_error(ArgumentError)
130
+ lambda { Barometer::WeatherService.windy?(@measurement,1) }.should_not raise_error(ArgumentError)
131
+ lambda { Barometer::WeatherService.windy?(@measurement,1.1) }.should_not raise_error(ArgumentError)
132
+ end
133
+
134
+ it "requires time as a Data::LocalTime object" do
135
+ #lambda { Barometer::WeatherService.windy?(@measurement,1,"a") }.should raise_error(ArgumentError)
136
+ lambda { Barometer::WeatherService.windy?(@measurement,1,@now) }.should_not raise_error(ArgumentError)
137
+ end
138
+
139
+ it "stubs forecasted_windy?" do
140
+ Barometer::WeatherService.forecasted_windy?(@measurement,nil,nil).should be_nil
141
+ end
142
+
143
+ describe "and is current" do
144
+
145
+ before(:each) do
146
+ module Barometer; class Data::Measurement
147
+ def current?(a=nil); true; end
148
+ end; end
149
+ end
150
+
151
+ it "returns nil" do
152
+ Barometer::WeatherService.windy?(@measurement).should be_nil
153
+ end
154
+
155
+ it "returns true if currently_windy?" do
156
+ module Barometer; class WeatherService
157
+ def self.currently_windy?(a=nil,b=nil); true; end
158
+ end; end
159
+ Barometer::WeatherService.windy?(@measurement).should be_true
160
+ end
161
+
162
+ it "returns false if !currently_windy?" do
163
+ module Barometer; class WeatherService
164
+ def self.currently_windy?(a=nil,b=nil); false; end
165
+ end; end
166
+ Barometer::WeatherService.windy?(@measurement).should be_false
167
+ end
168
+
169
+ end
170
+
171
+ describe "and is NOT current" do
172
+
173
+ before(:each) do
174
+ module Barometer; class Data::Measurement
175
+ def current?(a=nil); false; end
176
+ end; end
177
+ end
178
+
179
+ it "returns nil" do
180
+ Barometer::WeatherService.windy?(@measurement).should be_nil
181
+ end
182
+
183
+ it "returns true if forecasted_windy?" do
184
+ module Barometer; class WeatherService
185
+ def self.forecasted_windy?(a=nil,b=nil,c=nil); true; end
186
+ end; end
187
+ Barometer::WeatherService.windy?(@measurement).should be_true
188
+ end
189
+
190
+ it "returns false if !forecasted_windy?" do
191
+ module Barometer; class WeatherService
192
+ def self.forecasted_windy?(a=nil,b=nil,c=nil); false; end
193
+ end; end
194
+ Barometer::WeatherService.windy?(@measurement).should be_false
195
+ end
196
+
197
+ end
198
+
199
+ end
200
+
201
+ describe "currently_windy?" do
202
+
203
+ before(:each) do
204
+ # the function being tested was monkey patched in an earlier test
205
+ # so the original file must be reloaded
206
+ load 'lib/barometer/weather_services/service.rb'
207
+
208
+ @measurement = Data::Measurement.new
209
+ @threshold = 10
210
+ end
211
+
212
+ it "requires a measurement object" do
213
+ lambda { Barometer::WeatherService.currently_windy? }.should raise_error(ArgumentError)
214
+ lambda { Barometer::WeatherService.currently_windy?("a") }.should raise_error(ArgumentError)
215
+ lambda { Barometer::WeatherService.currently_windy?(@measurement) }.should_not raise_error(ArgumentError)
216
+ end
217
+
218
+ it "requires threshold as a number" do
219
+ lambda { Barometer::WeatherService.currently_windy?(@measurement,"a") }.should raise_error(ArgumentError)
220
+ lambda { Barometer::WeatherService.currently_windy?(@measurement,1) }.should_not raise_error(ArgumentError)
221
+ lambda { Barometer::WeatherService.currently_windy?(@measurement,1.1) }.should_not raise_error(ArgumentError)
222
+ end
223
+
224
+ it "returns nil when value unavailable" do
225
+ measurement = Data::Measurement.new
226
+ Barometer::WeatherService.currently_windy?(measurement,@threshold).should be_nil
227
+ measurement.current = Data::CurrentMeasurement.new
228
+ Barometer::WeatherService.currently_windy?(measurement,@threshold).should be_nil
229
+ measurement.current.wind = Data::Speed.new
230
+ Barometer::WeatherService.currently_windy?(measurement,@threshold).should be_nil
231
+ end
232
+
233
+ describe "when metric" do
234
+
235
+ before(:each) do
236
+ @measurement = Data::Measurement.new
237
+ @measurement.current = Data::CurrentMeasurement.new
238
+ @measurement.current.wind = Data::Speed.new
239
+ @measurement.metric!
240
+ @measurement.metric?.should be_true
241
+ end
242
+
243
+ # measurement.current.wind.kph.to_f
244
+ it "returns true when wind speed (kph) above threshold" do
245
+ @measurement.current.wind.kph = @threshold + 1
246
+ Barometer::WeatherService.currently_windy?(@measurement,@threshold).should be_true
247
+ end
248
+
249
+ it "returns false when wind speed (kph) below threshold" do
250
+ @measurement.current.wind.kph = @threshold - 1
251
+ Barometer::WeatherService.currently_windy?(@measurement,@threshold).should be_false
252
+ end
253
+
254
+ end
255
+
256
+ describe "when imperial" do
257
+
258
+ before(:each) do
259
+ @measurement = Data::Measurement.new
260
+ @measurement.current = Data::CurrentMeasurement.new
261
+ @measurement.current.wind = Data::Speed.new
262
+ @measurement.imperial!
263
+ @measurement.metric?.should be_false
264
+ end
265
+
266
+ it "returns true when wind speed (mph) above threshold" do
267
+ @measurement.current.wind.mph = @threshold - 1
268
+ Barometer::WeatherService.currently_windy?(@measurement,@threshold).should be_false
269
+ end
270
+
271
+ it "returns false when wind speed (mph) below threshold" do
272
+ @measurement.current.wind.mph = @threshold - 1
273
+ Barometer::WeatherService.currently_windy?(@measurement,@threshold).should be_false
274
+ end
275
+
276
+ end
277
+
278
+ end
279
+
280
+ describe "wet?" do
281
+
282
+ it "requires a measurement object" do
283
+ lambda { Barometer::WeatherService.wet? }.should raise_error(ArgumentError)
284
+ lambda { Barometer::WeatherService.wet?("a") }.should raise_error(ArgumentError)
285
+ lambda { Barometer::WeatherService.wet?(@measurement) }.should_not raise_error(ArgumentError)
286
+ end
287
+
288
+ it "requires threshold as a number" do
289
+ lambda { Barometer::WeatherService.wet?(@measurement,"a") }.should raise_error(ArgumentError)
290
+ lambda { Barometer::WeatherService.wet?(@measurement,1) }.should_not raise_error(ArgumentError)
291
+ lambda { Barometer::WeatherService.wet?(@measurement,1.1) }.should_not raise_error(ArgumentError)
292
+ end
293
+
294
+ it "requires time as a Data::LocalTime object" do
295
+ #lambda { Barometer::WeatherService.wet?(@measurement,1,"a") }.should raise_error(ArgumentError)
296
+ lambda { Barometer::WeatherService.wet?(@measurement,1,@now) }.should_not raise_error(ArgumentError)
297
+ end
298
+
299
+ describe "and is current" do
300
+
301
+ before(:each) do
302
+ module Barometer; class Data::Measurement
303
+ def current?(a=nil); true; end
304
+ end; end
305
+ end
306
+
307
+ it "returns nil" do
308
+ Barometer::WeatherService.wet?(@measurement).should be_nil
309
+ end
310
+
311
+ it "returns true if currently_wet?" do
312
+ module Barometer; class WeatherService
313
+ def self.currently_wet?(a=nil,b=nil); true; end
314
+ end; end
315
+ Barometer::WeatherService.wet?(@measurement).should be_true
316
+ end
317
+
318
+ it "returns false if !currently_wet?" do
319
+ module Barometer; class WeatherService
320
+ def self.currently_wet?(a=nil,b=nil); false; end
321
+ end; end
322
+ Barometer::WeatherService.wet?(@measurement).should be_false
323
+ end
324
+
325
+ end
326
+
327
+ describe "and is NOT current" do
328
+
329
+ before(:each) do
330
+ module Barometer; class Data::Measurement
331
+ def current?(a=nil); false; end
332
+ end; end
333
+ end
334
+
335
+ it "returns nil" do
336
+ Barometer::WeatherService.wet?(@measurement).should be_nil
337
+ end
338
+
339
+ it "returns true if forecasted_wet?" do
340
+ module Barometer; class WeatherService
341
+ def self.forecasted_wet?(a=nil,b=nil,c=nil); true; end
342
+ end; end
343
+ Barometer::WeatherService.wet?(@measurement).should be_true
344
+ end
345
+
346
+ it "returns false if !forecasted_wet?" do
347
+ module Barometer; class WeatherService
348
+ def self.forecasted_wet?(a=nil,b=nil,c=nil); false; end
349
+ end; end
350
+ Barometer::WeatherService.wet?(@measurement).should be_false
351
+ end
352
+
353
+ end
354
+
355
+ end
356
+
357
+ describe "currently_wet?" do
358
+
359
+ before(:each) do
360
+ # the function being tested was monkey patched in an earlier test
361
+ # so the original file must be reloaded
362
+ load 'lib/barometer/weather_services/service.rb'
363
+
364
+ @measurement = Data::Measurement.new
365
+ @threshold = 10
366
+ @temperature = 15
367
+ end
368
+
369
+ it "requires a measurement object" do
370
+ lambda { Barometer::WeatherService.currently_wet? }.should raise_error(ArgumentError)
371
+ lambda { Barometer::WeatherService.currently_wet?("a") }.should raise_error(ArgumentError)
372
+ lambda { Barometer::WeatherService.currently_wet?(@measurement) }.should_not raise_error(ArgumentError)
373
+ end
374
+
375
+ it "requires threshold as a number" do
376
+ lambda { Barometer::WeatherService.currently_wet?(@measurement,"a") }.should raise_error(ArgumentError)
377
+ lambda { Barometer::WeatherService.currently_wet?(@measurement,1) }.should_not raise_error(ArgumentError)
378
+ lambda { Barometer::WeatherService.currently_wet?(@measurement,1.1) }.should_not raise_error(ArgumentError)
379
+ end
380
+
381
+ it "returns nil when value unavailable" do
382
+ measurement = Data::Measurement.new
383
+ Barometer::WeatherService.currently_wet?(measurement,@threshold).should be_nil
384
+ measurement.current = Data::CurrentMeasurement.new
385
+ Barometer::WeatherService.currently_wet?(measurement,@threshold).should be_nil
386
+ measurement.current.wind = Data::Speed.new
387
+ Barometer::WeatherService.currently_wet?(measurement,@threshold).should be_nil
388
+ end
389
+
390
+ describe "currently_wet_by_icon?" do
391
+
392
+ before(:each) do
393
+ @measurement.current = Data::CurrentMeasurement.new
394
+ end
395
+
396
+ it "requires a Barometer::Measurement object" do
397
+ lambda { Barometer::WeatherService.currently_wet_by_icon?(nil) }.should raise_error(ArgumentError)
398
+ lambda { Barometer::WeatherService.currently_wet_by_icon?("invlaid") }.should raise_error(ArgumentError)
399
+
400
+ lambda { Barometer::WeatherService.currently_wet_by_icon?(@measurement.current) }.should_not raise_error(ArgumentError)
401
+ end
402
+
403
+ it "returns nil if no icon" do
404
+ @measurement.current.icon?.should be_false
405
+ Barometer::WeatherService.currently_wet_by_icon?(@measurement.current).should be_nil
406
+ end
407
+
408
+ it "returns true if matching icon code" do
409
+ module Barometer; class WeatherService; def self.wet_icon_codes
410
+ ["rain"]
411
+ end; end; end
412
+ @measurement.current.icon = "rain"
413
+ @measurement.current.icon?.should be_true
414
+ Barometer::WeatherService.currently_wet_by_icon?(@measurement.current).should be_true
415
+ end
416
+
417
+ it "returns false if NO matching icon code" do
418
+ module Barometer; class WeatherService; def self.wet_icon_codes
419
+ ["rain"]
420
+ end; end; end
421
+ @measurement.current.icon = "sunny"
422
+ @measurement.current.icon?.should be_true
423
+ Barometer::WeatherService.currently_wet_by_icon?(@measurement.current).should be_false
424
+ end
425
+
426
+ end
427
+
428
+ describe "and currently_wet_by_dewpoint?" do
429
+
430
+ describe "when metric" do
431
+
432
+ before(:each) do
433
+ @measurement = Data::Measurement.new
434
+ @measurement.current = Data::CurrentMeasurement.new
435
+ @measurement.current.temperature = Data::Temperature.new
436
+ @measurement.current.dew_point = Data::Temperature.new
437
+ @measurement.metric!
438
+ @measurement.metric?.should be_true
439
+ end
440
+
441
+ it "returns true when temperature < dew_point" do
442
+ @measurement.current.temperature.c = @temperature
443
+ @measurement.current.dew_point.c = @temperature + 1
444
+ Barometer::WeatherService.currently_wet_by_dewpoint?(@measurement).should be_true
445
+ end
446
+
447
+ it "returns false when temperature > dew_point" do
448
+ @measurement.current.temperature.c = @temperature
449
+ @measurement.current.dew_point.c = @temperature - 1
450
+ Barometer::WeatherService.currently_wet_by_dewpoint?(@measurement).should be_false
451
+ end
452
+
453
+ end
454
+
455
+ describe "when imperial" do
456
+
457
+ before(:each) do
458
+ @measurement = Data::Measurement.new
459
+ @measurement.current = Data::CurrentMeasurement.new
460
+ @measurement.current.temperature = Data::Temperature.new
461
+ @measurement.current.dew_point = Data::Temperature.new
462
+ @measurement.imperial!
463
+ @measurement.metric?.should be_false
464
+ end
465
+
466
+ it "returns true when temperature < dew_point" do
467
+ @measurement.current.temperature.f = @temperature
468
+ @measurement.current.dew_point.f = @temperature + 1
469
+ Barometer::WeatherService.currently_wet_by_dewpoint?(@measurement).should be_true
470
+ end
471
+
472
+ it "returns false when temperature > dew_point" do
473
+ @measurement.current.temperature.f = @temperature
474
+ @measurement.current.dew_point.f = @temperature - 1
475
+ Barometer::WeatherService.currently_wet_by_dewpoint?(@measurement).should be_false
476
+ end
477
+
478
+ end
479
+
480
+ end
481
+
482
+ describe "and currently_wet_by_humidity?" do
483
+
484
+ before(:each) do
485
+ @measurement = Data::Measurement.new
486
+ @measurement.current = Data::CurrentMeasurement.new
487
+ end
488
+
489
+ it "returns true when humidity >= 99%" do
490
+ @measurement.current.humidity = 99
491
+ Barometer::WeatherService.currently_wet_by_humidity?(@measurement.current).should be_true
492
+ @measurement.current.humidity = 100
493
+ Barometer::WeatherService.currently_wet_by_humidity?(@measurement.current).should be_true
494
+ end
495
+
496
+ it "returns false when humidity < 99%" do
497
+ @measurement.current.humidity = 98
498
+ Barometer::WeatherService.currently_wet_by_humidity?(@measurement.current).should be_false
499
+ end
500
+
501
+ end
502
+
503
+ describe "and currently_wet_by_pop?" do
504
+
505
+ before(:each) do
506
+ @measurement = Data::Measurement.new
507
+ @measurement.forecast = [Data::ForecastMeasurement.new]
508
+ @measurement.forecast.first.date = Date.today
509
+ @measurement.forecast.size.should == 1
510
+ end
511
+
512
+ it "returns true when pop (%) above threshold" do
513
+ @measurement.forecast.first.pop = @threshold + 1
514
+ Barometer::WeatherService.currently_wet_by_pop?(@measurement, @threshold).should be_true
515
+ end
516
+
517
+ it "returns false when pop (%) below threshold" do
518
+ @measurement.forecast.first.pop = @threshold - 1
519
+ Barometer::WeatherService.currently_wet_by_pop?(@measurement, @threshold).should be_false
520
+ end
521
+
522
+ end
523
+
524
+ end
525
+
526
+ describe "forecasted_wet?" do
527
+
528
+ before(:each) do
529
+ # the function being tested was monkey patched in an earlier test
530
+ # so the original file must be reloaded
531
+ load 'lib/barometer/weather_services/service.rb'
532
+
533
+ @measurement = Data::Measurement.new
534
+ @threshold = 10
535
+ @temperature = 15
536
+ end
537
+
538
+ it "requires a measurement object" do
539
+ lambda { Barometer::WeatherService.forecasted_wet? }.should raise_error(ArgumentError)
540
+ lambda { Barometer::WeatherService.forecasted_wet?("a") }.should raise_error(ArgumentError)
541
+ lambda { Barometer::WeatherService.forecasted_wet?(@measurement) }.should_not raise_error(ArgumentError)
542
+ end
543
+
544
+ it "requires threshold as a number" do
545
+ lambda { Barometer::WeatherService.forecasted_wet?(@measurement,"a") }.should raise_error(ArgumentError)
546
+ lambda { Barometer::WeatherService.forecasted_wet?(@measurement,1) }.should_not raise_error(ArgumentError)
547
+ lambda { Barometer::WeatherService.forecasted_wet?(@measurement,1.1) }.should_not raise_error(ArgumentError)
548
+ end
549
+
550
+ it "requires utc_time as a Data::LocalTime object" do
551
+ #lambda { Barometer::WeatherService.forecasted_wet?(@measurement,1,"string") }.should raise_error(ArgumentError)
552
+ lambda { Barometer::WeatherService.forecasted_wet?(@measurement,1,@now) }.should_not raise_error(ArgumentError)
553
+ end
554
+
555
+ it "returns nil when value unavailable" do
556
+ measurement = Data::Measurement.new
557
+ Barometer::WeatherService.forecasted_wet?(measurement,@threshold).should be_nil
558
+ measurement.forecast = [Data::ForecastMeasurement.new]
559
+ Barometer::WeatherService.forecasted_wet?(measurement,@threshold).should be_nil
560
+ end
561
+
562
+ describe "forecasted_wet_by_icon?" do
563
+
564
+ before(:each) do
565
+ @measurement.forecast = [Data::ForecastMeasurement.new]
566
+ @measurement.forecast.first.date = Date.today
567
+ @measurement.forecast.size.should == 1
568
+ end
569
+
570
+ it "requires a Barometer::Measurement object" do
571
+ lambda { Barometer::WeatherService.forecasted_wet_by_icon?(nil) }.should raise_error(ArgumentError)
572
+ lambda { Barometer::WeatherService.forecasted_wet_by_icon?("invlaid") }.should raise_error(ArgumentError)
573
+
574
+ lambda { Barometer::WeatherService.forecasted_wet_by_icon?(@measurement.forecast.first) }.should_not raise_error(ArgumentError)
575
+ end
576
+
577
+ it "returns nil if no icon" do
578
+ @measurement.forecast.first.icon?.should be_false
579
+ Barometer::WeatherService.forecasted_wet_by_icon?(@measurement.forecast.first).should be_nil
580
+ end
581
+
582
+ it "returns true if matching icon code" do
583
+ module Barometer; class WeatherService; def self.wet_icon_codes
584
+ ["rain"]
585
+ end; end; end
586
+ @measurement.forecast.first.icon = "rain"
587
+ @measurement.forecast.first.icon?.should be_true
588
+ Barometer::WeatherService.forecasted_wet_by_icon?(@measurement.forecast.first).should be_true
589
+ end
590
+
591
+ it "returns false if NO matching icon code" do
592
+ module Barometer; class WeatherService; def self.wet_icon_codes
593
+ ["rain"]
594
+ end; end; end
595
+ @measurement.forecast.first.icon = "sunny"
596
+ @measurement.forecast.first.icon?.should be_true
597
+ Barometer::WeatherService.forecasted_wet_by_icon?(@measurement.forecast.first).should be_false
598
+ end
599
+
600
+ after(:each) do
601
+ # the function being tested was monkey patched in an earlier test
602
+ # so the original file must be reloaded
603
+ load 'lib/barometer/weather_services/service.rb'
604
+ end
605
+
606
+ end
607
+
608
+ describe "and forecasted_wet_by_pop?" do
609
+
610
+ before(:each) do
611
+ @measurement = Data::Measurement.new
612
+ @measurement.forecast = [Data::ForecastMeasurement.new]
613
+ @measurement.forecast.first.date = Date.today
614
+ @measurement.forecast.size.should == 1
615
+ end
616
+
617
+ it "returns true when pop (%) above threshold" do
618
+ @measurement.forecast.first.pop = @threshold + 1
619
+ Barometer::WeatherService.forecasted_wet_by_pop?(@measurement.forecast.first, @threshold).should be_true
620
+ end
621
+
622
+ it "returns false when pop (%) below threshold" do
623
+ @measurement.forecast.first.pop = @threshold - 1
624
+ Barometer::WeatherService.forecasted_wet_by_pop?(@measurement.forecast.first, @threshold).should be_false
625
+ end
626
+
627
+ end
628
+
629
+ end
630
+
631
+ describe "day?" do
632
+
633
+ it "requires a measurement object" do
634
+ lambda { Barometer::WeatherService.day? }.should raise_error(ArgumentError)
635
+ lambda { Barometer::WeatherService.day?("a") }.should raise_error(ArgumentError)
636
+ lambda { Barometer::WeatherService.day?(@measurement) }.should_not raise_error(ArgumentError)
637
+ end
638
+
639
+ it "requires time as a Data::LocalTime object" do
640
+ #lambda { Barometer::WeatherService.day?(@measurement,"a") }.should raise_error(ArgumentError)
641
+ lambda { Barometer::WeatherService.day?(@measurement,@now) }.should_not raise_error(ArgumentError)
642
+ end
643
+
644
+ describe "and is current" do
645
+
646
+ before(:each) do
647
+ module Barometer; class Data::Measurement
648
+ def current?(a=nil); true; end
649
+ end; end
650
+ end
651
+
652
+ it "returns nil" do
653
+ Barometer::WeatherService.day?(@measurement).should be_nil
654
+ end
655
+
656
+ it "returns true if currently_day?" do
657
+ module Barometer; class WeatherService
658
+ def self.currently_day?(a=nil); true; end
659
+ end; end
660
+ Barometer::WeatherService.day?(@measurement).should be_true
661
+ end
662
+
663
+ it "returns false if !currently_day?" do
664
+ module Barometer; class WeatherService
665
+ def self.currently_day?(a=nil); false; end
666
+ end; end
667
+ Barometer::WeatherService.day?(@measurement).should be_false
668
+ end
669
+
670
+ end
671
+
672
+ describe "and is NOT current" do
673
+
674
+ before(:each) do
675
+ module Barometer; class Data::Measurement
676
+ def current?(a=nil); false; end
677
+ end; end
678
+ end
679
+
680
+ it "returns nil" do
681
+ Barometer::WeatherService.day?(@measurement).should be_nil
682
+ end
683
+
684
+ it "returns true if forecasted_day?" do
685
+ module Barometer; class WeatherService
686
+ def self.forecasted_day?(a=nil,b=nil); true; end
687
+ end; end
688
+ Barometer::WeatherService.day?(@measurement).should be_true
689
+ end
690
+
691
+ it "returns false if !forecasted_day?" do
692
+ module Barometer; class WeatherService
693
+ def self.forecasted_day?(a=nil,b=nil); false; end
694
+ end; end
695
+ Barometer::WeatherService.day?(@measurement).should be_false
696
+ end
697
+
698
+ end
699
+
700
+ end
701
+
702
+ describe "currently_day?" do
703
+
704
+ before(:each) do
705
+ # the function being tested was monkey patched in an earlier test
706
+ # so the original file must be reloaded
707
+ load 'lib/barometer/weather_services/service.rb'
708
+
709
+ @measurement = Data::Measurement.new
710
+ end
711
+
712
+ it "requires a measurement object" do
713
+ lambda { Barometer::WeatherService.currently_day? }.should raise_error(ArgumentError)
714
+ lambda { Barometer::WeatherService.currently_day?("a") }.should raise_error(ArgumentError)
715
+ lambda { Barometer::WeatherService.currently_day?(@measurement) }.should_not raise_error(ArgumentError)
716
+ end
717
+
718
+ it "returns nil when value unavailable" do
719
+ measurement = Data::Measurement.new
720
+ Barometer::WeatherService.currently_day?(measurement).should be_nil
721
+ end
722
+
723
+ describe "and currently_after_sunrise?" do
724
+
725
+ before(:each) do
726
+ @measurement = Data::CurrentMeasurement.new
727
+ @now = Data::LocalTime.parse("2:02 pm")
728
+ @past = @now - (60*60)
729
+ @future = @now + (60*60)
730
+ end
731
+
732
+ it "returns true when now is past sun_rise" do
733
+ @measurement.sun = Data::Sun.new(@past)
734
+ @measurement.current_at.should be_nil
735
+ Barometer::WeatherService.currently_after_sunrise?(@measurement).should be_nil
736
+
737
+ @measurement.current_at = @now
738
+ @measurement.current_at.should_not be_nil
739
+ Barometer::WeatherService.currently_after_sunrise?(@measurement).should be_true
740
+ end
741
+
742
+ it "returns false when now if before sun_rise" do
743
+ @measurement.sun = Data::Sun.new(@future)
744
+ @measurement.current_at.should be_nil
745
+ Barometer::WeatherService.currently_after_sunrise?(@measurement).should be_nil
746
+
747
+ @measurement.current_at = @now
748
+ @measurement.current_at.should_not be_nil
749
+ Barometer::WeatherService.currently_after_sunrise?(@measurement).should be_false
750
+ end
751
+
752
+ end
753
+
754
+ describe "and currently_before_sunset?" do
755
+
756
+ before(:each) do
757
+ @measurement = Data::CurrentMeasurement.new
758
+ @now = Data::LocalTime.parse("2:02 pm")
759
+ @past = @now - (60*60)
760
+ @future = @now + (60*60)
761
+ end
762
+
763
+ it "returns true when now is before sun_set" do
764
+ @measurement.sun = Data::Sun.new(nil,@future)
765
+ @measurement.current_at.should be_nil
766
+ Barometer::WeatherService.currently_before_sunset?(@measurement).should be_nil
767
+
768
+ @measurement.current_at = @now
769
+ @measurement.current_at.should_not be_nil
770
+ Barometer::WeatherService.currently_before_sunset?(@measurement).should be_true
771
+ end
772
+
773
+ it "returns false when now if after sun_set" do
774
+ @measurement.sun = Data::Sun.new(nil,@past)
775
+ @measurement.current_at.should be_nil
776
+ Barometer::WeatherService.currently_before_sunset?(@measurement).should be_nil
777
+
778
+ @measurement.current_at = @now
779
+ @measurement.current_at.should_not be_nil
780
+ Barometer::WeatherService.currently_before_sunset?(@measurement).should be_false
781
+ end
782
+
783
+ end
784
+
785
+ end
786
+
787
+ describe "forecasted_day?" do
788
+
789
+ before(:each) do
790
+ # the function being tested was monkey patched in an earlier test
791
+ # so the original file must be reloaded
792
+ load 'lib/barometer/weather_services/service.rb'
793
+
794
+ @measurement = Data::Measurement.new
795
+ end
796
+
797
+ it "requires a measurement object" do
798
+ lambda { Barometer::WeatherService.forecasted_day? }.should raise_error(ArgumentError)
799
+ lambda { Barometer::WeatherService.forecasted_day?("a") }.should raise_error(ArgumentError)
800
+ lambda { Barometer::WeatherService.forecasted_day?(@measurement) }.should_not raise_error(ArgumentError)
801
+ end
802
+
803
+ it "requires time as a Data::LocalTime object" do
804
+ #lambda { Barometer::WeatherService.forecasted_day?(@measurement,"a") }.should raise_error(ArgumentError)
805
+ lambda { Barometer::WeatherService.forecasted_day?(@measurement,@now) }.should_not raise_error(ArgumentError)
806
+ end
807
+
808
+ it "returns nil when value unavailable" do
809
+ measurement = Data::Measurement.new
810
+ Barometer::WeatherService.forecasted_day?(measurement).should be_nil
811
+ end
812
+
813
+ describe "and forecasted_after_sunrise?" do
814
+
815
+ before(:each) do
816
+ @measurement = Data::ForecastMeasurement.new
817
+ @now = Data::LocalDateTime.parse("2:02 pm")
818
+ @past = @now - (60*60)
819
+ @future = @now + (60*60)
820
+ end
821
+
822
+ it "returns true when now is past sun_rise" do
823
+ @measurement.sun = Data::Sun.new(@past)
824
+ Barometer::WeatherService.forecasted_after_sunrise?(@measurement, @now).should be_true
825
+ end
826
+
827
+ it "returns false when now if before sun_rise" do
828
+ @measurement.sun = Data::Sun.new(@future)
829
+ Barometer::WeatherService.forecasted_after_sunrise?(@measurement, @now).should be_false
830
+ end
831
+
832
+ end
833
+
834
+ describe "and forecasted_before_sunset?" do
835
+
836
+ before(:each) do
837
+ @measurement = Data::ForecastMeasurement.new
838
+ @now = Data::LocalDateTime.parse("2:02 pm")
839
+ @past = @now - (60*60)
840
+ @future = @now + (60*60)
841
+ end
842
+
843
+ it "returns true when now is before sun_set" do
844
+ @measurement.sun = Data::Sun.new(nil,@future)
845
+ Barometer::WeatherService.forecasted_before_sunset?(@measurement,@now).should be_true
846
+ end
847
+
848
+ it "returns false when now if after sun_set" do
849
+ @measurement.sun = Data::Sun.new(nil,@past)
850
+ Barometer::WeatherService.forecasted_before_sunset?(@measurement,@now).should be_false
851
+ end
852
+
853
+ end
854
+
855
+ end
856
+
857
+ describe "sunny?" do
858
+
859
+ it "requires a measurement object" do
860
+ lambda { Barometer::WeatherService.sunny? }.should raise_error(ArgumentError)
861
+ lambda { Barometer::WeatherService.sunny?("a") }.should raise_error(ArgumentError)
862
+ lambda { Barometer::WeatherService.sunny?(@measurement) }.should_not raise_error(ArgumentError)
863
+ end
864
+
865
+ it "requires time as a Data::LocalTime object" do
866
+ #lambda { Barometer::WeatherService.sunny?(@measurement,"a") }.should raise_error(ArgumentError)
867
+ lambda { Barometer::WeatherService.sunny?(@measurement,@now) }.should_not raise_error(ArgumentError)
868
+ end
869
+
870
+ it "draws attention to this spot to fix this test"
871
+ # it "returns false if night time" do
872
+ # @measurement.forecast = [Data::ForecastMeasurement.new]
873
+ # @measurement.forecast.size.should == 1
874
+ # @measurement.forecast[0].date = Date.today
875
+ # module Barometer; class WeatherService; def self.day?(a=nil, b=nil)
876
+ # true
877
+ # end; end; end
878
+ # Barometer::WeatherService.forecasted_sunny?(@measurement).should be_true
879
+ # module Barometer; class WeatherService; def self.day?(a=nil, b=nil)
880
+ # false
881
+ # end; end; end
882
+ # Barometer::WeatherService.forecasted_sunny?(@measurement).should be_false
883
+ # end
884
+
885
+ describe "and is current" do
886
+
887
+ before(:each) do
888
+ module Barometer; class Data::Measurement
889
+ def current?(a=nil); true; end
890
+ end; end
891
+ end
892
+
893
+ it "returns nil" do
894
+ Barometer::WeatherService.sunny?(@measurement).should be_nil
895
+ end
896
+
897
+ it "returns true if currently_sunny?" do
898
+ module Barometer; class WeatherService
899
+ def self.currently_sunny?(a=nil); true; end
900
+ end; end
901
+ Barometer::WeatherService.sunny?(@measurement).should be_true
902
+ end
903
+
904
+ it "returns false if !currently_sunny?" do
905
+ module Barometer; class WeatherService
906
+ def self.currently_sunny?(a=nil); false; end
907
+ end; end
908
+ Barometer::WeatherService.sunny?(@measurement).should be_false
909
+ end
910
+
911
+ end
912
+
913
+ describe "and is NOT current" do
914
+
915
+ before(:each) do
916
+ module Barometer; class Data::Measurement
917
+ def current?(a=nil); false; end
918
+ end; end
919
+ end
920
+
921
+ it "returns nil" do
922
+ Barometer::WeatherService.sunny?(@measurement).should be_nil
923
+ end
924
+
925
+ it "returns true if forecasted_sunny?" do
926
+ module Barometer; class WeatherService
927
+ def self.forecasted_sunny?(a=nil,b=nil); true; end
928
+ end; end
929
+ Barometer::WeatherService.sunny?(@measurement).should be_true
930
+ end
931
+
932
+ it "returns false if !forecasted_wet?" do
933
+ module Barometer; class WeatherService
934
+ def self.forecasted_sunny?(a=nil,b=nil); false; end
935
+ end; end
936
+ Barometer::WeatherService.sunny?(@measurement).should be_false
937
+ end
938
+
939
+ end
940
+
941
+ end
942
+
943
+ describe "currently_sunny?" do
944
+
945
+ before(:each) do
946
+ # the function being tested was monkey patched in an earlier test
947
+ # so the original file must be reloaded
948
+ load 'lib/barometer/weather_services/service.rb'
949
+
950
+ @measurement = Data::Measurement.new
951
+ end
952
+
953
+ it "requires a measurement object" do
954
+ lambda { Barometer::WeatherService.currently_sunny? }.should raise_error(ArgumentError)
955
+ lambda { Barometer::WeatherService.currently_sunny?("a") }.should raise_error(ArgumentError)
956
+ lambda { Barometer::WeatherService.currently_sunny?(@measurement) }.should_not raise_error(ArgumentError)
957
+ end
958
+
959
+ it "returns nil when value unavailable" do
960
+ measurement = Data::Measurement.new
961
+ Barometer::WeatherService.currently_sunny?(measurement).should be_nil
962
+ measurement.current = Data::CurrentMeasurement.new
963
+ Barometer::WeatherService.currently_sunny?(measurement).should be_nil
964
+ end
965
+
966
+ it "returns false if night time" do
967
+ @measurement.current = Data::CurrentMeasurement.new
968
+ module Barometer; class WeatherService; def self.currently_day?(a=nil)
969
+ true
970
+ end; end; end
971
+ module Barometer; class WeatherService; def self.currently_sunny_by_icon?(a=nil)
972
+ true
973
+ end; end; end
974
+ Barometer::WeatherService.currently_sunny?(@measurement).should be_true
975
+ module Barometer; class WeatherService; def self.currently_day?(a=nil)
976
+ false
977
+ end; end; end
978
+ Barometer::WeatherService.currently_sunny?(@measurement).should be_false
979
+ end
980
+
981
+ describe "currently_sunny_by_icon?" do
982
+
983
+ before(:each) do
984
+ @measurement.current = Data::CurrentMeasurement.new
985
+ end
986
+
987
+ it "requires a Barometer::Measurement object" do
988
+ lambda { Barometer::WeatherService.currently_sunny_by_icon?(nil) }.should raise_error(ArgumentError)
989
+ lambda { Barometer::WeatherService.currently_sunny_by_icon?("invlaid") }.should raise_error(ArgumentError)
990
+
991
+ lambda { Barometer::WeatherService.currently_sunny_by_icon?(@measurement.current) }.should_not raise_error(ArgumentError)
992
+ end
993
+
994
+ it "returns nil if no icon" do
995
+ @measurement.current.icon?.should be_false
996
+ Barometer::WeatherService.currently_sunny_by_icon?(@measurement.current).should be_nil
997
+ end
998
+
999
+ it "returns true if matching icon code" do
1000
+ module Barometer; class WeatherService; def self.sunny_icon_codes
1001
+ ["sunny"]
1002
+ end; end; end
1003
+ @measurement.current.icon = "sunny"
1004
+ @measurement.current.icon?.should be_true
1005
+ Barometer::WeatherService.currently_sunny_by_icon?(@measurement.current).should be_true
1006
+ end
1007
+
1008
+ it "returns false if NO matching icon code" do
1009
+ module Barometer; class WeatherService; def self.sunny_icon_codes
1010
+ ["sunny"]
1011
+ end; end; end
1012
+ @measurement.current.icon = "rain"
1013
+ @measurement.current.icon?.should be_true
1014
+ Barometer::WeatherService.currently_sunny_by_icon?(@measurement.current).should be_false
1015
+ end
1016
+
1017
+ end
1018
+
1019
+ end
1020
+
1021
+ describe "forecasted_sunny?" do
1022
+
1023
+ before(:each) do
1024
+ # the function being tested was monkey patched in an earlier test
1025
+ # so the original file must be reloaded
1026
+ load 'lib/barometer/weather_services/service.rb'
1027
+
1028
+ @measurement = Data::Measurement.new
1029
+ end
1030
+
1031
+ it "requires a measurement object" do
1032
+ lambda { Barometer::WeatherService.forecasted_sunny? }.should raise_error(ArgumentError)
1033
+ lambda { Barometer::WeatherService.forecasted_sunny?("a") }.should raise_error(ArgumentError)
1034
+ lambda { Barometer::WeatherService.forecasted_sunny?(@measurement) }.should_not raise_error(ArgumentError)
1035
+ end
1036
+
1037
+ it "requires utc_time as a Data::LocalTime object" do
1038
+ #lambda { Barometer::WeatherService.forecasted_sunny?(@measurement,"string") }.should raise_error(ArgumentError)
1039
+ lambda { Barometer::WeatherService.forecasted_sunny?(@measurement,@now) }.should_not raise_error(ArgumentError)
1040
+ end
1041
+
1042
+ it "returns nil when value unavailable" do
1043
+ measurement = Data::Measurement.new
1044
+ Barometer::WeatherService.forecasted_sunny?(measurement).should be_nil
1045
+ measurement.forecast = [Data::ForecastMeasurement.new]
1046
+ measurement.forecast.size.should == 1
1047
+ Barometer::WeatherService.forecasted_sunny?(measurement).should be_nil
1048
+ end
1049
+
1050
+ it "returns false if night time" do
1051
+ @measurement.forecast = [Data::ForecastMeasurement.new]
1052
+ @measurement.forecast.size.should == 1
1053
+ target_date = Date.today
1054
+ @measurement.forecast[0].date = target_date
1055
+ module Barometer; class WeatherService; def self.forecasted_day?(a=nil, b=nil)
1056
+ true
1057
+ end; end; end
1058
+ module Barometer; class WeatherService; def self.forecasted_sunny_by_icon?(a=nil, b=nil)
1059
+ true
1060
+ end; end; end
1061
+ Barometer::WeatherService.forecasted_sunny?(@measurement, target_date).should be_true
1062
+ module Barometer; class WeatherService; def self.forecasted_day?(a=nil, b=nil)
1063
+ false
1064
+ end; end; end
1065
+ Barometer::WeatherService.forecasted_sunny?(@measurement).should be_false
1066
+ end
1067
+
1068
+ describe "forecasted_sunny_by_icon?" do
1069
+
1070
+ before(:each) do
1071
+ @measurement.forecast = [Data::ForecastMeasurement.new]
1072
+ @measurement.forecast.first.date = Date.today
1073
+ @measurement.forecast.size.should == 1
1074
+ end
1075
+
1076
+ it "requires a Barometer::Measurement object" do
1077
+ lambda { Barometer::WeatherService.forecasted_sunny_by_icon?(nil) }.should raise_error(ArgumentError)
1078
+ lambda { Barometer::WeatherService.forecasted_sunny_by_icon?("invlaid") }.should raise_error(ArgumentError)
1079
+
1080
+ lambda { Barometer::WeatherService.forecasted_sunny_by_icon?(@measurement.forecast.first) }.should_not raise_error(ArgumentError)
1081
+ end
1082
+
1083
+ it "returns nil if no icon" do
1084
+ @measurement.forecast.first.icon?.should be_false
1085
+ Barometer::WeatherService.forecasted_sunny_by_icon?(@measurement.forecast.first).should be_nil
1086
+ end
1087
+
1088
+ it "returns true if matching icon code" do
1089
+ module Barometer; class WeatherService; def self.sunny_icon_codes
1090
+ ["sunny"]
1091
+ end; end; end
1092
+ @measurement.forecast.first.icon = "sunny"
1093
+ @measurement.forecast.first.icon?.should be_true
1094
+ Barometer::WeatherService.forecasted_sunny_by_icon?(@measurement.forecast.first).should be_true
1095
+ end
1096
+
1097
+ it "returns false if NO matching icon code" do
1098
+ module Barometer; class WeatherService; def self.sunny_icon_codes
1099
+ ["sunny"]
1100
+ end; end; end
1101
+ @measurement.forecast.first.icon = "rain"
1102
+ @measurement.forecast.first.icon?.should be_true
1103
+ Barometer::WeatherService.forecasted_sunny_by_icon?(@measurement.forecast.first).should be_false
1104
+ end
1105
+
1106
+ after(:each) do
1107
+ # the function being tested was monkey patched in an earlier test
1108
+ # so the original file must be reloaded
1109
+ load 'lib/barometer/weather_services/service.rb'
1110
+ end
1111
+
1112
+ end
1113
+
1114
+ end
1115
+
1116
+ end
1117
+
1118
+ end