lita-forecast 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,34 @@
1
+ # -*- coding: UTF-8 -*-
2
+ require 'English'
3
+
4
+ $LOAD_PATH.unshift File.expand_path('../lib', __FILE__)
5
+
6
+ require 'lita-forecast/version'
7
+
8
+ Gem::Specification.new do |g|
9
+ g.name = 'lita-forecast'
10
+ g.version = LitaForecast::VERSION
11
+ g.date = Time.now.strftime('%Y-%m-%d')
12
+ g.description = 'Lita plugin for Forecast.io'
13
+ g.summary = 'Lita + Forecast.io'
14
+ g.authors = ['Tim Heckman']
15
+ g.email = 't@heckman.io'
16
+ g.homepage = 'https://github.com/theckman/lita_forecast'
17
+ g.license = 'MIT'
18
+
19
+ g.test_files = %x(git ls-files spec/*).split
20
+ g.files = %x(git ls-files).split
21
+
22
+ g.add_development_dependency 'bundler', '~> 1.5'
23
+ g.add_development_dependency 'rake', '~> 10.1.0'
24
+ g.add_development_dependency 'rubocop', '~> 0.19.1'
25
+ g.add_development_dependency 'rspec', '>= 3.0.0.beta2'
26
+ g.add_development_dependency 'fuubar', '~> 1.3.2'
27
+ g.add_development_dependency 'coveralls', '~> 0.7.0'
28
+ g.add_development_dependency 'simplecov', '~> 0.8.2'
29
+
30
+ g.add_runtime_dependency 'lita', '~>3.0.0'
31
+ g.add_runtime_dependency 'forecast_io', '~>2.0.0'
32
+ g.add_runtime_dependency 'geocoder', '~>1.1.9'
33
+ g.add_runtime_dependency 'compass_rose', '~> 0.1.0'
34
+ end
@@ -0,0 +1,264 @@
1
+ # -*- coding: UTF-8 -*-
2
+ require 'spec_helper'
3
+
4
+ describe LitaForecast::Current do
5
+ let(:forecast) do
6
+ {
7
+ 'currently' => {
8
+ 'temperature' => 100.11,
9
+ 'apparentTemperature' => 102.11,
10
+ 'summary' => 'weather',
11
+ 'windBearing' => 0,
12
+ 'windSpeed' => 5.11,
13
+ 'humidity' => 0.10,
14
+ 'dewPoint' => 20.11,
15
+ 'pressure' => 1020.11,
16
+ 'cloudCover' => 0.01
17
+ },
18
+ 'minutely' => { 'summary' => 'minutely weather' },
19
+ 'hourly' => { 'summary' => 'hourly weather' },
20
+ 'flags' => { 'units' => 'us' }
21
+ }
22
+ end
23
+ let(:current) { described_class.new(forecast) }
24
+
25
+ describe '#new' do
26
+ context 'when given more than one arg' do
27
+ it 'should raise error ArgumentError' do
28
+ expect do
29
+ LitaForecast::Current.new(nil, nil)
30
+ end.to raise_error ArgumentError
31
+ end
32
+ end
33
+
34
+ context 'when given less than one arg' do
35
+ it 'should raise error ArgumentError' do
36
+ expect do
37
+ LitaForecast::Current.new
38
+ end.to raise_error ArgumentError
39
+ end
40
+ end
41
+
42
+ context 'when provided valid arguments' do
43
+ subject { LitaForecast::Current.new(forecast) }
44
+
45
+ it { should be_an_instance_of LitaForecast::Current }
46
+
47
+ it 'should set the f instance variable' do
48
+ expect(subject.instance_variable_get(:@f)).to eql forecast
49
+ end
50
+ end
51
+ end
52
+
53
+ describe '.currently' do
54
+ context 'when given one arg' do
55
+ it 'should raise error ArgumentError' do
56
+ expect do
57
+ current.send(:currently, nil)
58
+ end.to raise_error ArgumentError
59
+ end
60
+ end
61
+
62
+ context 'when passed no args' do
63
+ subject { current.send(:currently) }
64
+
65
+ it { should be_an_instance_of Hash }
66
+
67
+ it { should eql forecast['currently'] }
68
+ end
69
+ end
70
+
71
+ describe '.temp' do
72
+ context 'when given one arg' do
73
+ it 'should raise error ArgumentError' do
74
+ expect do
75
+ current.send(:temp, nil)
76
+ end.to raise_error ArgumentError
77
+ end
78
+ end
79
+
80
+ context 'when passed no args' do
81
+ subject { current.send(:temp) }
82
+ let(:temp) { '100.1F' }
83
+
84
+ it { should be_an_instance_of String }
85
+
86
+ it { should eql temp }
87
+ end
88
+ end
89
+
90
+ describe '.feels' do
91
+ context 'when given one arg' do
92
+ it 'should raise error ArgumentError' do
93
+ expect do
94
+ current.send(:feels, nil)
95
+ end.to raise_error ArgumentError
96
+ end
97
+ end
98
+
99
+ context 'when passed no args' do
100
+ subject { current.send(:feels) }
101
+ let(:feels) { '102.1F' }
102
+
103
+ it { should be_an_instance_of String }
104
+
105
+ it { should eql feels }
106
+ end
107
+ end
108
+
109
+ describe '.wind' do
110
+ context 'when given one arg' do
111
+ it 'should raise error ArgumentError' do
112
+ expect do
113
+ current.send(:wind, nil)
114
+ end.to raise_error ArgumentError
115
+ end
116
+ end
117
+
118
+ context 'when passed no args' do
119
+ subject { current.send(:wind) }
120
+ let(:wind) { 'N 5.1mph' }
121
+
122
+ it { should be_an_instance_of String }
123
+
124
+ it { should eql wind }
125
+ end
126
+ end
127
+
128
+ describe '.humidity' do
129
+ context 'when given one arg' do
130
+ it 'should raise error ArgumentError' do
131
+ expect do
132
+ current.send(:humidity, nil)
133
+ end.to raise_error ArgumentError
134
+ end
135
+ end
136
+
137
+ context 'when passed no args' do
138
+ subject { current.send(:humidity) }
139
+ let(:humidity) { '10%' }
140
+
141
+ it { should be_an_instance_of String }
142
+
143
+ it { should eql humidity }
144
+ end
145
+ end
146
+
147
+ describe '.dew_pt' do
148
+ context 'when given one arg' do
149
+ it 'should raise error ArgumentError' do
150
+ expect do
151
+ current.send(:dew_pt, nil)
152
+ end.to raise_error ArgumentError
153
+ end
154
+ end
155
+
156
+ context 'when passed no args' do
157
+ subject { current.send(:dew_pt) }
158
+ let(:dew_pt) { '20.1F' }
159
+
160
+ it { should be_an_instance_of String }
161
+
162
+ it { should eql dew_pt }
163
+ end
164
+ end
165
+
166
+ describe '.pressure' do
167
+ context 'when given one arg' do
168
+ it 'should raise error ArgumentError' do
169
+ expect do
170
+ current.send(:pressure, nil)
171
+ end.to raise_error ArgumentError
172
+ end
173
+ end
174
+
175
+ context 'when passed no args' do
176
+ subject { current.send(:pressure) }
177
+ let(:pressure) { '1020.1mb' }
178
+
179
+ it { should be_an_instance_of String }
180
+
181
+ it { should eql pressure }
182
+ end
183
+ end
184
+
185
+ describe '.clouds' do
186
+ context 'when given one arg' do
187
+ it 'should raise error ArgumentError' do
188
+ expect do
189
+ current.send(:clouds, nil)
190
+ end.to raise_error ArgumentError
191
+ end
192
+ end
193
+
194
+ context 'when passed no args' do
195
+ subject { current.send(:clouds) }
196
+ let(:clouds) { '1%' } # these clouds are the 1%... (horrible joke) //TH
197
+
198
+ it { should be_an_instance_of String }
199
+
200
+ it { should eql clouds }
201
+ end
202
+ end
203
+
204
+ describe '.next_hour' do
205
+ context 'when given one arg' do
206
+ it 'should raise error ArgumentError' do
207
+ expect do
208
+ current.send(:next_hour, nil)
209
+ end.to raise_error ArgumentError
210
+ end
211
+ end
212
+
213
+ context 'when passed no args' do
214
+ subject { current.send(:next_hour) }
215
+ let(:next_hour) { 'minutely weather' }
216
+
217
+ it { should be_an_instance_of String }
218
+
219
+ it { should eql next_hour }
220
+ end
221
+ end
222
+
223
+ describe '.today' do
224
+ context 'when given one arg' do
225
+ it 'should raise error ArgumentError' do
226
+ expect do
227
+ current.send(:today, nil)
228
+ end.to raise_error ArgumentError
229
+ end
230
+ end
231
+
232
+ context 'when passed no args' do
233
+ subject { current.send(:today) }
234
+ let(:today) { 'hourly weather' }
235
+
236
+ it { should be_an_instance_of String }
237
+
238
+ it { should eql today }
239
+ end
240
+ end
241
+
242
+ describe '.conditions' do
243
+ subject { LitaForecast::Current.new(forecast).conditions }
244
+ let(:fc_string) do
245
+ '100.1F (feels like 102.1F) weather; Winds N 5.1mph; Humidity 10%; ' \
246
+ "Dew Pt 20.1F; Pressure 1020.1mb; Cloud cover 1%.\n" \
247
+ 'Next hour: minutely weather Next 24h: hourly weather'
248
+ end
249
+
250
+ context 'when given one arg' do
251
+ it 'should raise error ArgumentError' do
252
+ expect do
253
+ LitaForecast::Current.new(forecast).conditions(nil)
254
+ end.to raise_error ArgumentError
255
+ end
256
+ end
257
+
258
+ context 'when called with no args' do
259
+ it { should be_an_instance_of String }
260
+
261
+ it { should eql fc_string }
262
+ end
263
+ end
264
+ end
@@ -0,0 +1,260 @@
1
+ # -*- coding: UTF-8 -*-
2
+ require 'spec_helper'
3
+
4
+ describe LitaForecast::Future do
5
+ let(:forecast) do
6
+ {
7
+ 'flags' => { 'units' => 'us' },
8
+ 'daily' => {
9
+ 'summary' => 'daily weather',
10
+ 'data' => [
11
+ {
12
+ 'summary' => 'weather today!',
13
+ 'temperatureMax' => 68.0,
14
+ 'temperatureMin' => 60.2,
15
+ 'precipProbability' => 0,
16
+ 'windSpeed' => 0,
17
+ 'windBearing' => 0
18
+ },
19
+ {
20
+ 'summary' => 'weather tomorrow!',
21
+ 'temperatureMax' => 70.0,
22
+ 'temperatureMin' => 62.1,
23
+ 'precipProbability' => 1,
24
+ 'precipType' => 'rain',
25
+ 'windSpeed' => 10,
26
+ 'windBearing' => 270
27
+ }
28
+ ]
29
+ }
30
+ }
31
+ end
32
+
33
+ before do
34
+ @future = LitaForecast::Future.new(forecast)
35
+ end
36
+
37
+ describe '#new' do
38
+ context 'when given more than one arg' do
39
+ it 'should raise ArgumentError' do
40
+ expect do
41
+ LitaForecast::Future.new(nil, nil)
42
+ end.to raise_error ArgumentError
43
+ end
44
+ end
45
+
46
+ context 'when given less than one arg' do
47
+ it 'should raise ArgumentError' do
48
+ expect do
49
+ LitaForecast::Future.new
50
+ end.to raise_error ArgumentError
51
+ end
52
+ end
53
+
54
+ context 'when passed a ForecastIO-like response' do
55
+ subject { LitaForecast::Future.new(forecast) }
56
+
57
+ it { should be_an_instance_of LitaForecast::Future }
58
+
59
+ it 'should set the ForecastIO-like object to the @f variable' do
60
+ i = subject.instance_variable_get(:@f)
61
+ expect(i).to eql forecast
62
+ end
63
+ end
64
+ end
65
+
66
+ describe '.daily' do
67
+ context 'when passed more than zero args' do
68
+ it 'should raise ArgumentError' do
69
+ expect do
70
+ @future.send(:daily, nil)
71
+ end.to raise_error ArgumentError
72
+ end
73
+ end
74
+
75
+ context 'when called' do
76
+ subject { @future.send(:daily) }
77
+
78
+ it { should be_an_instance_of Array }
79
+
80
+ it { should eql forecast['daily']['data'] }
81
+ end
82
+ end
83
+
84
+ describe '.generate_summary' do
85
+ context 'when passed more than zero args' do
86
+ it 'should raise ArgumentError' do
87
+ expect do
88
+ @future.send(:generate_summary, nil)
89
+ end.to raise_error ArgumentError
90
+ end
91
+ end
92
+
93
+ context 'when called' do
94
+ subject { @future.send(:generate_summary) }
95
+
96
+ it { should be_an_instance_of String }
97
+
98
+ it { should eql "Summary: daily weather\n" }
99
+ end
100
+ end
101
+
102
+ describe '.summary' do
103
+ context 'when given more than zero args' do
104
+ it 'should raise ArgumentError' do
105
+ expect do
106
+ @future.send(:summary, nil)
107
+ end.to raise_error ArgumentError
108
+ end
109
+ end
110
+
111
+ context 'when called' do
112
+ before do
113
+ @future.instance_variable_set(:@i, forecast['daily']['data'][0])
114
+ @future.instance_variable_set(:@d, 'Today')
115
+ end
116
+
117
+ subject { @future.send(:summary) }
118
+
119
+ it { should be_an_instance_of String }
120
+
121
+ it { should eql 'Today: weather today!' }
122
+ end
123
+ end
124
+
125
+ describe '.high_low' do
126
+ context 'when given more than zero args' do
127
+ it 'should raise ArgumentError' do
128
+ expect do
129
+ @future.send(:high_low, nil)
130
+ end.to raise_error ArgumentError
131
+ end
132
+ end
133
+
134
+ context 'when called' do
135
+ before do
136
+ @future.instance_variable_set(:@i, forecast['daily']['data'][0])
137
+ @future.instance_variable_set(:@d, 'Today')
138
+ end
139
+ let(:good_string) { 'High 68F, Low 60F.' }
140
+
141
+ subject { @future.send(:high_low) }
142
+
143
+ it { should be_an_instance_of String }
144
+
145
+ it { should eql good_string }
146
+ end
147
+ end
148
+
149
+ describe '.precip' do
150
+ context 'when given more than zero args' do
151
+ it 'should raise ArgumentError' do
152
+ expect do
153
+ @future.send(:precip, nil)
154
+ end.to raise_error ArgumentError
155
+ end
156
+ end
157
+
158
+ context 'when called with no preciptType' do
159
+ before do
160
+ @future.instance_variable_set(:@i, forecast['daily']['data'][0])
161
+ end
162
+
163
+ subject { @future.send(:precip) }
164
+
165
+ it { should be_an_instance_of String }
166
+
167
+ it { should eql '0% chance of precipitation.' }
168
+ end
169
+
170
+ context 'when called with a precipType' do
171
+ before do
172
+ @future.instance_variable_set(:@i, forecast['daily']['data'][1])
173
+ end
174
+
175
+ subject { @future.send(:precip) }
176
+
177
+ it { should be_an_instance_of String }
178
+
179
+ it { should eql '100% chance of rain.' }
180
+ end
181
+ end
182
+
183
+ describe '.wind' do
184
+ context 'when given more than zero args' do
185
+ it 'should raise ArgumentError' do
186
+ expect do
187
+ @future.send(:wind, nil)
188
+ end.to raise_error ArgumentError
189
+ end
190
+ end
191
+
192
+ context 'when called' do
193
+ before do
194
+ @future.instance_variable_set(:@i, forecast['daily']['data'][0])
195
+ end
196
+
197
+ subject { @future.send(:wind) }
198
+
199
+ it { should be_an_instance_of String }
200
+
201
+ it { should eql 'Winds N 0mph.' }
202
+ end
203
+ end
204
+
205
+ describe '.generate_day' do
206
+ context 'when given more than two args' do
207
+ it 'should raise ArgumentError' do
208
+ expect do
209
+ @future.send(:generate_day, nil, nil, nil)
210
+ end.to raise_error ArgumentError
211
+ end
212
+ end
213
+
214
+ context 'when given less than two args' do
215
+ it 'should raise ArgumentError' do
216
+ expect do
217
+ @future.send(:generate_day, nil)
218
+ end.to raise_error ArgumentError
219
+ end
220
+ end
221
+
222
+ context 'when index is 0 and day is Today' do
223
+ let(:good_string) do
224
+ "Today: weather today! High 68F, Low 60F. 0% chance of " \
225
+ "precipitation. Winds N 0mph.\n"
226
+ end
227
+ subject { @future.send(:generate_day, 0, 'Today') }
228
+
229
+ it { should be_an_instance_of String }
230
+
231
+ it { should eql good_string }
232
+ end
233
+ end
234
+
235
+ describe '.conditions' do
236
+ context 'when given more than zero args' do
237
+ it 'should raise ArgumentError' do
238
+ expect do
239
+ @future.conditions(nil)
240
+ end.to raise_error ArgumentError
241
+ end
242
+ end
243
+
244
+ context 'when called' do
245
+ let(:good_string) do
246
+ "Summary: daily weather\n" \
247
+ "Today: weather today! High 68F, Low 60F. 0% chance of " \
248
+ "precipitation. Winds N 0mph.\n" \
249
+ "Tomorrow: weather tomorrow! High 70F, Low 62F. 100% chance of " \
250
+ "rain. Winds W 10mph.\n"
251
+ end
252
+
253
+ subject { @future.conditions }
254
+
255
+ it { should be_an_instance_of String }
256
+
257
+ it { should eql good_string }
258
+ end
259
+ end
260
+ end
@@ -0,0 +1,116 @@
1
+ # -*- coding: UTF-8 -*-
2
+ require 'spec_helper'
3
+ require 'hashie'
4
+
5
+ # Class for stubbing Geolocation data
6
+ #
7
+ class MockGeocoderClass
8
+ DATA = {
9
+ 'address_components' => [
10
+ { 'long_name' => 'San Francisco', 'types' => %w(locality) },
11
+ { 'short_name' => 'CA', 'types' => %w(administrative_area_level_1) }
12
+ ],
13
+ 'geometry' => {
14
+ 'location' => { 'lat' => 37.7749295, 'lng' => -122.4194155 }
15
+ }
16
+ }
17
+
18
+ def self.data
19
+ DATA
20
+ end
21
+ end
22
+
23
+ # Class for stubbing Redis class
24
+ #
25
+ class MockRedisClass
26
+ def self.hgetall(search)
27
+ Hashie::Mash.new({})
28
+ end
29
+ end
30
+
31
+ describe LitaForecast::Location do
32
+ before do
33
+ @lfloc = LitaForecast::Location.new(MockRedisClass)
34
+ end
35
+
36
+ describe '#new' do
37
+ context 'when passed more than one arg' do
38
+ it 'should raise ArgumentError' do
39
+ expect do
40
+ LitaForecast::Location.new(nil, nil)
41
+ end.to raise_error ArgumentError
42
+ end
43
+ end
44
+
45
+ context 'when passed less than one arg' do
46
+ it 'should raise ArgumentError' do
47
+ expect do
48
+ LitaForecast::Location.new
49
+ end.to raise_error ArgumentError
50
+ end
51
+ end
52
+
53
+ context 'when passed an object' do
54
+ subject { LitaForecast::Location.new(MockRedisClass) }
55
+
56
+ it { should be_an_instance_of LitaForecast::Location }
57
+ end
58
+ end
59
+
60
+ describe '.lita_redis' do
61
+ context 'when given an arg' do
62
+ subject { LitaForecast::Location.new(MockRedisClass).lita_redis }
63
+
64
+ it { should eql MockRedisClass }
65
+ end
66
+ end
67
+
68
+ describe '.find_location' do
69
+ before do
70
+ allow_any_instance_of(Geocoder).to receive(:search)
71
+ .and_return([MockGeocoderClass])
72
+ end
73
+
74
+ context 'when given more than one arg' do
75
+ it 'should raise ArgumentError' do
76
+ expect do
77
+ @lfloc.find_location(nil, nil)
78
+ end.to raise_error ArgumentError
79
+ end
80
+ end
81
+
82
+ context 'when given less tha one arg' do
83
+ it 'should raise ArgumentError' do
84
+ expect do
85
+ @lfloc.find_location
86
+ end.to raise_error ArgumentError
87
+ end
88
+ end
89
+
90
+ context 'when passed "san francisco" and not cached' do
91
+ let(:good_hash) do
92
+ { lat: 37.7749295, lng: -122.4194155, desc: 'San Francisco, CA' }
93
+ end
94
+
95
+ subject { @lfloc.find_location('san francisco') }
96
+
97
+ it { should be_an_instance_of Hash }
98
+
99
+ it { should eql good_hash }
100
+ end
101
+
102
+ context 'when passed "san francisco" and cached' do
103
+ before do
104
+ @cr = { lat: 37.7749295, lng: -122.4194155, desc: 'San Francisco, CA' }
105
+ allow_any_instance_of(MockRedisClass).to receive(:hgetall)
106
+ .and_return(@cr)
107
+ end
108
+
109
+ subject { @lfloc.find_location('san francisco') }
110
+
111
+ it { should be_an_instance_of Hash }
112
+
113
+ it { should eql @cr }
114
+ end
115
+ end
116
+ end