barometer 0.9.2 → 0.9.3
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +1 -1
- data/barometer.gemspec +1 -0
- data/lib/barometer/query/base.rb +0 -1
- data/lib/barometer/version.rb +1 -1
- data/lib/barometer/weather_service.rb +0 -1
- data/spec/spec_helper.rb +3 -4
- metadata +18 -26
- data/lib/barometer/weather_services/forecast_io.rb +0 -36
- data/lib/barometer/weather_services/forecast_io/api.rb +0 -22
- data/lib/barometer/weather_services/forecast_io/query.rb +0 -38
- data/lib/barometer/weather_services/forecast_io/response.rb +0 -31
- data/lib/barometer/weather_services/forecast_io/response/current_weather.rb +0 -78
- data/lib/barometer/weather_services/forecast_io/response/forecasted_weather.rb +0 -74
- data/lib/barometer/weather_services/forecast_io/response/location.rb +0 -19
- data/lib/barometer/weather_services/forecast_io/response/timezone.rb +0 -25
- data/spec/support/key_file_parser.rb +0 -22
- data/spec/support/matchers/formats.rb +0 -36
- data/spec/support/matchers/have_data.rb +0 -46
- data/spec/support/matchers/have_field.rb +0 -128
- data/spec/support/matchers/have_forecast.rb +0 -46
- data/spec/support/matchers/path.rb +0 -23
- data/spec/support/query_factory.rb +0 -20
- data/spec/weather_services/forecast_io_spec.rb +0 -71
data/README.md
CHANGED
@@ -86,7 +86,7 @@ The current available sources are:
|
|
86
86
|
* Yahoo! Weather (:yahoo)
|
87
87
|
* WeatherBug.com (:weather_bug) [requires key]
|
88
88
|
* NOAA (:noaa)
|
89
|
-
* Forecast.io (:forecast_io) [requires key]
|
89
|
+
* Forecast.io (:forecast_io) [requires key + [barometer-forecast_io gem](https://github.com/attack/barometer-forecast_io)]
|
90
90
|
|
91
91
|
### Source Configuration
|
92
92
|
|
data/barometer.gemspec
CHANGED
data/lib/barometer/query/base.rb
CHANGED
data/lib/barometer/version.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -6,11 +6,10 @@ require 'cgi'
|
|
6
6
|
require 'pry'
|
7
7
|
require 'vcr'
|
8
8
|
require 'webmock/rspec'
|
9
|
+
require 'barometer/support'
|
9
10
|
|
10
11
|
require_relative '../lib/barometer'
|
11
12
|
|
12
|
-
Dir["./spec/support/**/*.rb"].sort.each {|f| require f}
|
13
|
-
|
14
13
|
WEATHERBUG_CODE = Barometer::Support::KeyFileParser.find(:weather_bug, :code) || 'weatherbug'
|
15
14
|
FORECAST_IO_APIKEY = Barometer::Support::KeyFileParser.find(:forecast_io, :apikey) || 'forecastio'
|
16
15
|
downcased_weatherbug_code = WEATHERBUG_CODE.to_s
|
@@ -31,6 +30,6 @@ end
|
|
31
30
|
|
32
31
|
RSpec.configure do |config|
|
33
32
|
config.treat_symbols_as_metadata_keys_with_true_values = true
|
33
|
+
config.include Barometer::Support::Matchers
|
34
|
+
config.include Barometer::Support::Factory
|
34
35
|
end
|
35
|
-
|
36
|
-
include Barometer::Matchers
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: barometer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-11-
|
12
|
+
date: 2013-11-23 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: httpclient
|
@@ -219,6 +219,22 @@ dependencies:
|
|
219
219
|
- - ! '>='
|
220
220
|
- !ruby/object:Gem::Version
|
221
221
|
version: '0'
|
222
|
+
- !ruby/object:Gem::Dependency
|
223
|
+
name: barometer-support
|
224
|
+
requirement: !ruby/object:Gem::Requirement
|
225
|
+
none: false
|
226
|
+
requirements:
|
227
|
+
- - ! '>='
|
228
|
+
- !ruby/object:Gem::Version
|
229
|
+
version: '0'
|
230
|
+
type: :development
|
231
|
+
prerelease: false
|
232
|
+
version_requirements: !ruby/object:Gem::Requirement
|
233
|
+
none: false
|
234
|
+
requirements:
|
235
|
+
- - ! '>='
|
236
|
+
- !ruby/object:Gem::Version
|
237
|
+
version: '0'
|
222
238
|
description: A multi API consuming weather forecasting superstar.
|
223
239
|
email:
|
224
240
|
- barometer@attackcorp.com
|
@@ -323,14 +339,6 @@ files:
|
|
323
339
|
- lib/barometer/weather.rb
|
324
340
|
- lib/barometer/weather_service.rb
|
325
341
|
- lib/barometer/weather_services/base.rb
|
326
|
-
- lib/barometer/weather_services/forecast_io.rb
|
327
|
-
- lib/barometer/weather_services/forecast_io/api.rb
|
328
|
-
- lib/barometer/weather_services/forecast_io/query.rb
|
329
|
-
- lib/barometer/weather_services/forecast_io/response.rb
|
330
|
-
- lib/barometer/weather_services/forecast_io/response/current_weather.rb
|
331
|
-
- lib/barometer/weather_services/forecast_io/response/forecasted_weather.rb
|
332
|
-
- lib/barometer/weather_services/forecast_io/response/location.rb
|
333
|
-
- lib/barometer/weather_services/forecast_io/response/timezone.rb
|
334
342
|
- lib/barometer/weather_services/noaa.rb
|
335
343
|
- lib/barometer/weather_services/noaa/current_api.rb
|
336
344
|
- lib/barometer/weather_services/noaa/current_query.rb
|
@@ -453,13 +461,6 @@ files:
|
|
453
461
|
- spec/response/predicition_spec.rb
|
454
462
|
- spec/response/prediction_collection_spec.rb
|
455
463
|
- spec/spec_helper.rb
|
456
|
-
- spec/support/key_file_parser.rb
|
457
|
-
- spec/support/matchers/formats.rb
|
458
|
-
- spec/support/matchers/have_data.rb
|
459
|
-
- spec/support/matchers/have_field.rb
|
460
|
-
- spec/support/matchers/have_forecast.rb
|
461
|
-
- spec/support/matchers/path.rb
|
462
|
-
- spec/support/query_factory.rb
|
463
464
|
- spec/utils/address_spec.rb
|
464
465
|
- spec/utils/config_reader_spec.rb
|
465
466
|
- spec/utils/get_spec.rb
|
@@ -469,7 +470,6 @@ files:
|
|
469
470
|
- spec/utils/time_spec.rb
|
470
471
|
- spec/utils/versioned_registration_spec.rb
|
471
472
|
- spec/weather_services/base_spec.rb
|
472
|
-
- spec/weather_services/forecast_io_spec.rb
|
473
473
|
- spec/weather_services/noaa/current_response_spec.rb
|
474
474
|
- spec/weather_services/noaa/forecast_response_spec.rb
|
475
475
|
- spec/weather_services/noaa_spec.rb
|
@@ -582,13 +582,6 @@ test_files:
|
|
582
582
|
- spec/response/predicition_spec.rb
|
583
583
|
- spec/response/prediction_collection_spec.rb
|
584
584
|
- spec/spec_helper.rb
|
585
|
-
- spec/support/key_file_parser.rb
|
586
|
-
- spec/support/matchers/formats.rb
|
587
|
-
- spec/support/matchers/have_data.rb
|
588
|
-
- spec/support/matchers/have_field.rb
|
589
|
-
- spec/support/matchers/have_forecast.rb
|
590
|
-
- spec/support/matchers/path.rb
|
591
|
-
- spec/support/query_factory.rb
|
592
585
|
- spec/utils/address_spec.rb
|
593
586
|
- spec/utils/config_reader_spec.rb
|
594
587
|
- spec/utils/get_spec.rb
|
@@ -598,7 +591,6 @@ test_files:
|
|
598
591
|
- spec/utils/time_spec.rb
|
599
592
|
- spec/utils/versioned_registration_spec.rb
|
600
593
|
- spec/weather_services/base_spec.rb
|
601
|
-
- spec/weather_services/forecast_io_spec.rb
|
602
594
|
- spec/weather_services/noaa/current_response_spec.rb
|
603
595
|
- spec/weather_services/noaa/forecast_response_spec.rb
|
604
596
|
- spec/weather_services/noaa_spec.rb
|
@@ -1,36 +0,0 @@
|
|
1
|
-
require_relative 'forecast_io/api'
|
2
|
-
require_relative 'forecast_io/response'
|
3
|
-
|
4
|
-
module Barometer
|
5
|
-
module WeatherService
|
6
|
-
class ForecastIo
|
7
|
-
def self.call(query, config={})
|
8
|
-
ForecastIo.new(query, config).measure!
|
9
|
-
end
|
10
|
-
|
11
|
-
def initialize(query, config={})
|
12
|
-
@query = query
|
13
|
-
@apikey = config[:keys][:api] if config[:keys]
|
14
|
-
end
|
15
|
-
|
16
|
-
def measure!
|
17
|
-
validate_key!
|
18
|
-
|
19
|
-
api = ForecastIo::Api.new(query, apikey)
|
20
|
-
ForecastIo::Response.new.parse(api.get)
|
21
|
-
end
|
22
|
-
|
23
|
-
private
|
24
|
-
|
25
|
-
attr_reader :query, :apikey
|
26
|
-
|
27
|
-
def validate_key!
|
28
|
-
unless apikey && !apikey.empty?
|
29
|
-
raise KeyRequired
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
Barometer::WeatherService.register(:forecast_io, Barometer::WeatherService::ForecastIo)
|
@@ -1,22 +0,0 @@
|
|
1
|
-
require_relative 'query'
|
2
|
-
|
3
|
-
module Barometer
|
4
|
-
module WeatherService
|
5
|
-
class ForecastIo
|
6
|
-
class Api < Utils::Api
|
7
|
-
def initialize(query, api_code)
|
8
|
-
@query = ForecastIo::Query.new(query)
|
9
|
-
@api_code = api_code
|
10
|
-
end
|
11
|
-
|
12
|
-
def url
|
13
|
-
"https://api.forecast.io/forecast/#{@api_code}/#{@query.to_param}"
|
14
|
-
end
|
15
|
-
|
16
|
-
def params
|
17
|
-
@query.units_param
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
@@ -1,38 +0,0 @@
|
|
1
|
-
require 'delegate'
|
2
|
-
|
3
|
-
module Barometer
|
4
|
-
module WeatherService
|
5
|
-
class ForecastIo
|
6
|
-
class Query < SimpleDelegator
|
7
|
-
attr_reader :converted_query
|
8
|
-
|
9
|
-
def self.accepted_formats
|
10
|
-
[:coordinates]
|
11
|
-
end
|
12
|
-
|
13
|
-
def initialize(query)
|
14
|
-
super
|
15
|
-
@converted_query = convert_query
|
16
|
-
end
|
17
|
-
|
18
|
-
def to_param
|
19
|
-
@converted_query.q
|
20
|
-
end
|
21
|
-
|
22
|
-
def units_param
|
23
|
-
{units: unit_type}
|
24
|
-
end
|
25
|
-
|
26
|
-
private
|
27
|
-
|
28
|
-
def convert_query
|
29
|
-
convert!(*self.class.accepted_formats)
|
30
|
-
end
|
31
|
-
|
32
|
-
def unit_type
|
33
|
-
converted_query.metric? ? 'si' : 'us'
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
@@ -1,31 +0,0 @@
|
|
1
|
-
require_relative 'response/timezone'
|
2
|
-
require_relative 'response/location'
|
3
|
-
require_relative 'response/current_weather'
|
4
|
-
require_relative 'response/forecasted_weather'
|
5
|
-
|
6
|
-
module Barometer
|
7
|
-
module WeatherService
|
8
|
-
class ForecastIo
|
9
|
-
class Response
|
10
|
-
def initialize
|
11
|
-
@response = Barometer::Response.new
|
12
|
-
end
|
13
|
-
|
14
|
-
def parse(payload)
|
15
|
-
response.add_query(payload.query)
|
16
|
-
|
17
|
-
response.timezone = ForecastIo::Response::TimeZone.new(payload).parse
|
18
|
-
response.location = ForecastIo::Response::Location.new(payload).parse
|
19
|
-
response.current = ForecastIo::Response::CurrentWeather.new(payload).parse
|
20
|
-
response.forecast = ForecastIo::Response::ForecastedWeather.new(payload).parse
|
21
|
-
|
22
|
-
response
|
23
|
-
end
|
24
|
-
|
25
|
-
private
|
26
|
-
|
27
|
-
attr_reader :response
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
@@ -1,78 +0,0 @@
|
|
1
|
-
module Barometer
|
2
|
-
module WeatherService
|
3
|
-
class ForecastIo
|
4
|
-
class Response
|
5
|
-
class CurrentWeather
|
6
|
-
def initialize(payload)
|
7
|
-
@payload = payload
|
8
|
-
@current = Barometer::Response::Current.new
|
9
|
-
end
|
10
|
-
|
11
|
-
def parse
|
12
|
-
current.observed_at = observed_at
|
13
|
-
current.humidity = humidity
|
14
|
-
current.condition = condition
|
15
|
-
current.icon = icon
|
16
|
-
current.temperature = temperature
|
17
|
-
current.dew_point = dew_point
|
18
|
-
current.wind = wind
|
19
|
-
current.pressure = pressure
|
20
|
-
current.visibility = visibility
|
21
|
-
|
22
|
-
current
|
23
|
-
end
|
24
|
-
|
25
|
-
private
|
26
|
-
|
27
|
-
attr_reader :payload, :current
|
28
|
-
|
29
|
-
def units
|
30
|
-
payload.units
|
31
|
-
end
|
32
|
-
|
33
|
-
def observed_at
|
34
|
-
Time.at(payload.fetch('currently', 'time').to_i)
|
35
|
-
end
|
36
|
-
|
37
|
-
def humidity
|
38
|
-
payload.fetch('currently', 'humidity') * 100
|
39
|
-
end
|
40
|
-
|
41
|
-
def condition
|
42
|
-
payload.fetch('currently', 'summary')
|
43
|
-
end
|
44
|
-
|
45
|
-
def icon
|
46
|
-
payload.fetch('currently', 'icon')
|
47
|
-
end
|
48
|
-
|
49
|
-
def temperature
|
50
|
-
[units, payload.fetch('currently', 'temperature')]
|
51
|
-
end
|
52
|
-
|
53
|
-
def dew_point
|
54
|
-
[units, payload.fetch('currently', 'dewPoint')]
|
55
|
-
end
|
56
|
-
|
57
|
-
def wind
|
58
|
-
[units, convert_metre_per_second(payload.fetch('currently', 'windSpeed')), payload.fetch('currently', 'windBearing').to_i]
|
59
|
-
end
|
60
|
-
|
61
|
-
def pressure
|
62
|
-
[:metric, payload.fetch('currently', 'pressure')]
|
63
|
-
end
|
64
|
-
|
65
|
-
def visibility
|
66
|
-
[units, payload.fetch('currently', 'visibility')]
|
67
|
-
end
|
68
|
-
|
69
|
-
private
|
70
|
-
|
71
|
-
def convert_metre_per_second(value)
|
72
|
-
value.to_f * 60 * 60 / 1000
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|
@@ -1,74 +0,0 @@
|
|
1
|
-
module Barometer
|
2
|
-
module WeatherService
|
3
|
-
class ForecastIo
|
4
|
-
class Response
|
5
|
-
class ForecastedWeather
|
6
|
-
def initialize(payload)
|
7
|
-
@payload = payload
|
8
|
-
@predictions = Barometer::Response::PredictionCollection.new
|
9
|
-
end
|
10
|
-
|
11
|
-
def parse
|
12
|
-
each_prediction do |prediction, forecast_payload|
|
13
|
-
prediction.starts_at = starts_at(forecast_payload)
|
14
|
-
prediction.ends_at = Utils::Time.add_one_day(prediction.starts_at)
|
15
|
-
prediction.icon = icon(forecast_payload)
|
16
|
-
prediction.condition = condition(forecast_payload)
|
17
|
-
prediction.high = high(forecast_payload)
|
18
|
-
prediction.low = low(forecast_payload)
|
19
|
-
prediction.sun = sun(forecast_payload, prediction.starts_at, prediction.ends_at)
|
20
|
-
end
|
21
|
-
|
22
|
-
predictions
|
23
|
-
end
|
24
|
-
|
25
|
-
private
|
26
|
-
|
27
|
-
attr_reader :payload, :predictions
|
28
|
-
|
29
|
-
def units
|
30
|
-
payload.units
|
31
|
-
end
|
32
|
-
|
33
|
-
def each_prediction
|
34
|
-
payload.fetch_each('daily', 'data') do |forecast_payload|
|
35
|
-
predictions.build do |prediction|
|
36
|
-
yield prediction, forecast_payload
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
def starts_at(forecast_payload)
|
42
|
-
time(forecast_payload.fetch('time'))
|
43
|
-
end
|
44
|
-
|
45
|
-
def icon(forecast_payload)
|
46
|
-
forecast_payload.fetch('icon')
|
47
|
-
end
|
48
|
-
|
49
|
-
def condition(forecast_payload)
|
50
|
-
forecast_payload.fetch('summary')
|
51
|
-
end
|
52
|
-
|
53
|
-
def high(forecast_payload)
|
54
|
-
[units, forecast_payload.fetch('temperatureMax')]
|
55
|
-
end
|
56
|
-
|
57
|
-
def low(forecast_payload)
|
58
|
-
[units, forecast_payload.fetch('temperatureMin')]
|
59
|
-
end
|
60
|
-
|
61
|
-
def sun(forecast_payload, starts_at, ends_at)
|
62
|
-
utc_rise_time = time(forecast_payload.fetch('sunriseTime'))
|
63
|
-
utc_set_time = time(forecast_payload.fetch('sunsetTime'))
|
64
|
-
Data::Sun.new(rise: utc_rise_time, set: utc_set_time)
|
65
|
-
end
|
66
|
-
|
67
|
-
def time(timestamp)
|
68
|
-
Time.at(timestamp.to_i)
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
@@ -1,19 +0,0 @@
|
|
1
|
-
module Barometer
|
2
|
-
module WeatherService
|
3
|
-
class ForecastIo
|
4
|
-
class Response
|
5
|
-
class Location < WeatherService::Response::Location
|
6
|
-
private
|
7
|
-
|
8
|
-
def latitude
|
9
|
-
payload.fetch('latitude')
|
10
|
-
end
|
11
|
-
|
12
|
-
def longitude
|
13
|
-
payload.fetch('longitude')
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
@@ -1,25 +0,0 @@
|
|
1
|
-
module Barometer
|
2
|
-
module WeatherService
|
3
|
-
class ForecastIo
|
4
|
-
class Response
|
5
|
-
class TimeZone
|
6
|
-
def initialize(payload)
|
7
|
-
@payload = payload
|
8
|
-
end
|
9
|
-
|
10
|
-
def parse
|
11
|
-
Data::Zone.new(time_zone)
|
12
|
-
end
|
13
|
-
|
14
|
-
private
|
15
|
-
|
16
|
-
attr_reader :payload
|
17
|
-
|
18
|
-
def time_zone
|
19
|
-
payload.fetch('timezone')
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
@@ -1,22 +0,0 @@
|
|
1
|
-
module Barometer
|
2
|
-
KEY_FILE = File.expand_path(File.join('~', '.barometer'))
|
3
|
-
|
4
|
-
module Support
|
5
|
-
class KeyFileParser
|
6
|
-
def self.find(*paths)
|
7
|
-
if File.exists?(KEY_FILE)
|
8
|
-
keys = YAML.load_file(KEY_FILE)
|
9
|
-
|
10
|
-
paths.each do |path|
|
11
|
-
if keys && keys.has_key?(path.to_s)
|
12
|
-
keys = keys.fetch(path.to_s)
|
13
|
-
else
|
14
|
-
keys = nil
|
15
|
-
end
|
16
|
-
end
|
17
|
-
keys
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
@@ -1,36 +0,0 @@
|
|
1
|
-
require 'rspec/expectations'
|
2
|
-
|
3
|
-
module Barometer
|
4
|
-
module Matchers
|
5
|
-
module Formats
|
6
|
-
def is_of_format?(format, value)
|
7
|
-
value.match(_find_regex(format))
|
8
|
-
end
|
9
|
-
|
10
|
-
def _find_regex(format)
|
11
|
-
case format
|
12
|
-
when :time
|
13
|
-
/^\d{1,4}-\d{1,2}-\d{1,2} \d{2}:\d{2}:\d{2} [\-\+\d]{5}$/i
|
14
|
-
when :optional_string
|
15
|
-
/^[\w \.-]*$/i
|
16
|
-
when :string
|
17
|
-
/^[\w \.-]{2,}$/i
|
18
|
-
when :number
|
19
|
-
/^\d{1,3}$/i
|
20
|
-
when :float
|
21
|
-
/^[\d\.]{1,5}$/i
|
22
|
-
when :temperature
|
23
|
-
/^-?[0-9\.]{1,5}[ ]?[cfCF]?$/i
|
24
|
-
when :pressure
|
25
|
-
/^[0-9\.]{1,7}[ ]?[a-zA-Z]{0,3}$/i
|
26
|
-
when :vector
|
27
|
-
/^[0-9\.]{1,5} (?:mph|kph) (?:[nesw]{1,3}(?:orth|outh|t|ast)?|@ [0-9\.]{1,5} degrees)$/i
|
28
|
-
when :distance
|
29
|
-
/^[0-9\.]{1,5}[ ]?k?m?$/i
|
30
|
-
when Regexp
|
31
|
-
format
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
@@ -1,46 +0,0 @@
|
|
1
|
-
require_relative 'path'
|
2
|
-
require_relative 'formats'
|
3
|
-
|
4
|
-
module Barometer
|
5
|
-
module Matchers
|
6
|
-
def have_data(*paths)
|
7
|
-
HaveData.new(*paths)
|
8
|
-
end
|
9
|
-
|
10
|
-
class HaveData
|
11
|
-
include Barometer::Matchers::Formats
|
12
|
-
|
13
|
-
def initialize(*paths)
|
14
|
-
@paths = paths
|
15
|
-
end
|
16
|
-
|
17
|
-
def matches?(subject)
|
18
|
-
@result = Walker.new(subject).follow(@paths)
|
19
|
-
|
20
|
-
if @format
|
21
|
-
is_of_format?(@format, @result)
|
22
|
-
else
|
23
|
-
@result == @value || @result.to_f == @value
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
def failure_message
|
28
|
-
"expected that '#{@result}' matches '#{@value || @format}'"
|
29
|
-
end
|
30
|
-
|
31
|
-
def description
|
32
|
-
"have correct value for #{@paths.join('.')}"
|
33
|
-
end
|
34
|
-
|
35
|
-
def as_value(value)
|
36
|
-
@value = value
|
37
|
-
self
|
38
|
-
end
|
39
|
-
|
40
|
-
def as_format(format)
|
41
|
-
@format = format
|
42
|
-
self
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
@@ -1,128 +0,0 @@
|
|
1
|
-
require 'rspec/expectations'
|
2
|
-
|
3
|
-
module Barometer
|
4
|
-
module Matchers
|
5
|
-
def have_field(field)
|
6
|
-
HaveField.new(field)
|
7
|
-
end
|
8
|
-
|
9
|
-
class HaveField
|
10
|
-
def initialize(field)
|
11
|
-
@field = field
|
12
|
-
end
|
13
|
-
|
14
|
-
def matches?(subject)
|
15
|
-
@subject = subject
|
16
|
-
has_field? &&
|
17
|
-
type_casts_as_type? &&
|
18
|
-
sets_value?
|
19
|
-
end
|
20
|
-
|
21
|
-
def failure_message
|
22
|
-
"Expected #{expectation} (#{@problem})"
|
23
|
-
end
|
24
|
-
|
25
|
-
def description
|
26
|
-
"have data field \"#{@field}\""
|
27
|
-
end
|
28
|
-
|
29
|
-
def of_type(type)
|
30
|
-
@type = type
|
31
|
-
self
|
32
|
-
end
|
33
|
-
|
34
|
-
protected
|
35
|
-
|
36
|
-
def has_field?
|
37
|
-
assert @subject.respond_to?(@field), "does not have field '#{@field}'"
|
38
|
-
end
|
39
|
-
|
40
|
-
def type_casts_as_type?
|
41
|
-
if type_is_time?
|
42
|
-
set_value "2013-01-01 10:15:30 am"
|
43
|
-
elsif type_is_sun?
|
44
|
-
rise = Time.utc(2013,1,1,10,15,30)
|
45
|
-
set = Time.utc(2013,1,1,18,14,56)
|
46
|
-
set_value Data::Sun.new(rise: rise, set: set)
|
47
|
-
else
|
48
|
-
set_value 10
|
49
|
-
end
|
50
|
-
assert value.is_a?(@type), "#{@field} does not typecast as #{@type}"
|
51
|
-
end
|
52
|
-
|
53
|
-
def sets_value?
|
54
|
-
if type_is_time?
|
55
|
-
set_value "10 15 30 2013 01 01 am", "%H %M %S %Y %m %d %p"
|
56
|
-
assert value.to_i == Time.utc(2013,01,01,10,15,30).to_i, "expected value of '2013-01-01 10:15:30 am', got '#{print_value}'"
|
57
|
-
elsif type_is_sun?
|
58
|
-
rise = Time.utc(2013,1,1,10,15,30)
|
59
|
-
set = Time.utc(2013,1,1,18,14,56)
|
60
|
-
set_value Data::Sun.new(rise: rise, set: set)
|
61
|
-
assert print_value == "rise: 10:15, set: 18:14", "expected value of 'rise: 10:15, set: 18:14'', got '#{print_value}'"
|
62
|
-
else
|
63
|
-
set_value 10
|
64
|
-
assert value.to_i == 10, "expected value of '10', got '#{value.to_i}'"
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
private
|
69
|
-
|
70
|
-
def value
|
71
|
-
@subject.send(@field)
|
72
|
-
end
|
73
|
-
|
74
|
-
def set_value(*value)
|
75
|
-
if type_is_time?
|
76
|
-
@subject.send("#{@field}=", value)
|
77
|
-
else
|
78
|
-
@subject.send("#{@field}=", *value)
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
def print_value
|
83
|
-
value.to_s
|
84
|
-
end
|
85
|
-
|
86
|
-
def metric_units
|
87
|
-
@type.send(:new, true).units
|
88
|
-
end
|
89
|
-
|
90
|
-
def imperial_units
|
91
|
-
@type.send(:new, false).units
|
92
|
-
end
|
93
|
-
|
94
|
-
def expectation
|
95
|
-
"\"#{@field}\" to be a #{@type}"
|
96
|
-
end
|
97
|
-
|
98
|
-
def value_responds_to_metric?
|
99
|
-
if type_is_time?
|
100
|
-
false
|
101
|
-
elsif @type == Float
|
102
|
-
# rubinius does not like Float.new being called on the next line
|
103
|
-
# so avoid it
|
104
|
-
false
|
105
|
-
else
|
106
|
-
@type.respond_to?(:new) && @type.new.respond_to?(:metric)
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
def type_is_time?
|
111
|
-
@type == Time
|
112
|
-
end
|
113
|
-
|
114
|
-
def type_is_sun?
|
115
|
-
@type == Data::Sun
|
116
|
-
end
|
117
|
-
|
118
|
-
def assert(test, failure_message)
|
119
|
-
if test
|
120
|
-
true
|
121
|
-
else
|
122
|
-
@problem = failure_message
|
123
|
-
false
|
124
|
-
end
|
125
|
-
end
|
126
|
-
end
|
127
|
-
end
|
128
|
-
end
|
@@ -1,46 +0,0 @@
|
|
1
|
-
require_relative 'path'
|
2
|
-
require_relative 'formats'
|
3
|
-
|
4
|
-
module Barometer
|
5
|
-
module Matchers
|
6
|
-
def have_forecast(*paths)
|
7
|
-
HaveForecast.new(*paths)
|
8
|
-
end
|
9
|
-
|
10
|
-
class HaveForecast
|
11
|
-
include Barometer::Matchers::Formats
|
12
|
-
|
13
|
-
def initialize(*paths)
|
14
|
-
@paths = paths
|
15
|
-
end
|
16
|
-
|
17
|
-
def matches?(subject)
|
18
|
-
@result = Walker.new(subject.forecast[0]).follow(@paths)
|
19
|
-
|
20
|
-
if @format
|
21
|
-
is_of_format?(@format, @result)
|
22
|
-
else
|
23
|
-
@result == @value || @result.to_f == @value
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
def failure_message
|
28
|
-
"expected that '#{@result}' matches '#{@value || @format}'"
|
29
|
-
end
|
30
|
-
|
31
|
-
def description
|
32
|
-
"have correct forecast value for #{@paths.join('.')}"
|
33
|
-
end
|
34
|
-
|
35
|
-
def as_value(value)
|
36
|
-
@value = value
|
37
|
-
self
|
38
|
-
end
|
39
|
-
|
40
|
-
def as_format(format)
|
41
|
-
@format = format
|
42
|
-
self
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
@@ -1,23 +0,0 @@
|
|
1
|
-
module Barometer
|
2
|
-
module Matchers
|
3
|
-
class Walker
|
4
|
-
attr_reader :value
|
5
|
-
|
6
|
-
def initialize(value)
|
7
|
-
@value = value
|
8
|
-
end
|
9
|
-
|
10
|
-
def follow(paths)
|
11
|
-
path_value = value
|
12
|
-
paths.each do |path|
|
13
|
-
path_value = path_value.send(path)
|
14
|
-
end
|
15
|
-
if path_value.respond_to?(:strftime)
|
16
|
-
path_value.strftime("%Y-%m-%d %H:%M:%S %z")
|
17
|
-
else
|
18
|
-
path_value.to_s
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
@@ -1,20 +0,0 @@
|
|
1
|
-
module Barometer
|
2
|
-
module Support
|
3
|
-
module Factory
|
4
|
-
def build_query
|
5
|
-
double(
|
6
|
-
:query,
|
7
|
-
q: 'foo',
|
8
|
-
format: :unknown,
|
9
|
-
units: :metric,
|
10
|
-
geo: nil,
|
11
|
-
metric?: true
|
12
|
-
)
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
RSpec.configure do |config|
|
19
|
-
config.include Barometer::Support::Factory
|
20
|
-
end
|
@@ -1,71 +0,0 @@
|
|
1
|
-
require_relative '../spec_helper'
|
2
|
-
|
3
|
-
describe Barometer::WeatherService::ForecastIo, vcr: {
|
4
|
-
cassette_name: "WeatherService::ForecastIo"
|
5
|
-
} do
|
6
|
-
|
7
|
-
it "auto-registers this weather service as :forecast_io" do
|
8
|
-
Barometer::WeatherService.source(:forecast_io).should == Barometer::WeatherService::ForecastIo
|
9
|
-
end
|
10
|
-
|
11
|
-
describe ".call" do
|
12
|
-
context "when no keys provided" do
|
13
|
-
let(:query) { build_query }
|
14
|
-
|
15
|
-
it "raises error" do
|
16
|
-
expect {
|
17
|
-
Barometer::WeatherService::ForecastIo.call(query)
|
18
|
-
}.to raise_error(Barometer::WeatherService::KeyRequired)
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
context "when keys are provided" do
|
23
|
-
let(:converted_query) { Barometer::ConvertedQuery.new('42.7243,-73.6927', :coordinates, :metric) }
|
24
|
-
let(:query) { build_query.tap{|q|q.stub(:convert! => converted_query)} }
|
25
|
-
let(:config) { {keys: {api: FORECAST_IO_APIKEY}} }
|
26
|
-
|
27
|
-
subject { Barometer::WeatherService::ForecastIo.call(query, config) }
|
28
|
-
|
29
|
-
it "asks the query to convert to accepted formats" do
|
30
|
-
query.should_receive(:convert!).with(:coordinates)
|
31
|
-
subject
|
32
|
-
end
|
33
|
-
|
34
|
-
it "includes the expected data" do
|
35
|
-
subject.query.should == '42.7243,-73.6927'
|
36
|
-
subject.format.should == :coordinates
|
37
|
-
subject.should be_metric
|
38
|
-
|
39
|
-
should have_data(:current, :observed_at).as_format(:time)
|
40
|
-
# should have_data(:current, :stale_at).as_format(:time)
|
41
|
-
|
42
|
-
should have_data(:current, :humidity).as_format(:float)
|
43
|
-
should have_data(:current, :condition).as_format(:string)
|
44
|
-
should have_data(:current, :icon).as_format(:string)
|
45
|
-
should have_data(:current, :temperature).as_format(:temperature)
|
46
|
-
should have_data(:current, :dew_point).as_format(:temperature)
|
47
|
-
should have_data(:current, :wind).as_format(:vector)
|
48
|
-
should have_data(:current, :pressure).as_format(:pressure)
|
49
|
-
should have_data(:current, :visibility).as_format(:distance)
|
50
|
-
# should have_data(:current, :sun, :rise).as_format(:time)
|
51
|
-
# should have_data(:current, :sun, :set).as_format(:time)
|
52
|
-
|
53
|
-
should have_data(:location, :latitude).as_value(42.7243)
|
54
|
-
should have_data(:location, :longitude).as_value(-73.6927)
|
55
|
-
|
56
|
-
should have_data(:timezone, :to_s).as_value('America/New_York')
|
57
|
-
should have_data(:timezone, :code).as_format(/^E[DS]T$/i)
|
58
|
-
|
59
|
-
subject.forecast.size.should == 8
|
60
|
-
should have_forecast(:starts_at).as_format(:time)
|
61
|
-
should have_forecast(:ends_at).as_format(:time)
|
62
|
-
should have_forecast(:icon).as_format(:string)
|
63
|
-
should have_forecast(:condition).as_format(:string)
|
64
|
-
should have_forecast(:high).as_format(:temperature)
|
65
|
-
should have_forecast(:low).as_format(:temperature)
|
66
|
-
should have_forecast(:sun, :rise).as_format(:time)
|
67
|
-
should have_forecast(:sun, :set).as_format(:time)
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|