fixer_currency 3.4.2
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.
- checksums.yaml +7 -0
- data/.gemtest +0 -0
- data/AUTHORS +11 -0
- data/CHANGELOG.md +133 -0
- data/LICENSE +20 -0
- data/README.md +49 -0
- data/Rakefile +49 -0
- data/fixer_currency.gemspec +24 -0
- data/lib/money/bank/fixer_currency.rb +162 -0
- data/lib/money/rates_store/rate_removal_support.rb +27 -0
- data/spec/fixer_currency_with_json_spec.rb +142 -0
- data/spec/spec_helper.rb +9 -0
- metadata +113 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: a49f8eaca5bb9152f750e6336416b0991c3358ee4a7653555820e531551b71cd
|
4
|
+
data.tar.gz: 9c813b15ff729dd8f801d4cb917122a3cb31b857fcfae011133883226f123f7d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 3a6c7877a40ceb7076f4463f30bb2fbbb6d1a403a1f9ce60744448e2f5a7ae3f9620ce367146870840bdbcf827b738ba91315c35caf45953eacf59560fff9240
|
7
|
+
data.tar.gz: afe799a1adda9a9c6a438e7abe67c06159ae2389548793b30b732d62de7205f68c9ba34be1d13438090c3de77f73bfffb697ca84f4606cec684986538902a697
|
data/.gemtest
ADDED
File without changes
|
data/AUTHORS
ADDED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,133 @@
|
|
1
|
+
3.4.1
|
2
|
+
=====
|
3
|
+
|
4
|
+
- Fix the deprecated URL
|
5
|
+
|
6
|
+
3.4.0
|
7
|
+
=====
|
8
|
+
|
9
|
+
- Add captcha response detection
|
10
|
+
- Use finance.google.com for reliability across different regions
|
11
|
+
|
12
|
+
3.3.0
|
13
|
+
=====
|
14
|
+
|
15
|
+
- Update Money gem dep
|
16
|
+
|
17
|
+
3.2.1
|
18
|
+
=====
|
19
|
+
- Increase precision of rates by using inverse reciprocals for certain currencyes
|
20
|
+
|
21
|
+
3.0.0
|
22
|
+
=====
|
23
|
+
|
24
|
+
- Google closed ig/calculator, so we're now using finance/calculator
|
25
|
+
- fix incorrect parsing of complex rates
|
26
|
+
|
27
|
+
Google Currency 2.2.0
|
28
|
+
=====================
|
29
|
+
|
30
|
+
- Update money dependency to ~> 5.1.0
|
31
|
+
|
32
|
+
Google Currency 2.1.0
|
33
|
+
=====================
|
34
|
+
|
35
|
+
- Update money dependency to ~> 5.0.0
|
36
|
+
|
37
|
+
Google Currency 2.0.2
|
38
|
+
=====================
|
39
|
+
|
40
|
+
Bugfixes
|
41
|
+
--------
|
42
|
+
- Fix encoding issue
|
43
|
+
|
44
|
+
Google Currency 2.0.1
|
45
|
+
=====================
|
46
|
+
|
47
|
+
Features
|
48
|
+
--------
|
49
|
+
- Handles funky exchange rates (Arnaud Joubay)
|
50
|
+
|
51
|
+
Bugfixes
|
52
|
+
--------
|
53
|
+
- Fix for running under 1.9.2 in TextMate (larspind)
|
54
|
+
|
55
|
+
Google Currency 2.0.0
|
56
|
+
=====================
|
57
|
+
|
58
|
+
Features
|
59
|
+
--------
|
60
|
+
- Added multi_json to allow users to select their own JSON parsing engine.
|
61
|
+
- Removed deprecated method #get_google_rate.
|
62
|
+
|
63
|
+
Bugfixes
|
64
|
+
--------
|
65
|
+
- Updated deprecated rake tasks
|
66
|
+
|
67
|
+
Google Currency 1.1.1
|
68
|
+
=====================
|
69
|
+
|
70
|
+
Bugfixes
|
71
|
+
--------
|
72
|
+
- Built gem using Ruby 1.8.7 to bypass a known error with RubyGems 1.5.0 and
|
73
|
+
Ruby 1.9.2
|
74
|
+
|
75
|
+
Google Currency 1.1.0
|
76
|
+
=====================
|
77
|
+
|
78
|
+
Features
|
79
|
+
--------
|
80
|
+
- Deprecated #get_google_rate, use #get_rate (thanks RMU Alumni)
|
81
|
+
|
82
|
+
Bugfixes
|
83
|
+
---------
|
84
|
+
- Fixed an issue when rates over 1000 did not parse correctly (thanks Brandon
|
85
|
+
Anderson)
|
86
|
+
|
87
|
+
Google Currency 1.0.3
|
88
|
+
=====================
|
89
|
+
|
90
|
+
Features
|
91
|
+
--------
|
92
|
+
- Update `money` requirement to `~> 3.5`
|
93
|
+
|
94
|
+
Google Currency 1.0.2
|
95
|
+
=====================
|
96
|
+
|
97
|
+
Features
|
98
|
+
--------
|
99
|
+
- Replace `eval` with `JSON.parse`
|
100
|
+
- Use BigDecimal instead of Float
|
101
|
+
|
102
|
+
Bugfixes
|
103
|
+
--------
|
104
|
+
- Quell parenthetical warnings in specs
|
105
|
+
|
106
|
+
Google Currency 1.0.1
|
107
|
+
=====================
|
108
|
+
|
109
|
+
Features
|
110
|
+
--------
|
111
|
+
- Update `money` requirement to `~> 3.1.5`
|
112
|
+
|
113
|
+
Google Currency 1.0.0
|
114
|
+
=====================
|
115
|
+
|
116
|
+
Features
|
117
|
+
--------
|
118
|
+
- Updated `money` requirement to `~> 3.1.0`
|
119
|
+
|
120
|
+
Google Currency 0.1.1
|
121
|
+
=====================
|
122
|
+
|
123
|
+
Features
|
124
|
+
--------
|
125
|
+
- Added #flush_rates
|
126
|
+
- Added #flush_rate
|
127
|
+
|
128
|
+
Google Currency 0.1.0
|
129
|
+
=====================
|
130
|
+
|
131
|
+
Features
|
132
|
+
--------
|
133
|
+
- Initial release
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2010 Shane Emmons
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
Fixer Currency
|
2
|
+
===============
|
3
|
+
This gem extends Money::Bank::VariableExchange with Money::Bank::FixerCurrency
|
4
|
+
and gives you access to the current fixer.io exchange rates.
|
5
|
+
|
6
|
+
This gem was forked from the [Money::Bank::GoogleCurrency](http://rubymoney.github.com/google_currency)
|
7
|
+
gem.
|
8
|
+
|
9
|
+
Usage
|
10
|
+
-----
|
11
|
+
|
12
|
+
```ruby
|
13
|
+
|
14
|
+
require 'money'
|
15
|
+
require 'money/bank/fixer_currency'
|
16
|
+
|
17
|
+
# (optional)
|
18
|
+
# set the seconds after than the current rates are automatically expired
|
19
|
+
# by default, they never expire
|
20
|
+
Money::Bank::FixerCurrency.ttl_in_seconds = 86400
|
21
|
+
|
22
|
+
# set default bank to instance of FixerCurrency with access key parameter
|
23
|
+
# being your access_key from fixer.io
|
24
|
+
Money.default_bank = Money::Bank::FixerCurrency.new('your_access_key')
|
25
|
+
|
26
|
+
# create a new money object, and use the standard #exchange_to method
|
27
|
+
money = Money.new(1_00, "USD") # amount is in cents
|
28
|
+
money.exchange_to(:EUR)
|
29
|
+
|
30
|
+
# or install and use the 'monetize' gem
|
31
|
+
require 'monetize'
|
32
|
+
money = 1.to_money(:USD)
|
33
|
+
money.exchange_to(:EUR)
|
34
|
+
|
35
|
+
```
|
36
|
+
|
37
|
+
An `UnknownRate` will be thrown if `#exchange_to` is called with a `Currency`
|
38
|
+
that `Money` knows, but fixer.io does not.
|
39
|
+
|
40
|
+
An `UnknownCurrency` will be thrown if `#exchange_to` is called with a
|
41
|
+
`Currency` that `Money` does not know.
|
42
|
+
|
43
|
+
A `FixerCurrencyFetchError` will be thrown if there is an unknown issue with
|
44
|
+
parsing the response including rates from fixer.io's API.
|
45
|
+
|
46
|
+
Caveats
|
47
|
+
-------
|
48
|
+
|
49
|
+
This gem uses [fixer.io](https://fixer.io/) under the hood.
|
data/Rakefile
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake/clean'
|
3
|
+
|
4
|
+
CLOBBER.include('.yardoc', 'doc')
|
5
|
+
|
6
|
+
def gemspec
|
7
|
+
@gemspec ||= begin
|
8
|
+
file = File.expand_path("../fixer_currency.gemspec", __FILE__)
|
9
|
+
eval(File.read(file), binding, file)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
begin
|
14
|
+
require 'rspec/core/rake_task'
|
15
|
+
RSpec::Core::RakeTask.new
|
16
|
+
rescue LoadError
|
17
|
+
task(:spec){abort "`gem install rspec` to run specs"}
|
18
|
+
end
|
19
|
+
task :default => :spec
|
20
|
+
task :test => :spec
|
21
|
+
|
22
|
+
begin
|
23
|
+
require 'yard'
|
24
|
+
YARD::Rake::YardocTask.new do |t|
|
25
|
+
t.options << "--files" << "CHANGELOG.md,LICENSE"
|
26
|
+
end
|
27
|
+
rescue LoadError
|
28
|
+
task(:yard){abort "`gem install yard` to generate documentation"}
|
29
|
+
end
|
30
|
+
|
31
|
+
begin
|
32
|
+
require 'rubygems/package_task'
|
33
|
+
Gem::PackageTask.new(gemspec) do |pkg|
|
34
|
+
pkg.gem_spec = gemspec
|
35
|
+
end
|
36
|
+
task :gem => :gemspec
|
37
|
+
rescue LoadError
|
38
|
+
task(:gem){abort "`gem install rake` to package gems"}
|
39
|
+
end
|
40
|
+
|
41
|
+
desc "Install the gem locally"
|
42
|
+
task :install => :gem do
|
43
|
+
sh "gem install pkg/#{gemspec.full_name}.gem"
|
44
|
+
end
|
45
|
+
|
46
|
+
desc "Validate the gemspec"
|
47
|
+
task :gemspec do
|
48
|
+
gemspec.validate
|
49
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = 'fixer_currency'
|
3
|
+
s.version = '3.4.2'
|
4
|
+
s.platform = Gem::Platform::RUBY
|
5
|
+
s.authors = ['Emily Wilson']
|
6
|
+
s.email = ['emilywilson@privy.com']
|
7
|
+
s.homepage = 'https://github.com/Privy/fixer_currency'
|
8
|
+
s.summary = 'Access the fixer.io exchange rate data.'
|
9
|
+
s.description = 'FixerCurrency extends Money::Bank::Base and gives you access
|
10
|
+
to the current fixer.io exchange rates.'
|
11
|
+
s.license = 'MIT'
|
12
|
+
|
13
|
+
s.add_development_dependency 'ffi'
|
14
|
+
s.add_development_dependency 'rspec', '>= 3.0.0'
|
15
|
+
s.add_development_dependency 'yard', '>= 0.5.8'
|
16
|
+
|
17
|
+
s.add_dependency 'money', '~> 6.7'
|
18
|
+
|
19
|
+
s.files = Dir.glob('{lib,spec}/**/*')
|
20
|
+
s.files += %w(LICENSE README.md CHANGELOG.md AUTHORS)
|
21
|
+
s.files += %w(Rakefile .gemtest fixer_currency.gemspec)
|
22
|
+
|
23
|
+
s.require_path = 'lib'
|
24
|
+
end
|
@@ -0,0 +1,162 @@
|
|
1
|
+
require 'money'
|
2
|
+
require 'money/rates_store/rate_removal_support'
|
3
|
+
require 'open-uri'
|
4
|
+
|
5
|
+
class Money
|
6
|
+
module Bank
|
7
|
+
# # Raised when there is an unexpected error in extracting exchange rates
|
8
|
+
# # from fixer.io
|
9
|
+
class FixerCurrencyFetchError < Error
|
10
|
+
end
|
11
|
+
|
12
|
+
# VariableExchange bank that handles fetching exchange rates from fixer.io
|
13
|
+
# and storing them in the in memory rates store.
|
14
|
+
class FixerCurrency < Money::Bank::VariableExchange
|
15
|
+
SERVICE_HOST = 'data.fixer.io'.freeze
|
16
|
+
SERVICE_PATH = '/api/latest'.freeze
|
17
|
+
|
18
|
+
# @return [Hash] Stores the currently known rates.
|
19
|
+
attr_reader :rates
|
20
|
+
|
21
|
+
# @return [String] Access key from fixer.io allowing access to API
|
22
|
+
attr_accessor :access_key
|
23
|
+
|
24
|
+
class << self
|
25
|
+
# @return [Integer] Returns the Time To Live (TTL) in seconds.
|
26
|
+
attr_reader :ttl_in_seconds
|
27
|
+
|
28
|
+
# @return [Time] Returns the time when the rates expire.
|
29
|
+
attr_reader :rates_expiration
|
30
|
+
|
31
|
+
##
|
32
|
+
# Set the Time To Live (TTL) in seconds.
|
33
|
+
#
|
34
|
+
# @param [Integer] the seconds between an expiration and another.
|
35
|
+
def ttl_in_seconds=(value)
|
36
|
+
@ttl_in_seconds = value
|
37
|
+
refresh_rates_expiration! if ttl_in_seconds
|
38
|
+
end
|
39
|
+
|
40
|
+
##
|
41
|
+
# Set the rates expiration TTL seconds from the current time.
|
42
|
+
#
|
43
|
+
# @return [Time] The next expiration.
|
44
|
+
def refresh_rates_expiration!
|
45
|
+
@rates_expiration = Time.now + ttl_in_seconds
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def initialize(access_key)
|
50
|
+
super()
|
51
|
+
@store.extend Money::RatesStore::RateRemovalSupport
|
52
|
+
@access_key = access_key
|
53
|
+
end
|
54
|
+
|
55
|
+
##
|
56
|
+
# Clears all rates stored in @rates
|
57
|
+
#
|
58
|
+
# @return [Hash] The empty @rates Hash.
|
59
|
+
#
|
60
|
+
# @example
|
61
|
+
# @bank = FixerCurrency.new #=> <Money::Bank::FixerCurrency...>
|
62
|
+
# @bank.get_rate(:USD, :EUR) #=> 0.776337241
|
63
|
+
# @bank.flush_rates #=> {}
|
64
|
+
def flush_rates
|
65
|
+
store.clear_rates
|
66
|
+
end
|
67
|
+
|
68
|
+
##
|
69
|
+
# Clears the specified rate stored in @rates.
|
70
|
+
#
|
71
|
+
# @param [String, Symbol, Currency] from Currency to convert from (used
|
72
|
+
# for key into @rates).
|
73
|
+
# @param [String, Symbol, Currency] to Currency to convert to (used for
|
74
|
+
# key into @rates).
|
75
|
+
#
|
76
|
+
# @return [Float] The flushed rate.
|
77
|
+
#
|
78
|
+
# @example
|
79
|
+
# @bank = FixerCurrency.new #=> <Money::Bank::FixerCurrency...>
|
80
|
+
# @bank.get_rate(:USD, :EUR) #=> 0.776337241
|
81
|
+
# @bank.flush_rate(:USD, :EUR) #=> 0.776337241
|
82
|
+
def flush_rate(from, to)
|
83
|
+
store.remove_rate(from, to)
|
84
|
+
end
|
85
|
+
|
86
|
+
##
|
87
|
+
# Returns the requested rate.
|
88
|
+
#
|
89
|
+
# It also flushes all the rates when and if they are expired.
|
90
|
+
#
|
91
|
+
# @param [String, Symbol, Currency] from Currency to convert from
|
92
|
+
# @param [String, Symbol, Currency] to Currency to convert to
|
93
|
+
#
|
94
|
+
# @return [Float] The requested rate.
|
95
|
+
#
|
96
|
+
# @example
|
97
|
+
# @bank = FixerCurrency.new #=> <Money::Bank::FixerCurrency...>
|
98
|
+
# @bank.get_rate(:USD, :EUR) #=> 0.776337241
|
99
|
+
def get_rate(from, to)
|
100
|
+
expire_rates
|
101
|
+
|
102
|
+
fetch_rates if !store.get_rate(from, :EUR) || !store.get_rate(to, :EUR)
|
103
|
+
|
104
|
+
begin
|
105
|
+
return store.get_rate(from, :EUR) / store.get_rate(to, :EUR)
|
106
|
+
rescue
|
107
|
+
raise UnknownRate
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
##
|
112
|
+
# Flushes all the rates if they are expired.
|
113
|
+
#
|
114
|
+
# @return [Boolean]
|
115
|
+
def expire_rates
|
116
|
+
if self.class.ttl_in_seconds && self.class.rates_expiration <= Time.now
|
117
|
+
flush_rates
|
118
|
+
self.class.refresh_rates_expiration!
|
119
|
+
true
|
120
|
+
else
|
121
|
+
false
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
private
|
126
|
+
|
127
|
+
##
|
128
|
+
# Makes an api call to populate all of the exchange rates in the in
|
129
|
+
# memory store.
|
130
|
+
def fetch_rates
|
131
|
+
data = build_uri.read
|
132
|
+
extract_rates(data)
|
133
|
+
end
|
134
|
+
|
135
|
+
##
|
136
|
+
# Build a URI for the given arguments.
|
137
|
+
#
|
138
|
+
# @return [URI::HTTP]
|
139
|
+
def build_uri
|
140
|
+
URI::HTTP.build(
|
141
|
+
host: SERVICE_HOST,
|
142
|
+
path: SERVICE_PATH,
|
143
|
+
query: "access_key=#{access_key}"
|
144
|
+
)
|
145
|
+
end
|
146
|
+
|
147
|
+
##
|
148
|
+
# Takes the response from fixer.io and extract the rates and adds them to
|
149
|
+
# the rates store.
|
150
|
+
#
|
151
|
+
# @param [String] data The hash of rates from fixer to decode.
|
152
|
+
def extract_rates(data)
|
153
|
+
rates = JSON.parse(data)['rates']
|
154
|
+
rates.each do |currency, rate|
|
155
|
+
store.add_rate(currency, :EUR, 1 / BigDecimal(rate.to_s))
|
156
|
+
end
|
157
|
+
rescue
|
158
|
+
raise FixerCurrencyFetchError
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Money::RatesStore
|
2
|
+
module RateRemovalSupport
|
3
|
+
# Remove a conversion rate and returns it. Uses +Mutex+ to synchronize data access.
|
4
|
+
#
|
5
|
+
# @param [String] currency_iso_from Currency to exchange from.
|
6
|
+
# @param [String] currency_iso_to Currency to exchange to.
|
7
|
+
#
|
8
|
+
# @return [Numeric]
|
9
|
+
#
|
10
|
+
# @example
|
11
|
+
# store = Money::RatesStore::Memory.new
|
12
|
+
# store.remove_rate("USD", "CAD")
|
13
|
+
# store.remove_rate("CAD", "USD")
|
14
|
+
def remove_rate(currency_iso_from, currency_iso_to)
|
15
|
+
transaction { index.delete rate_key_for(currency_iso_from, currency_iso_to) }
|
16
|
+
end
|
17
|
+
|
18
|
+
# Clears all conversion rates. Uses +Mutex+ to synchronize data access.
|
19
|
+
#
|
20
|
+
# @example
|
21
|
+
# store = Money::RatesStore::Memory.new
|
22
|
+
# store.clear_rates
|
23
|
+
def clear_rates
|
24
|
+
transaction { @index = {} }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,142 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
require 'money'
|
4
|
+
require 'money/bank/fixer_currency'
|
5
|
+
|
6
|
+
describe Money::Bank::FixerCurrency do
|
7
|
+
before :each do
|
8
|
+
@bank = Money::Bank::FixerCurrency.new('123')
|
9
|
+
end
|
10
|
+
|
11
|
+
context 'given ttl_in_seconds' do
|
12
|
+
before(:each) do
|
13
|
+
Money::Bank::FixerCurrency.ttl_in_seconds = 86_400
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'should accept a ttl_in_seconds option' do
|
17
|
+
expect(Money::Bank::FixerCurrency.ttl_in_seconds).to eq(86_400)
|
18
|
+
end
|
19
|
+
|
20
|
+
describe '.refresh_rates_expiration!' do
|
21
|
+
it 'set the #rates_expiration using the TTL and the current time' do
|
22
|
+
new_time = Time.now
|
23
|
+
Timecop.freeze(new_time)
|
24
|
+
Money::Bank::FixerCurrency.refresh_rates_expiration!
|
25
|
+
expect(Money::Bank::FixerCurrency.rates_expiration)
|
26
|
+
.to eq(new_time + 86_400)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe '#get_rate' do
|
32
|
+
before(:each) do
|
33
|
+
@bank.flush_rates
|
34
|
+
@bank.store.add_rate(:EUR, :EUR, 1.0)
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'should try to expire the rates' do
|
38
|
+
expect(@bank).to receive(:expire_rates).once
|
39
|
+
@bank.get_rate(:EUR, :EUR)
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'should return the correct rate' do
|
43
|
+
expect(@bank.get_rate(:EUR, :EUR)).to eq(1.0)
|
44
|
+
end
|
45
|
+
|
46
|
+
context 'when rate is unknown' do
|
47
|
+
before(:each) do
|
48
|
+
@bank.flush_rates
|
49
|
+
allow(@bank).to receive(:fetch_rates) do
|
50
|
+
@bank.store.add_rate(:EUR, :EUR, 1.0)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'should call #fetch_rates' do
|
55
|
+
expect(@bank).to receive(:fetch_rates).once
|
56
|
+
@bank.get_rate(:EUR, :EUR)
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'should store the rate for faster retreival' do
|
60
|
+
@bank.get_rate(:EUR, :EUR)
|
61
|
+
expect(@bank.store.instance_variable_get('@index'))
|
62
|
+
.to include('EUR_TO_EUR')
|
63
|
+
end
|
64
|
+
|
65
|
+
context 'when exhange rate is not found' do
|
66
|
+
it 'should raise UnknownRate error' do
|
67
|
+
expect { @bank.get_rate('VND', :USD) }
|
68
|
+
.to raise_error(Money::Bank::UnknownRate)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
context 'when rate is known' do
|
74
|
+
it 'should not use #fetch_rates' do
|
75
|
+
expect(@bank).to_not receive(:fetch_rates)
|
76
|
+
@bank.get_rate(:EUR, :EUR)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
describe '#flush_rates' do
|
82
|
+
before(:each) do
|
83
|
+
@bank.store.add_rate(:EUR, :EUR, 1.0)
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'should empty @rates' do
|
87
|
+
@bank.get_rate(:EUR, :EUR)
|
88
|
+
@bank.flush_rates
|
89
|
+
expect(@bank.store.instance_variable_get('@index')).to eq({})
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
describe '#flush_rate' do
|
94
|
+
before(:each) do
|
95
|
+
allow(@bank).to(receive(:fetch_rates).once) do
|
96
|
+
@bank.store.add_rate('JPY', :EUR, 107)
|
97
|
+
@bank.store.add_rate(:USD, :EUR, 1.2)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'should remove a specific rate from @rates' do
|
102
|
+
@bank.get_rate(:USD, :JPY)
|
103
|
+
@bank.flush_rate(:USD, :EUR)
|
104
|
+
expect(@bank.store.instance_variable_get('@index'))
|
105
|
+
.to include('JPY_TO_EUR')
|
106
|
+
expect(@bank.store.instance_variable_get('@index'))
|
107
|
+
.to_not include('USD_TO_EUR')
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
describe '#expire_rates' do
|
112
|
+
before do
|
113
|
+
Money::Bank::FixerCurrency.ttl_in_seconds = 1000
|
114
|
+
end
|
115
|
+
|
116
|
+
context 'when the ttl has expired' do
|
117
|
+
before do
|
118
|
+
new_time = Time.now + 1001
|
119
|
+
Timecop.freeze(new_time)
|
120
|
+
end
|
121
|
+
|
122
|
+
it 'should flush all rates' do
|
123
|
+
expect(@bank).to receive(:flush_rates)
|
124
|
+
@bank.expire_rates
|
125
|
+
end
|
126
|
+
|
127
|
+
it 'updates the next expiration time' do
|
128
|
+
exp_time = Time.now + 1000
|
129
|
+
|
130
|
+
@bank.expire_rates
|
131
|
+
expect(Money::Bank::FixerCurrency.rates_expiration).to eq(exp_time)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
context 'when the ttl has not expired' do
|
136
|
+
it 'not should flush all rates' do
|
137
|
+
expect(@bank).to_not receive(:flush_rates)
|
138
|
+
@bank.expire_rates
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: fixer_currency
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 3.4.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Emily Wilson
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-07-06 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: ffi
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rspec
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 3.0.0
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 3.0.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: yard
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 0.5.8
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 0.5.8
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: money
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '6.7'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '6.7'
|
69
|
+
description: |-
|
70
|
+
FixerCurrency extends Money::Bank::Base and gives you access
|
71
|
+
to the current fixer.io exchange rates.
|
72
|
+
email:
|
73
|
+
- emilywilson@privy.com
|
74
|
+
executables: []
|
75
|
+
extensions: []
|
76
|
+
extra_rdoc_files: []
|
77
|
+
files:
|
78
|
+
- ".gemtest"
|
79
|
+
- AUTHORS
|
80
|
+
- CHANGELOG.md
|
81
|
+
- LICENSE
|
82
|
+
- README.md
|
83
|
+
- Rakefile
|
84
|
+
- fixer_currency.gemspec
|
85
|
+
- lib/money/bank/fixer_currency.rb
|
86
|
+
- lib/money/rates_store/rate_removal_support.rb
|
87
|
+
- spec/fixer_currency_with_json_spec.rb
|
88
|
+
- spec/spec_helper.rb
|
89
|
+
homepage: https://github.com/Privy/fixer_currency
|
90
|
+
licenses:
|
91
|
+
- MIT
|
92
|
+
metadata: {}
|
93
|
+
post_install_message:
|
94
|
+
rdoc_options: []
|
95
|
+
require_paths:
|
96
|
+
- lib
|
97
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
98
|
+
requirements:
|
99
|
+
- - ">="
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
103
|
+
requirements:
|
104
|
+
- - ">="
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
version: '0'
|
107
|
+
requirements: []
|
108
|
+
rubyforge_project:
|
109
|
+
rubygems_version: 2.7.6
|
110
|
+
signing_key:
|
111
|
+
specification_version: 4
|
112
|
+
summary: Access the fixer.io exchange rate data.
|
113
|
+
test_files: []
|