exchange 1.1.1 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +2 -2
- data/README.rdoc +57 -41
- data/exchange.gemspec +10 -4
- data/ext/mkrf_conf.rb +44 -0
- data/lib/exchange/base.rb +6 -1
- data/lib/exchange/core_extensions.rb +1 -0
- data/lib/exchange/core_extensions/big_decimal/mri_2_1_0_patch.rb +24 -0
- data/lib/exchange/external_api/base.rb +1 -1
- data/spec/exchange/core_extensions/big_decimal/mri_2_1_0_patch_spec.rb +18 -0
- data/spec/exchange/core_extensions/float/error_safe_spec.rb +11 -2
- data/spec/exchange/money_spec.rb +36 -1
- metadata +33 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b07fc45eb9ab48bfe650be620f7e7a56320b7139
|
4
|
+
data.tar.gz: c282e0a9b56802cadd9fd5be61aadc4baf3dfdaf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: af9f00a17b47fbe5c28a6cfbaaac207209da877a7bead8ceece961950d336638f2bc4944794ff6ea5268bbd0fe31ea0b23fc883686413226af58e535d610e946
|
7
|
+
data.tar.gz: 768f5bdbbc7dd3e8bbe71a23a3a97ee105856b282c286364cf743b5e59f934ba5f8426088777827e2715503046c33640638167b8c9b3729b4877f7d7f3d04741
|
data/.travis.yml
CHANGED
data/README.rdoc
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
= exchange {<img src="https://secure.travis-ci.org/beatrichartz/exchange.png?branch=master" />}[http://travis-ci.org/beatrichartz/exchange] {<img src="https://gemnasium.com/beatrichartz/exchange.png" alt="Dependency Status" />}[https://gemnasium.com/beatrichartz/exchange] {<img src="https://codeclimate.com/github/beatrichartz/exchange.png" />}[https://codeclimate.com/github/beatrichartz/exchange]
|
1
|
+
= exchange {<img src="https://secure.travis-ci.org/beatrichartz/exchange.png?branch=master" />}[http://travis-ci.org/beatrichartz/exchange] {<img src="https://gemnasium.com/beatrichartz/exchange.png" alt="Dependency Status" />}[https://gemnasium.com/beatrichartz/exchange] {<img src="https://codeclimate.com/github/beatrichartz/exchange.png" />}[https://codeclimate.com/github/beatrichartz/exchange] {<img src="https://d2weczhvl823v0.cloudfront.net/beatrichartz/exchange/trend.png"/>}[https://bitdeli.com/free]
|
2
2
|
|
3
3
|
The Exchange Gem gives you easy access to currency functions directly on your Numbers. {It is tested against}[http://travis-ci.org/beatrichartz/exchange]: ruby 2.0, 1.9, ree and rubinius (1.9 and 2.0 mode). Exchange will in future versions take advantage of 2.1 features like refinements, be sure to check this page for updates!
|
4
4
|
|
@@ -6,10 +6,13 @@ You can use it with just plain ruby projects, in Rails 2 and 3, Sinatra or whate
|
|
6
6
|
|
7
7
|
{<img src="http://api.flattr.com/button/flattr-badge-large.png" alt="Flattr this" title="Flattr this" border="0" />}[http://flattr.com/thing/1096528/]
|
8
8
|
|
9
|
+
=== Note when using with MRI 2.1.0-p0
|
10
|
+
MRI 2.1.0-p0 has {a confirmed bug in BigDecimal causing it to return wrong results for BigDecimal division when the rvalue is lower than 1}[https://www.ruby-forum.com/topic/4419577]. Exchange includes a patch for this, and all tests are running for MRI 2.1.0.
|
11
|
+
|
9
12
|
== Installation
|
10
13
|
=== Bundler / Rails
|
11
|
-
Add it to your Gemfile
|
12
|
-
gem "exchange", "
|
14
|
+
Add it to your Gemfile
|
15
|
+
gem "exchange", "~> 1.2.0"
|
13
16
|
=== Manually
|
14
17
|
Just install it as a gem
|
15
18
|
gem install exchange
|
@@ -29,9 +32,9 @@ or better for historic dates
|
|
29
32
|
1.in(:eur).to(:usd, :at => Time.now - 84600)
|
30
33
|
|
31
34
|
=== Fallbacks for Conversion APIs
|
32
|
-
Never worry if an API is shortly unavailable – Exchange provides the possibility to fall back to other conversion API's if the chosen one is currently not available or does not provide a rate for the attempted conversion. Thus it is possible to combine different API's with incomplete currency sets to have a more complete currency set.
|
35
|
+
Never worry if an API is shortly unavailable – Exchange provides the possibility to fall back to other conversion API's if the chosen one is currently not available or does not provide a rate for the attempted conversion. Thus it is possible to combine different API's with incomplete currency sets to have a more complete currency set.
|
33
36
|
|
34
|
-
The performance impact of a fallback if a rate is recognizably not provided by an API is minimal, whereas the performance impact on a http connection error can have a bigger impact on performance.
|
37
|
+
The performance impact of a fallback if a rate is recognizably not provided by an API is minimal, whereas the performance impact on a http connection error can have a bigger impact on performance.
|
35
38
|
|
36
39
|
The default fallback mechanism used calls the ECB API if the Xavier Media API is unavailable. You can set your own fallback chain using the API configuration.
|
37
40
|
|
@@ -110,6 +113,10 @@ Specify the symbol format will print out the currency with a symbol. If no symbo
|
|
110
113
|
Specifying the amount format will print out the formatted amount only
|
111
114
|
|
112
115
|
1440.4.in(:usd).to_s(:amount) #=> "1,440.40"
|
116
|
+
|
117
|
+
Specifying the plain format will print out the amount formatted with just a dot separator
|
118
|
+
|
119
|
+
1440.4.in(:usd).to_s(:plain) #=> "1440.40"
|
113
120
|
|
114
121
|
As seen above, exchange takes care of the right format for the separators
|
115
122
|
|
@@ -117,24 +124,24 @@ As seen above, exchange takes care of the right format for the separators
|
|
117
124
|
|
118
125
|
=== Use three great APIs or your own
|
119
126
|
|
120
|
-
Three open APIs are already included:
|
127
|
+
Three open APIs are already included:
|
121
128
|
|
122
129
|
- {Xaviermedia}[http://www.xavierforum.com/viewtopic.php?f=5&t=10979&sid=671a685edbfa5dbec219fbc6793d5057]
|
123
130
|
- {European Central Bank}[http://www.ecb.int/stats/exchange/eurofxref/html/index.en.html]
|
124
131
|
- {Open Exchange Rates}[http://openexchangerates.org/] (Look for the free plan at the bottom of the page)
|
125
132
|
|
126
|
-
but if you have another API you like to use, it becomes as easy as writing one Class and two methods to use it.
|
133
|
+
but if you have another API you like to use, it becomes as easy as writing one Class and two methods to use it.
|
127
134
|
{Example of a custom API Extension}[http://rubydoc.info/github/beatrichartz/exchange/Exchange/ExternalAPI]
|
128
135
|
|
129
136
|
=== Use great caches or your own great cache
|
130
137
|
|
131
|
-
Use one of three available caching solutions:
|
138
|
+
Use one of three available caching solutions:
|
132
139
|
|
133
140
|
- Memcached via the Dalli gem
|
134
141
|
- Redis via the redis gem
|
135
142
|
- Rails cache (This gem does however not depend on rails)
|
136
143
|
|
137
|
-
But, same here, if you don't like any of these or want to use your own caching solution, it is as easy as writing one Class and two methods to use it.
|
144
|
+
But, same here, if you don't like any of these or want to use your own caching solution, it is as easy as writing one Class and two methods to use it.
|
138
145
|
{Example of a custom cache extension}[http://rubydoc.info/github/beatrichartz/exchange/Exchange/Cache]
|
139
146
|
|
140
147
|
== Basic Operations
|
@@ -172,7 +179,7 @@ Compare Currencies, they will convert implicitly
|
|
172
179
|
2.in(:nok) < 2.in(:sek) #=> false (2.in(:sek) get converted to nok and compared)
|
173
180
|
5.in(:eur) == 4.34.in(:chf) #=> true
|
174
181
|
50.in(:eur) == 4.34.in(:chf) #=> false
|
175
|
-
50.in(:eur).to(:sek) == 50.in(:eur)
|
182
|
+
50.in(:eur).to(:sek) == 50.in(:eur) #=> true
|
176
183
|
50.in(:eur, :at => '2011-1-1') == 50.in(:sek) #=> false
|
177
184
|
|
178
185
|
Sort multiple currencies at once
|
@@ -265,18 +272,18 @@ If you want to maintain control over when a currency is converted, turn implicit
|
|
265
272
|
Exchange.configuration.implicit_conversions = false
|
266
273
|
1.in(:usd) + 1.in(:eur) #=> raises ImplicitConversionDenied
|
267
274
|
|
268
|
-
=== Caching Options
|
275
|
+
=== Caching Options
|
269
276
|
|
270
277
|
In Key/Value stores, exchange will cache the API files with a key starting with 'exchange_'
|
271
278
|
|
272
|
-
Use Memory to cache the result (default).
|
279
|
+
Use Memory to cache the result (default).
|
273
280
|
Exchange.configuration = Exchange::Configuration.new do |c|
|
274
281
|
c.cache = {
|
275
282
|
:subclass => :memory
|
276
283
|
}
|
277
284
|
end
|
278
285
|
|
279
|
-
Use Memcached to cache the result.
|
286
|
+
Use Memcached to cache the result.
|
280
287
|
Exchange.configuration = Exchange::Configuration.new do |c|
|
281
288
|
c.cache = {
|
282
289
|
:subclass => :memcached,
|
@@ -332,44 +339,51 @@ Use https as request protocol of your api requests:
|
|
332
339
|
Easily connect to your custom API by writing an ExternalAPI Class, or use your own caching solution to cache. Please note that only open source APIs can be accepted as contributions to this gem. Private / Premium APIs have to be written as your own.
|
333
340
|
module Exchange
|
334
341
|
module ExternalAPI
|
335
|
-
|
342
|
+
|
343
|
+
# Inherit from Json to write for a json api, and the json gem is automatically loaded
|
344
|
+
# Inherit from XML to write for an xml api, and nokogiri is automatically loaded
|
345
|
+
#
|
346
|
+
class MyCustom < Json
|
347
|
+
|
336
348
|
# Define here which currencies your API can handle
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
#
|
349
|
+
#
|
350
|
+
CURRENCIES = %W(usd chf).map(&:to_sym)
|
351
|
+
|
352
|
+
# Every instance of ExternalAPI Class has to have an update function which
|
353
|
+
# gets the rates from the API
|
341
354
|
#
|
342
355
|
def update(opts={})
|
356
|
+
|
343
357
|
# assure that you will get a Time object for the historical dates
|
344
358
|
#
|
345
|
-
time = assure_time(opts[:at])
|
359
|
+
time = helper.assure_time(opts[:at])
|
346
360
|
|
347
|
-
# Call your API (shown here with a helper function that builds your API URL).
|
361
|
+
# Call your API (shown here with a helper function that builds your API URL).
|
348
362
|
# Like this, your calls will get cached.
|
349
363
|
#
|
350
364
|
Call.new(api_url(time), :at => time) do |result|
|
351
365
|
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
366
|
+
# Assign the currency conversion base.
|
367
|
+
# Attention, this is readonly, self.base= won't work
|
368
|
+
#
|
369
|
+
@base = result['base']
|
370
|
+
|
371
|
+
# assign the rates, this has to be a hash with the following format:
|
372
|
+
# {'USD' => 1.23242, 'CHF' => 1.34323}.
|
373
|
+
#
|
374
|
+
# Attention, this is readonly, self.rates= won't work
|
375
|
+
#
|
376
|
+
@rates = result['rates']
|
377
|
+
|
378
|
+
# Timestamp the api call result. This may come in handy to assure you have
|
379
|
+
# the right result.
|
380
|
+
#
|
381
|
+
# Attention, this is readonly, self.timestamp= won't work
|
382
|
+
#
|
383
|
+
@timestamp = result['timestamp'].to_i
|
384
|
+
|
371
385
|
end
|
372
|
-
|
386
|
+
|
373
387
|
private
|
374
388
|
|
375
389
|
def api_url(time)
|
@@ -384,6 +398,8 @@ Now, you can configure your API in the configuration. The Symbol will get camelc
|
|
384
398
|
|
385
399
|
Exchange::Configuration.api.subclass = :my_custom
|
386
400
|
|
401
|
+
# Have fun, and don't forget to write tests.
|
402
|
+
|
387
403
|
Have fun, and don't forget to write tests.
|
388
404
|
|
389
405
|
=== Your own Cache
|
@@ -396,7 +412,7 @@ Write your own caching module to use the gem with your own custom caching soluti
|
|
396
412
|
# to the instance
|
397
413
|
#
|
398
414
|
def cached api, opts={}, &block
|
399
|
-
# generate the storage with key(api, opts[:at]) and you will get a
|
415
|
+
# generate the storage with key(api, opts[:at]) and you will get a
|
400
416
|
# unique key to store in your cache
|
401
417
|
#
|
402
418
|
# Your code goes here
|
data/exchange.gemspec
CHANGED
@@ -12,14 +12,20 @@ Gem::Specification.new do |s|
|
|
12
12
|
s.licenses = ["MIT"]
|
13
13
|
s.require_paths = ["lib"]
|
14
14
|
s.summary = "Simple Money handling for your ruby app"
|
15
|
+
s.extensions = 'ext/mkrf_conf.rb'
|
15
16
|
|
16
17
|
s.files = `git ls-files`.split("\n")
|
17
18
|
s.test_files = `git ls-files -- spec/*`.split("\n")
|
18
19
|
s.require_paths = ["lib"]
|
19
20
|
|
20
|
-
s.add_dependency "nokogiri", ">= 1.0.0"
|
21
|
-
s.add_development_dependency "json", ">= 1.0.0"
|
22
|
-
s.add_development_dependency "yard", ">= 0.7.4"
|
23
|
-
s.add_development_dependency "bundler", ">= 1.0.0"
|
21
|
+
s.add_dependency "nokogiri", "~> 1.6", ">= 1.0.0"
|
22
|
+
s.add_development_dependency "json", "~> 1.8", ">= 1.0.0"
|
23
|
+
s.add_development_dependency "yard", "~> 0.8", ">= 0.7.4"
|
24
|
+
s.add_development_dependency "bundler", "~> 1.5", ">= 1.0.0"
|
25
|
+
if RUBY_ENGINE == 'rbx'
|
26
|
+
s.add_development_dependency "rubysl-bigdecimal", "~> 2.0"
|
27
|
+
s.add_development_dependency "rubysl-singleton", "~> 2.0"
|
28
|
+
s.add_development_dependency "racc", "~> 1.4"
|
29
|
+
end
|
24
30
|
end
|
25
31
|
|
data/ext/mkrf_conf.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
rbx = defined?(RUBY_ENGINE) && 'rbx' == RUBY_ENGINE
|
2
|
+
|
3
|
+
def already_installed(dep)
|
4
|
+
!Gem::DependencyInstaller.new(:domain => :local).find_gems_with_sources(dep).empty? ||
|
5
|
+
!Gem::DependencyInstaller.new(:domain => :local,:prerelease => true).find_gems_with_sources(dep).empty?
|
6
|
+
end
|
7
|
+
|
8
|
+
if rbx
|
9
|
+
require 'rubygems'
|
10
|
+
require 'rubygems/command.rb'
|
11
|
+
require 'rubygems/dependency.rb'
|
12
|
+
require 'rubygems/dependency_installer.rb'
|
13
|
+
|
14
|
+
begin
|
15
|
+
Gem::Command.build_args = ARGV
|
16
|
+
rescue NoMethodError
|
17
|
+
end
|
18
|
+
|
19
|
+
dep = [
|
20
|
+
Gem::Dependency.new("rubysl-bigdecimal", '~> 2.0'),
|
21
|
+
Gem::Dependency.new("rubysl-singleton", '~> 2.0'),
|
22
|
+
Gem::Dependency.new("racc", '~> 1.4')
|
23
|
+
].reject{|d| already_installed(d) }
|
24
|
+
|
25
|
+
begin
|
26
|
+
puts "Installing base gem"
|
27
|
+
inst = Gem::DependencyInstaller.new
|
28
|
+
dep.each {|d| inst.install d }
|
29
|
+
rescue
|
30
|
+
inst = Gem::DependencyInstaller.new(:prerelease => true)
|
31
|
+
begin
|
32
|
+
dep.each {|d| inst.install d }
|
33
|
+
rescue Exception => e
|
34
|
+
puts e
|
35
|
+
puts e.backtrace.join "\n "
|
36
|
+
exit(1)
|
37
|
+
end
|
38
|
+
end unless dep.size == 0
|
39
|
+
end
|
40
|
+
|
41
|
+
# create dummy rakefile to indicate success
|
42
|
+
f = File.open(File.join(File.dirname(__FILE__), "Rakefile"), "w")
|
43
|
+
f.write("task :default\n")
|
44
|
+
f.close
|
data/lib/exchange/base.rb
CHANGED
@@ -1,9 +1,14 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
2
|
module Exchange
|
3
3
|
|
4
|
+
# constant for broken big decimal division in MRI 2.1.0
|
5
|
+
# https://www.ruby-forum.com/topic/4419577
|
6
|
+
#
|
7
|
+
BROKEN_BIG_DECIMAL_DIVISION = (RUBY_VERSION == '2.1.0' && RUBY_ENGINE == 'ruby')
|
8
|
+
|
4
9
|
# The current version of the exchange gem
|
5
10
|
#
|
6
|
-
VERSION = '1.
|
11
|
+
VERSION = '1.2.0'
|
7
12
|
|
8
13
|
# The root installation path of the gem
|
9
14
|
# @version 0.5
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
module Exchange
|
3
|
+
|
4
|
+
module MRI210Patch
|
5
|
+
|
6
|
+
# A patch for https://www.ruby-forum.com/topic/4419577
|
7
|
+
# Since the division values are off for values < 1,
|
8
|
+
# multiply the BigDecimal instance by its precision
|
9
|
+
#
|
10
|
+
def / other
|
11
|
+
if other.is_a?(BigDecimal) && other < 1
|
12
|
+
precision = 10 * precs.first
|
13
|
+
(self * precision) / (other * precision)
|
14
|
+
else
|
15
|
+
super
|
16
|
+
end
|
17
|
+
end
|
18
|
+
alias :div :/
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
BigDecimal.prepend Exchange::MRI210Patch if Exchange::BROKEN_BIG_DECIMAL_DIVISION #safeguard again if someone includes this file by accident
|
@@ -124,7 +124,7 @@ module Exchange
|
|
124
124
|
# Exchange::ExternalAPI::Base.new.rate(:usd, :eur, :at => Time.gm(3,23,2009))
|
125
125
|
# #=> 1.232231231
|
126
126
|
#
|
127
|
-
def rate from, to, opts={}
|
127
|
+
def rate from, to, opts={}
|
128
128
|
rate = cache.cached(self.class, opts.merge(:key_for => [from, to])) do
|
129
129
|
update(opts)
|
130
130
|
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
|
3
|
+
if Exchange::BROKEN_BIG_DECIMAL_DIVISION
|
4
|
+
require 'spec_helper'
|
5
|
+
|
6
|
+
describe "Exchange::MRI210Patch" do
|
7
|
+
|
8
|
+
describe "/" do
|
9
|
+
subject { BigDecimal.new("0.7") }
|
10
|
+
let(:other) { BigDecimal.new("0.5") }
|
11
|
+
it "should patch BigDecimal division for BigDecimals below 1" do
|
12
|
+
(subject / other).should == BigDecimal.new("1.4")
|
13
|
+
(subject.div(other)).should == BigDecimal.new("1.4")
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
@@ -2,6 +2,7 @@
|
|
2
2
|
require 'spec_helper'
|
3
3
|
|
4
4
|
describe "Exchange::ErrorSafe" do
|
5
|
+
let(:is_mri_21) { (RUBY_VERSION == '2.1.0' && RUBY_ENGINE == 'ruby') }
|
5
6
|
before(:all) do
|
6
7
|
Exchange.configuration = Exchange::Configuration.new { |c| c.cache = { :subclass => :no_cache } }
|
7
8
|
end
|
@@ -35,7 +36,11 @@ describe "Exchange::ErrorSafe" do
|
|
35
36
|
(1.0e+25 + BigDecimal.new("9999999999999999900000000").in(:usd)).round.to_f.should == 2.0e+25
|
36
37
|
end
|
37
38
|
it "should not touch other operations" do
|
38
|
-
|
39
|
+
if is_mri_21
|
40
|
+
(1.0e+25 + BigDecimal.new("9999999999999999900000000")).round.should == BigDecimal.new("0.199999999999999999E26")
|
41
|
+
else
|
42
|
+
(1.0e+25 + BigDecimal.new("9999999999999999900000000")).round.should == 20000000000000001811939328
|
43
|
+
end
|
39
44
|
end
|
40
45
|
end
|
41
46
|
describe "-" do
|
@@ -43,7 +48,11 @@ describe "Exchange::ErrorSafe" do
|
|
43
48
|
(1.0e+25 - BigDecimal.new("9999999999999999900000000").in(:usd)).round.should == 100000000
|
44
49
|
end
|
45
50
|
it "should not touch other operations" do
|
46
|
-
|
51
|
+
if is_mri_21
|
52
|
+
(1.0e+25 - BigDecimal.new("9999999999999999900000000")).should == BigDecimal.new("0.1E9")
|
53
|
+
else
|
54
|
+
(1.0e+25 - BigDecimal.new("9999999999999999900000000")).should == 0
|
55
|
+
end
|
47
56
|
end
|
48
57
|
end
|
49
58
|
end
|
data/spec/exchange/money_spec.rb
CHANGED
@@ -120,6 +120,15 @@ describe "Exchange::Money" do
|
|
120
120
|
it "should be able to add a float" do
|
121
121
|
(subject + 40.5).value.should == 80.5
|
122
122
|
end
|
123
|
+
context "with a big decimal" do
|
124
|
+
subject { Exchange::Money.new(0.82, :omr) }
|
125
|
+
it "should be able to add a big decimal below zero" do
|
126
|
+
(subject + BigDecimal.new("0.45454545")).value.round(8).should == BigDecimal.new("0.127454545E1")
|
127
|
+
end
|
128
|
+
it "should be able to add a big decimal above zero" do
|
129
|
+
(subject + BigDecimal.new("12.455")).round(2).value.should == BigDecimal.new("0.1328E2")
|
130
|
+
end
|
131
|
+
end
|
123
132
|
it "should not modify the base value" do
|
124
133
|
(subject + 40.5).value.should == 80.5
|
125
134
|
subject.value.should == 40.0
|
@@ -186,6 +195,15 @@ describe "Exchange::Money" do
|
|
186
195
|
it "should be able to subtract a float" do
|
187
196
|
(subject - 40.5).value.should == -0.5
|
188
197
|
end
|
198
|
+
context "with a big decimal" do
|
199
|
+
subject { Exchange::Money.new(1829.82, :omr) }
|
200
|
+
it "should be able to subtract a big decimal below zero" do
|
201
|
+
(subject - BigDecimal.new("0.45454545")).value.round(8).should == BigDecimal.new("0.182936545455E4")
|
202
|
+
end
|
203
|
+
it "should be able to subtract a big decimal above zero" do
|
204
|
+
(subject - BigDecimal.new("12.455")).round(2).value.should == BigDecimal.new("0.181737E4")
|
205
|
+
end
|
206
|
+
end
|
189
207
|
it "should not modify the base value" do
|
190
208
|
(subject - 40).value.should == 0
|
191
209
|
subject.value.should == 40.0
|
@@ -258,6 +276,15 @@ describe "Exchange::Money" do
|
|
258
276
|
(subject * 0.29).round(0).value.should == 15
|
259
277
|
end
|
260
278
|
end
|
279
|
+
context "with a big decimal" do
|
280
|
+
subject { Exchange::Money.new(1829.82, :omr) }
|
281
|
+
it "should be able to multiply by a big decimal below zero" do
|
282
|
+
(subject * BigDecimal.new("0.45454545")).value.round(8).should == BigDecimal.new("0.83173635532E3")
|
283
|
+
end
|
284
|
+
it "should be able to multiply by a big decimal above zero" do
|
285
|
+
(subject * BigDecimal.new("12.455")).round(2).value.should == BigDecimal.new("0.2279041E5")
|
286
|
+
end
|
287
|
+
end
|
261
288
|
it "should not fall for float rounding errors" do
|
262
289
|
(subject * 40.5)
|
263
290
|
end
|
@@ -329,7 +356,15 @@ describe "Exchange::Money" do
|
|
329
356
|
(subject / 12.0).round(2).value.should == 152.49
|
330
357
|
end
|
331
358
|
end
|
332
|
-
|
359
|
+
context "with a big decimal" do
|
360
|
+
subject { Exchange::Money.new(1829.82, :omr) }
|
361
|
+
it "should be able to divide by a big decimal below zero" do
|
362
|
+
(subject / BigDecimal.new("0.45454545")).value.round(8).should == BigDecimal.new("0.402560404026E4")
|
363
|
+
end
|
364
|
+
it "should be able to divide by a big decimal above zero" do
|
365
|
+
(subject / BigDecimal.new("12.455")).round(2).value.should == BigDecimal.new("0.14691E3")
|
366
|
+
end
|
367
|
+
end
|
333
368
|
it "should not modify the base value" do
|
334
369
|
(subject / 40).value.should == 1
|
335
370
|
subject.value.should == 40.0
|
metadata
CHANGED
@@ -1,19 +1,22 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: exchange
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Beat Richartz
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2014-01-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nokogiri
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.6'
|
17
20
|
- - '>='
|
18
21
|
- !ruby/object:Gem::Version
|
19
22
|
version: 1.0.0
|
@@ -21,6 +24,9 @@ dependencies:
|
|
21
24
|
prerelease: false
|
22
25
|
version_requirements: !ruby/object:Gem::Requirement
|
23
26
|
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '1.6'
|
24
30
|
- - '>='
|
25
31
|
- !ruby/object:Gem::Version
|
26
32
|
version: 1.0.0
|
@@ -28,6 +34,9 @@ dependencies:
|
|
28
34
|
name: json
|
29
35
|
requirement: !ruby/object:Gem::Requirement
|
30
36
|
requirements:
|
37
|
+
- - ~>
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '1.8'
|
31
40
|
- - '>='
|
32
41
|
- !ruby/object:Gem::Version
|
33
42
|
version: 1.0.0
|
@@ -35,6 +44,9 @@ dependencies:
|
|
35
44
|
prerelease: false
|
36
45
|
version_requirements: !ruby/object:Gem::Requirement
|
37
46
|
requirements:
|
47
|
+
- - ~>
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '1.8'
|
38
50
|
- - '>='
|
39
51
|
- !ruby/object:Gem::Version
|
40
52
|
version: 1.0.0
|
@@ -42,6 +54,9 @@ dependencies:
|
|
42
54
|
name: yard
|
43
55
|
requirement: !ruby/object:Gem::Requirement
|
44
56
|
requirements:
|
57
|
+
- - ~>
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: '0.8'
|
45
60
|
- - '>='
|
46
61
|
- !ruby/object:Gem::Version
|
47
62
|
version: 0.7.4
|
@@ -49,6 +64,9 @@ dependencies:
|
|
49
64
|
prerelease: false
|
50
65
|
version_requirements: !ruby/object:Gem::Requirement
|
51
66
|
requirements:
|
67
|
+
- - ~>
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0.8'
|
52
70
|
- - '>='
|
53
71
|
- !ruby/object:Gem::Version
|
54
72
|
version: 0.7.4
|
@@ -56,6 +74,9 @@ dependencies:
|
|
56
74
|
name: bundler
|
57
75
|
requirement: !ruby/object:Gem::Requirement
|
58
76
|
requirements:
|
77
|
+
- - ~>
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: '1.5'
|
59
80
|
- - '>='
|
60
81
|
- !ruby/object:Gem::Version
|
61
82
|
version: 1.0.0
|
@@ -63,6 +84,9 @@ dependencies:
|
|
63
84
|
prerelease: false
|
64
85
|
version_requirements: !ruby/object:Gem::Requirement
|
65
86
|
requirements:
|
87
|
+
- - ~>
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '1.5'
|
66
90
|
- - '>='
|
67
91
|
- !ruby/object:Gem::Version
|
68
92
|
version: 1.0.0
|
@@ -70,7 +94,8 @@ description: 'Simple Money handling for your ruby app – ISO4217-compatible Cur
|
|
70
94
|
instantiation, conversion, string formatting and more via an intuitive DSL: 1.in(:usd).to(:eur)'
|
71
95
|
email: attr_accessor@gmail.com
|
72
96
|
executables: []
|
73
|
-
extensions:
|
97
|
+
extensions:
|
98
|
+
- ext/mkrf_conf.rb
|
74
99
|
extra_rdoc_files: []
|
75
100
|
files:
|
76
101
|
- .document
|
@@ -85,6 +110,7 @@ files:
|
|
85
110
|
- Rakefile
|
86
111
|
- changelog.rdoc
|
87
112
|
- exchange.gemspec
|
113
|
+
- ext/mkrf_conf.rb
|
88
114
|
- html.html
|
89
115
|
- iso4217.yml
|
90
116
|
- iso4217_country_map.yml
|
@@ -102,6 +128,7 @@ files:
|
|
102
128
|
- lib/exchange/configurable.rb
|
103
129
|
- lib/exchange/configuration.rb
|
104
130
|
- lib/exchange/core_extensions.rb
|
131
|
+
- lib/exchange/core_extensions/big_decimal/mri_2_1_0_patch.rb
|
105
132
|
- lib/exchange/core_extensions/cachify.rb
|
106
133
|
- lib/exchange/core_extensions/float/error_safe.rb
|
107
134
|
- lib/exchange/core_extensions/numeric/conversability.rb
|
@@ -130,6 +157,7 @@ files:
|
|
130
157
|
- spec/exchange/cache/redis_spec.rb
|
131
158
|
- spec/exchange/configuration_spec.rb
|
132
159
|
- spec/exchange/core_extensions/array/cachify_spec.rb
|
160
|
+
- spec/exchange/core_extensions/big_decimal/mri_2_1_0_patch_spec.rb
|
133
161
|
- spec/exchange/core_extensions/float/error_safe_spec.rb
|
134
162
|
- spec/exchange/core_extensions/hash/cachify_spec.rb
|
135
163
|
- spec/exchange/core_extensions/numeric/cachify_spec.rb
|
@@ -175,7 +203,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
175
203
|
version: '0'
|
176
204
|
requirements: []
|
177
205
|
rubyforge_project:
|
178
|
-
rubygems_version: 2.
|
206
|
+
rubygems_version: 2.1.11
|
179
207
|
signing_key:
|
180
208
|
specification_version: 4
|
181
209
|
summary: Simple Money handling for your ruby app
|
@@ -190,6 +218,7 @@ test_files:
|
|
190
218
|
- spec/exchange/cache/redis_spec.rb
|
191
219
|
- spec/exchange/configuration_spec.rb
|
192
220
|
- spec/exchange/core_extensions/array/cachify_spec.rb
|
221
|
+
- spec/exchange/core_extensions/big_decimal/mri_2_1_0_patch_spec.rb
|
193
222
|
- spec/exchange/core_extensions/float/error_safe_spec.rb
|
194
223
|
- spec/exchange/core_extensions/hash/cachify_spec.rb
|
195
224
|
- spec/exchange/core_extensions/numeric/cachify_spec.rb
|