barometer 0.9.2 → 0.9.3
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.
- 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
|