barometer 0.3.2 → 0.5.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 (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