exchange 0.6.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +54 -0
- data/.travis.yml +4 -0
- data/Gemfile +1 -12
- data/Gemfile.lock +14 -28
- data/README.rdoc +91 -68
- data/changelog.rdoc +20 -1
- data/exchange-0.7.5.gem +0 -0
- data/exchange-0.7.6.gem +0 -0
- data/exchange.gemspec +22 -102
- data/lib/core_extensions/conversability.rb +5 -3
- data/lib/exchange/base.rb +1 -1
- data/lib/exchange/cache/base.rb +11 -3
- data/lib/exchange/cache/memcached.rb +4 -3
- data/lib/exchange/configuration.rb +5 -14
- data/lib/exchange/currency.rb +69 -19
- data/lib/exchange/external_api/base.rb +75 -15
- data/lib/exchange/external_api/call.rb +7 -4
- data/lib/exchange/external_api/currency_bot.rb +12 -2
- data/lib/exchange/external_api/ecb.rb +62 -8
- data/lib/exchange/external_api/json.rb +3 -13
- data/lib/exchange/external_api/xavier_media.rb +51 -8
- data/lib/exchange/helper.rb +1 -1
- data/lib/exchange/iso_4217.rb +1 -0
- data/spec/exchange/cache/memcached_spec.rb +41 -15
- data/spec/exchange/currency_spec.rb +185 -7
- data/spec/exchange/external_api/call_spec.rb +2 -2
- data/spec/spec_helper.rb +0 -1
- metadata +37 -31
- data/VERSION +0 -1
data/exchange-0.7.5.gem
ADDED
Binary file
|
data/exchange-0.7.6.gem
ADDED
Binary file
|
data/exchange.gemspec
CHANGED
@@ -1,107 +1,27 @@
|
|
1
|
-
# Generated by jeweler
|
2
|
-
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
-
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
1
|
# -*- encoding: utf-8 -*-
|
2
|
+
$LOAD_PATH << File.join(File.dirname(__FILE__), 'lib')
|
3
|
+
require 'exchange/base'
|
5
4
|
|
6
5
|
Gem::Specification.new do |s|
|
7
|
-
s.name
|
8
|
-
s.version
|
9
|
-
|
10
|
-
s.
|
11
|
-
s.
|
12
|
-
s.
|
13
|
-
s.
|
14
|
-
s.
|
15
|
-
s.
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
s.files
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
"Rakefile",
|
28
|
-
"VERSION",
|
29
|
-
"changelog.rdoc",
|
30
|
-
"exchange.gemspec",
|
31
|
-
"iso4217.yml",
|
32
|
-
"lib/core_extensions/conversability.rb",
|
33
|
-
"lib/exchange.rb",
|
34
|
-
"lib/exchange/base.rb",
|
35
|
-
"lib/exchange/cache.rb",
|
36
|
-
"lib/exchange/cache/base.rb",
|
37
|
-
"lib/exchange/cache/file.rb",
|
38
|
-
"lib/exchange/cache/memcached.rb",
|
39
|
-
"lib/exchange/cache/no_cache.rb",
|
40
|
-
"lib/exchange/cache/rails.rb",
|
41
|
-
"lib/exchange/cache/redis.rb",
|
42
|
-
"lib/exchange/configuration.rb",
|
43
|
-
"lib/exchange/currency.rb",
|
44
|
-
"lib/exchange/external_api.rb",
|
45
|
-
"lib/exchange/external_api/base.rb",
|
46
|
-
"lib/exchange/external_api/call.rb",
|
47
|
-
"lib/exchange/external_api/currency_bot.rb",
|
48
|
-
"lib/exchange/external_api/ecb.rb",
|
49
|
-
"lib/exchange/external_api/json.rb",
|
50
|
-
"lib/exchange/external_api/xavier_media.rb",
|
51
|
-
"lib/exchange/external_api/xml.rb",
|
52
|
-
"lib/exchange/gem_loader.rb",
|
53
|
-
"lib/exchange/helper.rb",
|
54
|
-
"lib/exchange/iso_4217.rb",
|
55
|
-
"spec/core_extensions/conversability_spec.rb",
|
56
|
-
"spec/exchange/cache/base_spec.rb",
|
57
|
-
"spec/exchange/cache/file_spec.rb",
|
58
|
-
"spec/exchange/cache/memcached_spec.rb",
|
59
|
-
"spec/exchange/cache/no_cache_spec.rb",
|
60
|
-
"spec/exchange/cache/rails_spec.rb",
|
61
|
-
"spec/exchange/cache/redis_spec.rb",
|
62
|
-
"spec/exchange/configuration_spec.rb",
|
63
|
-
"spec/exchange/currency_spec.rb",
|
64
|
-
"spec/exchange/external_api/base_spec.rb",
|
65
|
-
"spec/exchange/external_api/call_spec.rb",
|
66
|
-
"spec/exchange/external_api/currency_bot_spec.rb",
|
67
|
-
"spec/exchange/external_api/ecb_spec.rb",
|
68
|
-
"spec/exchange/external_api/xavier_media_spec.rb",
|
69
|
-
"spec/exchange/gem_loader_spec.rb",
|
70
|
-
"spec/exchange/helper_spec.rb",
|
71
|
-
"spec/exchange/iso_4217_spec.rb",
|
72
|
-
"spec/spec_helper.rb",
|
73
|
-
"spec/support/api_responses/example_ecb_xml_90d.xml",
|
74
|
-
"spec/support/api_responses/example_ecb_xml_daily.xml",
|
75
|
-
"spec/support/api_responses/example_ecb_xml_history.xml",
|
76
|
-
"spec/support/api_responses/example_historic_json.json",
|
77
|
-
"spec/support/api_responses/example_json_api.json",
|
78
|
-
"spec/support/api_responses/example_xml_api.xml"
|
79
|
-
]
|
80
|
-
s.homepage = "http://github.com/beatrichartz/exchange"
|
81
|
-
s.licenses = ["MIT"]
|
82
|
-
s.require_paths = ["lib"]
|
83
|
-
s.rubygems_version = "1.8.24"
|
84
|
-
s.summary = "Simple Exchange Rate operations for your ruby app"
|
85
|
-
|
86
|
-
if s.respond_to? :specification_version then
|
87
|
-
s.specification_version = 3
|
88
|
-
|
89
|
-
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
90
|
-
s.add_runtime_dependency(%q<exchange>, [">= 0"])
|
91
|
-
s.add_development_dependency(%q<yard>, ["~> 0.7.4"])
|
92
|
-
s.add_development_dependency(%q<bundler>, [">= 1.0.0"])
|
93
|
-
s.add_development_dependency(%q<jeweler>, ["~> 1.8.3"])
|
94
|
-
else
|
95
|
-
s.add_dependency(%q<exchange>, [">= 0"])
|
96
|
-
s.add_dependency(%q<yard>, ["~> 0.7.4"])
|
97
|
-
s.add_dependency(%q<bundler>, [">= 1.0.0"])
|
98
|
-
s.add_dependency(%q<jeweler>, ["~> 1.8.3"])
|
99
|
-
end
|
100
|
-
else
|
101
|
-
s.add_dependency(%q<exchange>, [">= 0"])
|
102
|
-
s.add_dependency(%q<yard>, ["~> 0.7.4"])
|
103
|
-
s.add_dependency(%q<bundler>, [">= 1.0.0"])
|
104
|
-
s.add_dependency(%q<jeweler>, ["~> 1.8.3"])
|
105
|
-
end
|
6
|
+
s.name = "exchange"
|
7
|
+
s.version = Exchange::VERSION
|
8
|
+
s.authors = ["Beat Richartz"]
|
9
|
+
s.date = "2012-10-09"
|
10
|
+
s.description = "The Exchange Gem gives you easy access to currency functions directly on your Numbers. Imagine a conversion as easy as \n 1.eur.to_usd\n or even better \n 1.eur.to_usd(:at => Time.now - 84600)\n which gets you an exchange at the rates of yesterday."
|
11
|
+
s.email = "exchange_gem@gmail.com"
|
12
|
+
s.homepage = "http://github.com/beatrichartz/exchange"
|
13
|
+
s.licenses = ["MIT"]
|
14
|
+
s.require_paths = ["lib"]
|
15
|
+
s.rubygems_version = "1.8.24"
|
16
|
+
s.summary = "Simple Exchange Rate operations for your ruby app"
|
17
|
+
|
18
|
+
s.files = `git ls-files`.split("\n")
|
19
|
+
s.test_files = `git ls-files -- spec/*`.split("\n")
|
20
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
21
|
+
s.require_paths = ["lib"]
|
22
|
+
|
23
|
+
s.add_dependency "json", ">= 1.0.0"
|
24
|
+
s.add_development_dependency "yard", ">= 0.7.4"
|
25
|
+
s.add_development_dependency "bundler", ">= 1.0.0"
|
106
26
|
end
|
107
27
|
|
@@ -24,6 +24,9 @@ module Exchange
|
|
24
24
|
# 1.nok.to_chf(:at => Time.now - 3600) => #<Exchange::Currency @value=6.57 @currency=:chf>
|
25
25
|
# -3.5.dkk.to_huf(:at => Time.now - 172800) => #<Exchange::Currency @value=-337.40 @currency=:huf>
|
26
26
|
#
|
27
|
+
# @since 0.1
|
28
|
+
# @version 0.2
|
29
|
+
#
|
27
30
|
ISO4217.definitions.keys.each do |c|
|
28
31
|
define_method c.downcase.to_sym do |*args|
|
29
32
|
Currency.new(self, c, *args)
|
@@ -33,6 +36,5 @@ module Exchange
|
|
33
36
|
end
|
34
37
|
end
|
35
38
|
|
36
|
-
|
37
|
-
|
38
|
-
BigDecimal.send :include, Exchange::Conversability
|
39
|
+
# include the Conversability methods in all number operations. Stack traces will indicate the module if something goes wrong.
|
40
|
+
Numeric.send :include, Exchange::Conversability
|
data/lib/exchange/base.rb
CHANGED
data/lib/exchange/cache/base.rb
CHANGED
@@ -7,15 +7,23 @@ module Exchange
|
|
7
7
|
# @example Write your own caching module
|
8
8
|
# module Cache
|
9
9
|
# class MyCustomCache < Base
|
10
|
-
# #
|
10
|
+
# # A cache class has to have the method "cached".
|
11
|
+
# # The cache Base is a singleton and forwards the method "cached"
|
12
|
+
# # to the instance
|
13
|
+
# #
|
11
14
|
# def cached api, opts={}, &block
|
12
|
-
# # generate the
|
15
|
+
# # generate the storage with key(api, opts[:at]) and you will get a
|
16
|
+
# # unique key to store in your cache
|
17
|
+
# #
|
13
18
|
# # Your code goes here
|
14
19
|
# end
|
15
20
|
# end
|
16
21
|
# end
|
22
|
+
#
|
17
23
|
# # Now, you can configure your Caching solution in the configuration. The Symbol will get camelcased and constantized
|
18
|
-
#
|
24
|
+
# #
|
25
|
+
# Exchange.configuration.cache.subclass = :my_custom_cache
|
26
|
+
#
|
19
27
|
# # Have fun, and don't forget to write tests.
|
20
28
|
|
21
29
|
module Cache
|
@@ -30,11 +30,12 @@ module Exchange
|
|
30
30
|
# @param [Exchange::ExternalAPI::Subclass] api The API class the data has to be stored for
|
31
31
|
# @param [Hash] opts the options to cache with
|
32
32
|
# @option opts [Time] :at the historic time of the exchange rates to be cached
|
33
|
-
# @yield [] This method takes a mandatory block with an arity of 0
|
33
|
+
# @yield [] This method takes a mandatory block with an arity of 0 for caching
|
34
34
|
# @raise [CachingWithoutBlockError] an Argument Error when no mandatory block has been given
|
35
|
-
|
35
|
+
#
|
36
36
|
def cached api, opts={}, &block
|
37
|
-
|
37
|
+
stored = client.get(key(api, opts))
|
38
|
+
result = opts[:plain] ? stored.to_s.gsub(/["\s+]/, '') : JSON.load(stored) if stored && !stored.empty?
|
38
39
|
|
39
40
|
unless result
|
40
41
|
result = super
|
@@ -52,9 +52,10 @@ module Exchange
|
|
52
52
|
#
|
53
53
|
def install_getter key, parent_module
|
54
54
|
define_method key do
|
55
|
-
|
56
|
-
|
57
|
-
|
55
|
+
config_part = @config[key]
|
56
|
+
config_part = OpenStruct.new(config_part) unless config_part.is_a?(OpenStruct)
|
57
|
+
config_part.subclass = parent_module.const_get camelize(config_part.subclass) unless config_part.subclass.is_a?(Class)
|
58
|
+
@config[key] = config_part
|
58
59
|
end
|
59
60
|
end
|
60
61
|
|
@@ -89,20 +90,10 @@ module Exchange
|
|
89
90
|
# Exchange::Configuration.new do |c|
|
90
91
|
# c.allow_mixed_operations = false
|
91
92
|
# c.cache = {
|
92
|
-
# :subclass => Cache::Redis,
|
93
|
+
# :subclass => Exhange::Cache::Redis,
|
93
94
|
# :expire => :hourly
|
94
95
|
# }
|
95
96
|
#
|
96
|
-
# @yield [Exchange::Configuration] yields an instance of the configuration class
|
97
|
-
# @yieldparam [optional, Symbol] cache The cache type to use. Possible Values: :redis, :memcached or :rails or false to disable caching. Defaults to :memcached
|
98
|
-
# @yieldparam [optional, String] cache_host A string with the hostname or IP to set the cache host to. Does not have to be set for Rails cache
|
99
|
-
# @yieldparam [optional, Integer] cache_port An integer for the cache port. Does not have to be set for Rails cache
|
100
|
-
# @yieldparam [optional, Symbol] api The API to use. Possible Values: :currency_bot (Open Source currency bot API) or :xavier_media (Xavier Media API). Defaults to :currency_bot
|
101
|
-
# @yieldparam [optional, Integer] retries The number of times the gem should retry to connect to the api host. Defaults to 5.
|
102
|
-
# @yieldparam [optional, Boolean] If set to false, Operations with with different currencies raise errors. Defaults to true.
|
103
|
-
# @yieldparam [optional, Symbol] The regularity of updates for the API. Possible values: :daily, :hourly. Defaults to :daily.
|
104
|
-
# @yieldparam [optional, String] The path where files can be stored for the gem (used for large files from ECB). Make sure ruby has write access.
|
105
|
-
#
|
106
97
|
def initialize configuration={}, &block
|
107
98
|
@config = DEFAULTS.merge(configuration)
|
108
99
|
self.instance_eval(&block) if block_given?
|
data/lib/exchange/currency.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Top Level Module of the the gem.
|
2
2
|
# @author Beat Richartz
|
3
|
-
# @version 0.
|
3
|
+
# @version 0.7
|
4
4
|
# @since 0.1
|
5
5
|
|
6
6
|
module Exchange
|
@@ -32,6 +32,10 @@ module Exchange
|
|
32
32
|
#
|
33
33
|
attr_reader :from
|
34
34
|
|
35
|
+
# @attr_reader
|
36
|
+
# @return [Exchange::ExternalAPI] The current api subclass
|
37
|
+
attr_reader :api
|
38
|
+
|
35
39
|
# Intialize the currency with a number and a currency
|
36
40
|
# @param [Integer, Float] number The number the currency is instantiated from
|
37
41
|
# @param [String, Symbol] currency The currency the currency object is in
|
@@ -52,6 +56,7 @@ module Exchange
|
|
52
56
|
@currency = currency
|
53
57
|
@time = Helper.assure_time(opts[:at], :default => :now)
|
54
58
|
@from = opts[:from]
|
59
|
+
@api = Exchange.configuration.api.subclass
|
55
60
|
end
|
56
61
|
|
57
62
|
# Method missing is used to handle conversions from one currency object to another. It only handles currencies which are available in
|
@@ -62,14 +67,16 @@ module Exchange
|
|
62
67
|
# Exchange::Currency.new(40,:nok).to_sek(:at => Time.gm(2012,2,2))
|
63
68
|
#
|
64
69
|
def method_missing method, *args, &block
|
65
|
-
match
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
+
match = method.to_s.match /\Ato_(\w{3})$/
|
71
|
+
currency = $1
|
72
|
+
|
73
|
+
if match && api_supports_currency?(currency)
|
74
|
+
return convert_to currency, { :at => time }.merge(args.first || {})
|
75
|
+
elsif match
|
76
|
+
test_for_no_rate_error(currency)
|
70
77
|
end
|
71
78
|
|
72
|
-
|
79
|
+
value.send method, *args, &block
|
73
80
|
end
|
74
81
|
|
75
82
|
# Converts this instance of currency into another currency
|
@@ -95,21 +102,20 @@ module Exchange
|
|
95
102
|
#
|
96
103
|
def install_operation op
|
97
104
|
define_method op do |*precision|
|
98
|
-
|
99
|
-
self
|
105
|
+
Exchange::Currency.new(ISO4217.send(op, self.value, self.currency, precision.first), currency, :at => time, :from => self)
|
100
106
|
end
|
101
107
|
end
|
102
108
|
|
103
109
|
# @private
|
104
110
|
# @macro [attach] base_operations
|
105
111
|
# @method $1(other)
|
106
|
-
#
|
112
|
+
#
|
107
113
|
def base_operation op
|
108
114
|
self.class_eval <<-EOV
|
109
115
|
def #{op}(other)
|
110
|
-
|
111
|
-
|
112
|
-
self
|
116
|
+
test_for_currency_mix_error(other)
|
117
|
+
new_value = value #{op} (other.kind_of?(Currency) ? other.convert_to(self.currency, :at => other.time) : other)
|
118
|
+
Exchange::Currency.new(new_value, currency, :at => time, :from => self)
|
113
119
|
end
|
114
120
|
EOV
|
115
121
|
end
|
@@ -121,7 +127,7 @@ module Exchange
|
|
121
127
|
# @return [Exchange::Currency] The currency you started with with a rounded value
|
122
128
|
# @param [Integer] precision The precision you want the rounding to have. Defaults to the ISO 4217 standard value for the currency
|
123
129
|
# @since 0.1
|
124
|
-
# @version 0.
|
130
|
+
# @version 0.7.1
|
125
131
|
# @example Round your currency to the iso standard number of decimals
|
126
132
|
# Exchange::Currency.new(40.545, :usd).round
|
127
133
|
# #=> #<Exchange::Currency @value=40.55 @currency=:usd>
|
@@ -137,7 +143,7 @@ module Exchange
|
|
137
143
|
# @return [Exchange::Currency] The currency you started with with a ceiled value
|
138
144
|
# @param [Integer] precision The precision you want the ceiling to have. Defaults to the ISO 4217 standard value for the currency
|
139
145
|
# @since 0.1
|
140
|
-
# @version 0.
|
146
|
+
# @version 0.7.1
|
141
147
|
# @example Ceil your currency to the iso standard number of decimals
|
142
148
|
# Exchange::Currency.new(40.544, :usd).ceil
|
143
149
|
# #=> #<Exchange::Currency @value=40.55 @currency=:usd>
|
@@ -153,7 +159,7 @@ module Exchange
|
|
153
159
|
# @return [Exchange::Currency] The currency you started with with a floored value
|
154
160
|
# @param [Integer] precision The precision you want the flooring to have. Defaults to the ISO 4217 standard value for the currency
|
155
161
|
# @since 0.1
|
156
|
-
# @version 0.
|
162
|
+
# @version 0.7.1
|
157
163
|
# @example Floor your currency to the iso standard number of decimals
|
158
164
|
# Exchange::Currency.new(40.545, :usd).floor
|
159
165
|
# #=> #<Exchange::Currency @value=40.54 @currency=:usd>
|
@@ -175,6 +181,8 @@ module Exchange
|
|
175
181
|
# @example Configuration allows mixed operations (default)
|
176
182
|
# Exchange::Currency.new(20,:nok) + Exchange::Currency.new(20,:sek)
|
177
183
|
# #=> #<Exchange::Currency @value=37.56 @currency=:nok>
|
184
|
+
# @since 0.1
|
185
|
+
# @version 0.7
|
178
186
|
#
|
179
187
|
base_operation '+'
|
180
188
|
|
@@ -189,6 +197,8 @@ module Exchange
|
|
189
197
|
# @example Configuration allows mixed operations (default)
|
190
198
|
# Exchange::Currency.new(20,:nok) - Exchange::Currency.new(20,:sek)
|
191
199
|
# #=> #<Exchange::Currency @value=7.56 @currency=:nok>
|
200
|
+
# @since 0.1
|
201
|
+
# @version 0.7
|
192
202
|
#
|
193
203
|
base_operation '-'
|
194
204
|
|
@@ -203,6 +213,8 @@ module Exchange
|
|
203
213
|
# @example Configuration allows mixed operations (default)
|
204
214
|
# Exchange::Currency.new(20,:nok) * Exchange::Currency.new(20,:sek)
|
205
215
|
# #=> #<Exchange::Currency @value=70.56 @currency=:nok>
|
216
|
+
# @since 0.1
|
217
|
+
# @version 0.7
|
206
218
|
#
|
207
219
|
base_operation '*'
|
208
220
|
|
@@ -217,6 +229,8 @@ module Exchange
|
|
217
229
|
# @example Configuration allows mixed operations (default)
|
218
230
|
# Exchange::Currency.new(20,:nok) / Exchange::Currency.new(20,:sek)
|
219
231
|
# #=> #<Exchange::Currency @value=1.56 @currency=:nok>
|
232
|
+
# @since 0.1
|
233
|
+
# @version 0.7
|
220
234
|
#
|
221
235
|
base_operation '/'
|
222
236
|
|
@@ -230,6 +244,8 @@ module Exchange
|
|
230
244
|
# Exchange::Currency.new(40, :usd) == Exchange::Currency.new(34, :eur) #=> true, will implicitly convert eur to usd at the actual rate
|
231
245
|
# @example Compare a currency with a number, the value of the currency will get compared
|
232
246
|
# Exchange::Currency.new(35, :usd) == 35 #=> true
|
247
|
+
# @since 0.1
|
248
|
+
# @version 0.6
|
233
249
|
#
|
234
250
|
def == other
|
235
251
|
if is_same_currency?(other)
|
@@ -246,7 +262,7 @@ module Exchange
|
|
246
262
|
# @param [Whatever you want to throw at it] other The counterpart to compare
|
247
263
|
# @return [Fixed] a number which can be used for sorting
|
248
264
|
# @since 0.3
|
249
|
-
# @version 0.
|
265
|
+
# @version 0.6
|
250
266
|
# @todo which historic conversion should be used when two are present?
|
251
267
|
# @example Compare two currencies in terms of value
|
252
268
|
# Exchange::Currency.new(40, :usd) <=> Exchange::Currency.new(28, :usd) #=> -1
|
@@ -254,7 +270,7 @@ module Exchange
|
|
254
270
|
# Exchange::Currency.new(40, :usd) <=> Exchange::Currency.new(28, :eur) #=> -1
|
255
271
|
# @example Sort multiple currencies in an array
|
256
272
|
# [1.usd, 1.eur, 1.chf].sort.map(&:currency) #=> [:usd, :chf, :eur]
|
257
|
-
|
273
|
+
#
|
258
274
|
def <=> other
|
259
275
|
if is_same_currency?(other)
|
260
276
|
self.value <=> other.value
|
@@ -279,7 +295,7 @@ module Exchange
|
|
279
295
|
# Exchange::Currency.new(34.34, :omr).to_s #=> "OMR 34.340"
|
280
296
|
# @example Convert a currency to a string without the currency
|
281
297
|
# Exchange::ISO4217.stringif(34.34, :omr).to_s(:iso) #=> "34.340"
|
282
|
-
|
298
|
+
#
|
283
299
|
def to_s format=:currency
|
284
300
|
[
|
285
301
|
format == :currency && ISO4217.stringify(self.value, self.currency),
|
@@ -292,6 +308,8 @@ module Exchange
|
|
292
308
|
# determine if another given object is an instance of Exchange::Currency
|
293
309
|
# @param [Object] other The object to be tested against
|
294
310
|
# @return [Boolean] true if the other is an instance of Exchange::Currency, false if not
|
311
|
+
# @since 0.6
|
312
|
+
# @version 0.6
|
295
313
|
#
|
296
314
|
def is_currency? other
|
297
315
|
other.is_a?(Exchange::Currency)
|
@@ -300,6 +318,8 @@ module Exchange
|
|
300
318
|
# determine if another given object is an instance of Exchange::Currency and the same currency
|
301
319
|
# @param [Object] other The object to be tested against
|
302
320
|
# @return [Boolean] true if the other is an instance of Exchange::Currency and has the same currency as self, false if not
|
321
|
+
# @since 0.6
|
322
|
+
# @version 0.6
|
303
323
|
#
|
304
324
|
def is_same_currency? other
|
305
325
|
is_currency?(other) && other.currency == self.currency
|
@@ -308,10 +328,40 @@ module Exchange
|
|
308
328
|
# determine if another given object is an instance of Exchange::Currency and has another currency
|
309
329
|
# @param [Object] other The object to be tested against
|
310
330
|
# @return [Boolean] true if the other is an instance of Exchange::Currency and has another currency as self, false if not
|
331
|
+
# @since 0.6
|
332
|
+
# @version 0.6
|
311
333
|
#
|
312
334
|
def is_other_currency? other
|
313
335
|
is_currency?(other) && other.currency != self.currency
|
314
336
|
end
|
337
|
+
|
338
|
+
# determine wether the chosen api supports converting the given currency
|
339
|
+
# @param [String] currency The currency to test the api for
|
340
|
+
# @return [Boolean] True if the api supports the given currency, false if not
|
341
|
+
#
|
342
|
+
def api_supports_currency? currency
|
343
|
+
api::CURRENCIES.include?(currency)
|
344
|
+
end
|
345
|
+
|
346
|
+
# Test if another currency is used in an operation, and if so, if the operation is allowed
|
347
|
+
# @param [Numeric, Exchange::Currency] other The counterpart in the operation
|
348
|
+
# @raise [CurrencyMixError] an error if mixing currencies is not allowed and currencies where mixed
|
349
|
+
# @since 0.6
|
350
|
+
# @version 0.6
|
351
|
+
#
|
352
|
+
def test_for_currency_mix_error other
|
353
|
+
raise CurrencyMixError.new("You\'re trying to mix up #{self.currency} with #{other.currency}. You denied mixing currencies in the configuration, allow it or convert the currencies before mixing") if !Exchange.configuration.allow_mixed_operations && other.kind_of?(Currency) && other.currency != self.currency
|
354
|
+
end
|
355
|
+
|
356
|
+
# Helper method to raise a no rate error for a given currency if no rate is given
|
357
|
+
# @param [String] currency a possible currency
|
358
|
+
# @raise [NoRateError] an error indicating that the given string is a currency, but no rate is present
|
359
|
+
# @since 0.7.2
|
360
|
+
# @version 0.7.2
|
361
|
+
#
|
362
|
+
def test_for_no_rate_error currency
|
363
|
+
raise NoRateError.new("Cannot convert to #{currency} because the defined api does not provide a rate") if ISO4217.definitions.keys.include?(currency.upcase)
|
364
|
+
end
|
315
365
|
|
316
366
|
end
|
317
367
|
|