samlown-money 2.3.3.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,101 @@
1
+ require 'money/errors'
2
+ require 'net/http'
3
+ require 'rubygems'
4
+ require 'hpricot'
5
+
6
+ # Class for aiding in exchanging money between different currencies.
7
+ # By default, the Money class uses an object of this class (accessible through
8
+ # Money#bank) for performing currency exchanges.
9
+ #
10
+ # By default, VariableExchangeBank has no knowledge about conversion rates.
11
+ # One must manually specify them with +add_rate+, after which one can perform
12
+ # exchanges with +exchange+. For example:
13
+ #
14
+ # bank = Money::VariableExchangeBank.new
15
+ # bank.add_rate("CAD", 0.803115)
16
+ # bank.add_rate("USD", 1.24515)
17
+ #
18
+ # # Exchange 100 CAD to USD:
19
+ # bank.exchange(100_00, "CAD", "USD") # => 15504
20
+ # # Exchange 100 USD to CAD:
21
+ # bank.exchange(100_00, "USD", "CAD") # => 6450
22
+ class Money
23
+ class VariableExchangeBank
24
+ # Returns the singleton instance of VariableExchangeBank.
25
+ #
26
+ # By default, <tt>Money.default_bank</tt> returns the same object.
27
+ def self.instance
28
+ @@singleton
29
+ end
30
+
31
+ def initialize
32
+ @rates = {}
33
+ @rates["USD"] = 1.0
34
+ end
35
+
36
+ def add_rate(currency, rate)
37
+ @rates[currency.upcase] = (currency.upcase != Money.default_currency) ? (rate * @rates[Money.default_currency]) : rate
38
+ end
39
+
40
+ def get_rate(currency = nil)
41
+ return nil unless @rates[currency]
42
+ (currency != Money.default_currency) ? @rates[currency.upcase] / @rates[Money.default_currency] : @rates[currency.upcase]
43
+ end
44
+
45
+ # Given two currency names, checks whether they're both the same currency.
46
+ #
47
+ # bank = VariableExchangeBank.new
48
+ # bank.same_currency?("usd", "USD") # => true
49
+ # bank.same_currency?("usd", "EUR") # => false
50
+ def same_currency?(currency1, currency2)
51
+ currency1.upcase == currency2.upcase
52
+ end
53
+
54
+ # Exchange the given amount of cents in +from_currency+ to +to_currency+.
55
+ # Returns the amount of cents in +to_currency+ as an integer, rounded down.
56
+ #
57
+ # If the conversion rate is unknown, then Money::UnknownRate will be raised.
58
+ def exchange(cents, from_currency, to_currency)
59
+ from_currency.upcase!
60
+ to_currency.upcase!
61
+ if !@rates[from_currency] or !@rates[to_currency]
62
+ raise Money::UnknownRate, "No conversion rate known for '#{from_currency}' -> '#{to_currency}'"
63
+ end
64
+ ((cents / @rates[from_currency]) * @rates[to_currency]).round
65
+ end
66
+
67
+ # Fetch rates
68
+ def fetch_rates
69
+ xml = Hpricot.XML(
70
+ Net::HTTP.get(
71
+ URI.parse('http://www.ecb.int/stats/eurofxref/eurofxref-daily.xml')
72
+ )
73
+ )
74
+
75
+ @rates["EUR"] = 1.0
76
+ (xml/:Cube).each do |ele|
77
+ @rates[ele['currency'].upcase] = ele['rate'].to_f if ele['currency']
78
+ end
79
+ end
80
+
81
+
82
+ # Auto fetch the currencies every X seconds
83
+ # if no time is give, will fetch every hour
84
+ def auto_fetch(time = 60*60)
85
+ @auto_fetch.kill if (@auto_fetch && @auto_fetch.alive?)
86
+ @auto_fetch = Thread.new {
87
+ loop do
88
+ self.fetch_rates
89
+ sleep time
90
+ end
91
+ }
92
+ end
93
+
94
+ # stop auto fetch
95
+ def stop_fetch
96
+ @auto_fetch.kill if (@auto_fetch && @auto_fetch.alive?)
97
+ end
98
+
99
+ @@singleton = VariableExchangeBank.new
100
+ end
101
+ end
@@ -0,0 +1,37 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{money}
5
+ s.version = "2.3.3.2"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Money Team"]
9
+ s.date = %q{2009-05-14}
10
+ s.description = %q{This library aids one in handling money and different currencies.}
11
+ s.email = ["see@readme"]
12
+ s.extra_rdoc_files = ["History.txt", "Manifest.txt", "README.rdoc"]
13
+ s.files = ["History.txt", "MIT-LICENSE", "Manifest.txt", "README.rdoc", "Rakefile", "lib/money.rb", "lib/money/acts_as_money.rb", "lib/money/core_extensions.rb", "lib/money/errors.rb", "lib/money/money.rb", "lib/money/variable_exchange_bank.rb", "money.gemspec", "rails/init.rb", "script/console", "script/destroy", "script/generate", "spec/db/database.yml", "spec/db/schema.rb", "spec/money/acts_as_money_spec.rb", "spec/money/core_extensions_spec.rb", "spec/money/exchange_bank_spec.rb", "spec/money/money_spec.rb", "spec/spec.opts", "spec/spec_helper.rb" ]
14
+ s.has_rdoc = true
15
+ s.homepage = %q{http://github.com/samlown/money}
16
+ s.rdoc_options = ["--main", "README.rdoc"]
17
+ s.require_paths = ["lib"]
18
+ s.rubyforge_project = %q{money}
19
+ s.rubygems_version = %q{1.3.1}
20
+ s.summary = %q{This library aids one in handling money and different currencies.}
21
+
22
+ if s.respond_to? :specification_version then
23
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
24
+ s.specification_version = 2
25
+
26
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
27
+ s.add_development_dependency(%q<newgem>, [">= 1.3.0"])
28
+ s.add_development_dependency(%q<hoe>, [">= 1.8.0"])
29
+ else
30
+ s.add_dependency(%q<newgem>, [">= 1.3.0"])
31
+ s.add_dependency(%q<hoe>, [">= 1.8.0"])
32
+ end
33
+ else
34
+ s.add_dependency(%q<newgem>, [">= 1.3.0"])
35
+ s.add_dependency(%q<hoe>, [">= 1.8.0"])
36
+ end
37
+ end
@@ -0,0 +1,3 @@
1
+ require 'money/acts_as_money'
2
+
3
+ ActiveRecord::Base.send :include, ActsAsMoney
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ # File: script/console
3
+ irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
4
+
5
+ libs = " -r irb/completion"
6
+ # Perhaps use a console_lib to store any extra methods I may want available in the cosole
7
+ # libs << " -r #{File.dirname(__FILE__) + '/../lib/console_lib/console_logger.rb'}"
8
+ libs << " -r #{File.dirname(__FILE__) + '/../lib/postgis_adapter.rb'}"
9
+ puts "Loading postgis_adapter gem"
10
+ exec "#{irb} #{libs} --simple-prompt"
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/destroy'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
+ RubiGen::Scripts::Destroy.new.run(ARGV)
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/generate'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
+ RubiGen::Scripts::Generate.new.run(ARGV)
@@ -0,0 +1,4 @@
1
+ adapter: sqlite3
2
+ database: tmp/acts_as_money.sqlite3
3
+ pool: 5
4
+ timeout: 5000
@@ -0,0 +1,14 @@
1
+ ActiveRecord::Schema.define() do
2
+
3
+ create_table :accounts, :force => true do |t|
4
+ t.integer :value_cents, :total_cents
5
+ t.string :value_currency, :total_currency
6
+ end
7
+
8
+ create_table :products, :force => true do |t|
9
+ t.integer :value_cents, :tax_pennys
10
+ t.string :value_currency
11
+ end
12
+
13
+
14
+ end
@@ -0,0 +1,95 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper.rb'
2
+ require File.dirname(__FILE__) + '/../../rails/init.rb'
3
+
4
+ class Account < ActiveRecord::Base
5
+ has_money :value, :total, :allow_nil => true
6
+ end
7
+
8
+ class Product < ActiveRecord::Base
9
+ has_money :value, :allow_nil => false
10
+ has_money :tax, :cents => "pennys", :with_currency => false
11
+
12
+ validates_numericality_of :value_cents, :greater_than => 0
13
+ end
14
+
15
+ describe "Acts as Money" do
16
+
17
+
18
+ it "should accept nil" do
19
+ @account = Account.create(:value => nil)
20
+ @account.should be_valid
21
+ @account.value.should be_nil
22
+ end
23
+
24
+ it "should require money" do
25
+ @product = Product.create(:value => nil)
26
+ @product.should have(1).errors
27
+ @product.value.should == Money.new(0)
28
+ end
29
+
30
+ it "should require money" do
31
+ @product_fake = Product.create(:value => nil)
32
+ @product_fake.value_cents.should eql(0)
33
+ end
34
+
35
+ it "should create" do
36
+ @account = Account.create!(:value => 10, :total => "20 BRL")
37
+ @account.should be_valid
38
+ end
39
+
40
+ it "should write to the db" do
41
+ lambda do
42
+ @account = Account.create!(:value => 10, :total => "20 BRL")
43
+ end.should change(Account, :count).by(1)
44
+ Account.last.total.format.should eql("R$20,00")
45
+ end
46
+
47
+
48
+
49
+ describe "Account" do
50
+
51
+ before(:each) do
52
+ @account = Account.create!(:value => 10, :total => "20 BRL")
53
+ end
54
+
55
+ it "should return an instance of Money" do
56
+ @account.value.should be_instance_of(Money)
57
+ end
58
+
59
+ it "should format out nicely" do
60
+ @account.value.format.should eql("$10.00")
61
+ end
62
+
63
+ it "should include nicely" do
64
+ @account.value.to_s.should eql("10.00")
65
+ @account.total.to_s.should eql("20.00")
66
+ end
67
+
68
+ it "should map cents" do
69
+ @account.value_cents.to_s.should eql("1000")
70
+ end
71
+
72
+ it "should map currency" do
73
+ @account.value_currency.should eql("USD")
74
+ @account.total_currency.should eql("BRL")
75
+ end
76
+
77
+ end
78
+
79
+ describe "Product" do
80
+
81
+ before(:each) do
82
+ @product = Product.create(:value => 10, :tax => 2)
83
+ end
84
+
85
+ it "should map attributes" do
86
+ @product.pennys.should eql(200)
87
+ end
88
+
89
+ it "should map currency on tax" do
90
+ @product.should_not respond_to(:tax_currency)
91
+ end
92
+
93
+ end
94
+
95
+ end
@@ -0,0 +1,44 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper.rb'
2
+
3
+ describe "Money core extensions" do
4
+ describe "Numberic#to_money works" do
5
+ it "should convert integer to money" do
6
+ money = 1234.to_money
7
+ money.cents.should == 1234_00
8
+ money.currency.should == Money.default_currency
9
+ end
10
+
11
+ it "should convert float to money" do
12
+ money = 100.37.to_money
13
+ money.cents.should == 100_37
14
+ money.currency.should == Money.default_currency
15
+ end
16
+ end
17
+
18
+ describe "String#to_money works" do
19
+ it { "100".to_money.should == Money.new(100_00) }
20
+ it { "100.37".to_money.should == Money.new(100_37) }
21
+ it { "100,37".to_money.should == Money.new(100_37) }
22
+ it { "100 000".to_money.should == Money.new(100_000_00) }
23
+ it { "100.000,45".to_money.should == Money.new(100_000_45) }
24
+ it { "-100.100,45".to_money.should == Money.new(-100_100_45) }
25
+
26
+ it { "100 USD".to_money.should == Money.new(100_00, "USD") }
27
+ it { "-100 USD".to_money.should == Money.new(-100_00, "USD") }
28
+ it { "100 EUR".to_money.should == Money.new(100_00, "EUR") }
29
+ it { "100.37 EUR".to_money.should == Money.new(100_37, "EUR") }
30
+ it { "100,37 EUR".to_money.should == Money.new(100_37, "EUR") }
31
+
32
+ it { "USD 100".to_money.should == Money.new(100_00, "USD") }
33
+ it { "EUR 100".to_money.should == Money.new(100_00, "EUR") }
34
+ it { "EUR 100.37".to_money.should == Money.new(100_37, "EUR") }
35
+ it { "CAD -100.37".to_money.should == Money.new(-100_37, "CAD") }
36
+ it { "EUR 100,37".to_money.should == Money.new(100_37, "EUR") }
37
+ it { "EUR -100,37".to_money.should == Money.new(-100_37, "EUR") }
38
+
39
+ it { "BRL 100,37".to_money.should == Money.new(100_37, "BRL") }
40
+ it { "BRL -100,37".to_money.should == Money.new(-100_37, "BRL") }
41
+
42
+ it {"$100 USD".to_money.should == Money.new(100_00, "USD") }
43
+ end
44
+ end
@@ -0,0 +1,46 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper.rb'
2
+
3
+ describe Money::VariableExchangeBank do
4
+ before :each do
5
+ @bank = Money::VariableExchangeBank.new
6
+ end
7
+
8
+ it "returns the previously specified conversion rate" do
9
+ @bank.add_rate("USD", 0.788332676)
10
+ @bank.add_rate("EUR", 122.631477)
11
+ @bank.get_rate("USD").should == 0.788332676
12
+ @bank.get_rate("EUR").should == 122.631477
13
+ end
14
+
15
+ it "treats currency names case-insensitively" do
16
+ @bank.add_rate("usd", 1)
17
+ @bank.get_rate("USD").should == 1
18
+ @bank.same_currency?("USD", "usd").should be_true
19
+ @bank.same_currency?("EUR", "usd").should be_false
20
+ end
21
+
22
+ it "returns nil if the conversion rate is unknown" do
23
+ @bank.get_rate("American Pesos").should be_nil
24
+ end
25
+
26
+ it "exchanges money from one currency to another according to the specified conversion rates" do
27
+ @bank.add_rate("USD", 1.0)
28
+ @bank.add_rate("EUR", 0.5)
29
+ @bank.add_rate("YEN", 5)
30
+ @bank.exchange(10_00, "USD", "EUR").should == 5_00
31
+ @bank.exchange(500_00, "EUR", "YEN").should == 5000_00
32
+ end
33
+
34
+ it "rounds the exchanged result down" do
35
+ @bank.add_rate("USD", 1.0)
36
+ @bank.add_rate("EUR", 0.788332676)
37
+ @bank.add_rate("YEN", 122.631477)
38
+ @bank.exchange(10_00, "USD", "EUR").should == 788
39
+ @bank.exchange(500_00, "EUR", "YEN").should == 7777901
40
+ end
41
+
42
+ it "raises Money::UnknownRate upon conversion if the conversion rate is unknown" do
43
+ block = lambda { @bank.exchange(10, "USD", "ABC") }
44
+ block.should raise_error(Money::UnknownRate)
45
+ end
46
+ end
@@ -0,0 +1,266 @@
1
+ # -*- coding: utf-8 -*-
2
+ require File.dirname(__FILE__) + '/../spec_helper.rb'
3
+
4
+ describe Money do
5
+
6
+ it { Money.new(10_00).to_f.should eql(10.0) }
7
+ it { Money.new(10_00).to_s.should eql("10.00") }
8
+
9
+ it "is associated to the singleton instance of VariableExchangeBank by default" do
10
+ Money.new(0).bank.object_id.should == Money::VariableExchangeBank.instance.object_id
11
+ end
12
+
13
+ it "should return the amount of cents passed to the constructor" do
14
+ Money.new(200_00, "USD").cents.should == 200_00
15
+ end
16
+
17
+ it "should rounds the given cents to an integer" do
18
+ Money.new(1.0, "USD").cents.should == 1
19
+ Money.new(1.01, "USD").cents.should == 1
20
+ end
21
+
22
+ it "should use the floor method" do
23
+ Money.new(1.50, "USD").cents.should == 1
24
+ Money.new(1.99, "USD").cents.should == 1
25
+ end
26
+
27
+ it "#currency returns the currency passed to the constructor" do
28
+ Money.new(200_00, "USD").currency.should == "USD"
29
+ end
30
+
31
+ it "#zero? returns whether the amount is 0" do
32
+ Money.new(0, "USD").should be_zero
33
+ Money.new(0, "EUR").should be_zero
34
+ Money.new(1, "USD").should_not be_zero
35
+ Money.new(10, "YEN").should_not be_zero
36
+ Money.new(-1, "EUR").should_not be_zero
37
+ end
38
+
39
+ it "should exchange_to exchanges the amount via its exchange bank" do
40
+ money = Money.new(100_00, "USD")
41
+ money.bank.should_receive(:exchange).with(100_00, "USD", "EUR").and_return(200_00)
42
+ money.exchange_to("EUR")
43
+ end
44
+
45
+ it "should exchange_to exchanges the amount properly" do
46
+ money = Money.new(100_00, "USD")
47
+ money.bank.should_receive(:exchange).with(100_00, "USD", "EUR").and_return(200_00)
48
+ money.exchange_to("EUR").should == Money.new(200_00, "EUR")
49
+ end
50
+
51
+ it "should returns true if and only if their amount and currency are equal" do
52
+ Money.new(1_00, "USD").should == Money.new(1_00, "USD")
53
+ end
54
+
55
+ it "should add retaining the currency" do
56
+ (Money.new(1_00, "USD") + 10).should == Money.new(1_10, "USD")
57
+ end
58
+
59
+ it "should substract retaining the currency" do
60
+ (Money.new(1_00, "USD") - 10).should == Money.new(90, "USD")
61
+ end
62
+
63
+ it "should multiply while retaining the currency" do
64
+ (Money.new(1_00, "USD") * 10).should == Money.new(10_00, "USD")
65
+ end
66
+
67
+ it "should divides while retaining the currency" do
68
+ (Money.new(10_00, "USD") / 10).should == Money.new(1_00, "USD")
69
+ end
70
+
71
+ it "should create a new Money object of 0 cents if empty" do
72
+ Money.empty.should == Money.new(0)
73
+ end
74
+
75
+ it "Money.ca_dollar creates a new Money object of the given value in CAD" do
76
+ Money.ca_dollar(50).should == Money.new(50, "CAD")
77
+ end
78
+
79
+ it "Money.us_dollar creates a new Money object of the given value in USD" do
80
+ Money.us_dollar(50).should == Money.new(50, "USD")
81
+ end
82
+
83
+ it "Money.euro creates a new Money object of the given value in EUR" do
84
+ Money.euro(50).should == Money.new(50, "EUR")
85
+ end
86
+
87
+ it "Money.real creates a new Money object of the given value in BRL" do
88
+ Money.real(50).should == Money.new(50, "BRL")
89
+ end
90
+
91
+ describe "Installments" do
92
+
93
+ it "# divides the money ammout in installments add first" do
94
+ @money = Money.new(10_00).split_in_installments(3)
95
+ @money[0].cents.should eql(334)
96
+ @money[1].cents.should eql(333)
97
+ @money[2].cents.should eql(333)
98
+ end
99
+
100
+ it "# divides the money ammout in installments add last" do
101
+ @money = Money.new(10_00).split_in_installments(3,true)
102
+ @money.to_s.should eql(["3.33", "3.33", "3.34"])
103
+ end
104
+
105
+ it "# divides the money ammout in installments base on payment" do
106
+ money = Money.new(3_00)
107
+ Money.new(10_00).in_installments_of(money)[0].cents.should eql(334)
108
+ Money.new(10_00).in_installments_of(money)[1].cents.should eql(333)
109
+ Money.new(10_00).in_installments_of(money)[2].cents.should eql(333)
110
+ end
111
+
112
+ it "shuld sum array" do
113
+ Money.new(10_00).split_in_installments(3).sum.cents.should eql(1000)
114
+ end
115
+
116
+ it "should calculate tax" do
117
+ Money.new(100).add_tax(20).cents.should eql(120)
118
+ Money.new(100).add_tax(-20).cents.should eql(80)
119
+ end
120
+
121
+ it "shuld to_s wallet" do
122
+ @money = Money.new(10_00)
123
+ @money.split_in_installments(3).to_s.should eql(["3.34", "3.33", "3.33"])
124
+ end
125
+
126
+ it "shuld sum array" do
127
+ @money = Money.new(10_00).add_tax(10)
128
+ @money.split_in_installments(3).sum.cents.should eql(1100)
129
+ end
130
+
131
+ end
132
+
133
+ describe "Taxes and Interest" do
134
+
135
+ it "Money.add_rate works" do
136
+ Money.add_rate("USD", 1.0)
137
+ Money.add_rate("EUR", 10)
138
+ Money.new(10_00, "EUR").exchange_to("USD").should == Money.new(1_00, "USD")
139
+ end
140
+
141
+ it "Money method missing exchange" do
142
+ Money.add_rate("EUR", 1.0)
143
+ Money.add_rate("BRL", 10)
144
+ Money.new(10_00, "EUR").as_brl.should == Money.new(100_00, "BRL")
145
+ end
146
+
147
+ it "should calculate compound tax" do
148
+ m = Money.new(1000_00)
149
+ m.compound_interest(12.99,12).to_s.should eql("137.91")
150
+ end
151
+
152
+ it "should simple interest" do
153
+ m = Money.new(1000_00)
154
+ m.simple_interest(12.99,12).to_s.should eql("129.90")
155
+ end
156
+
157
+ it "should calculate compound interest" do
158
+ m = Money.new(2500_00)
159
+ m.compound_interest(12.99,3).to_s.should eql("82.06")
160
+ end
161
+
162
+ it "should calculate compound interest" do
163
+ m = Money.new(2500_00)
164
+ m.compound_interest(12.99,3,6).to_s.should eql("165.91")
165
+ end
166
+
167
+ end
168
+
169
+ describe "Format out " do
170
+
171
+ describe "Options" do
172
+ before(:each) do
173
+ @cash = Money.new(2_00, "JPY")
174
+ end
175
+
176
+ it { @cash.format.should eql("¥2.00") }
177
+ it { @cash.format(:symbol => "R$ ").should eql("R$ 2.00") }
178
+ it { @cash.format(:no_cents => true).should eql("¥2") }
179
+ it { @cash.format(:no_cents => true, :symbol => "R$ ").should eql("R$ 2") }
180
+ it { @cash.format(:html => true).should eql("&yen;2.00") }
181
+
182
+ end
183
+
184
+ it { Money.new(0).format.should eql("$0.00") }
185
+ it { Money.new(0).format(:display_free => true).should eql("free") }
186
+ it { Money.new(0).format(:display_free => "GRATIS").should eql("GRATIS") }
187
+
188
+ it { Money.new(9).format.should eql("$0.09") }
189
+ it { Money.new(99).format.should eql("$0.99") }
190
+ it { Money.new(800).format.should eql("$8.00") }
191
+ it { Money.new(-8000).format(:no_cents => true).should eql("$-80") }
192
+ it { Money.new(80000).format.should eql("$800.00") }
193
+ it { Money.new(800000).format.should eql("$8,000.00") }
194
+ it { Money.new(-8000000, "JPY").format(:no_cents => true).should eql("¥-80.000") }
195
+ it { Money.new(87654321, "BRL").format.should eql("R$876.543,21") }
196
+ it { Money.new(800000000, "BRL").format.should eql("R$8.000.000,00") }
197
+ it { Money.new(8000000000, "BRL").format.should eql("R$80.000.000,00") }
198
+ it { Money.new(80000000000, "CAD").format.should eql("$800,000,000.00") }
199
+ it { Money.new(880000000000, "GBP").format(:no_cents => true).should eql("£8,800,000,000") }
200
+ it { Money.new(8800000000088, "EUR").format.should eql("€88,000,000,000.88") }
201
+
202
+ end
203
+
204
+
205
+ describe "Actions involving two Money objects" do
206
+ describe "if the other Money object has the same currency" do
207
+ it "#<=> compares the two objects' amounts" do
208
+ (Money.new(1_00, "USD") <=> Money.new(1_00, "USD")).should == 0
209
+ (Money.new(1_00, "USD") <=> Money.new(99, "USD")).should > 0
210
+ (Money.new(1_00, "USD") <=> Money.new(2_00, "USD")).should < 0
211
+ end
212
+
213
+ it "#+ adds the other object's amount to the current object's amount while retaining the currency" do
214
+ (Money.new(10_00, "USD") + Money.new(90, "USD")).should == Money.new(10_90, "USD")
215
+ end
216
+
217
+ it "#- substracts the other object's amount from the current object's amount while retaining the currency" do
218
+ (Money.new(10_00, "USD") - Money.new(90, "USD")).should == Money.new(9_10, "USD")
219
+ end
220
+ end
221
+
222
+ describe "if the other Money object has a different currency" do
223
+ it "#<=> compares the two objects' amount after converting the other object's amount to its own currency" do
224
+ target = Money.new(200_00, "EUR")
225
+ target.should_receive(:exchange_to).with("USD").and_return(Money.new(300_00, "USD"))
226
+ (Money.new(100_00, "USD") <=> target).should < 0
227
+
228
+ target = Money.new(200_00, "EUR")
229
+ target.should_receive(:exchange_to).with("USD").and_return(Money.new(100_00, "USD"))
230
+ (Money.new(100_00, "USD") <=> target).should == 0
231
+
232
+ target = Money.new(200_00, "EUR")
233
+ target.should_receive(:exchange_to).with("USD").and_return(Money.new(99_00, "USD"))
234
+ (Money.new(100_00, "USD") <=> target).should > 0
235
+ end
236
+
237
+ it "#+ adds the other object's amount, converted to this object's currency, to this object's amount while retaining its currency" do
238
+ other = Money.new(90, "EUR")
239
+ other.should_receive(:exchange_to).with("USD").and_return(Money.new(9_00, "USD"))
240
+ (Money.new(10_00, "USD") + other).should == Money.new(19_00, "USD")
241
+ end
242
+
243
+ it "#- substracts the other object's amount, converted to this object's currency, from this object's amount while retaining its currency" do
244
+ other = Money.new(90, "EUR")
245
+ other.should_receive(:exchange_to).with("USD").and_return(Money.new(9_00, "USD"))
246
+ (Money.new(10_00, "USD") - other).should == Money.new(1_00, "USD")
247
+ end
248
+ end
249
+ end
250
+
251
+ describe "Comparisons involving Numeric objects" do
252
+ it "#<=> compares integer amounts" do
253
+ (Money.new(1_00) <=> 1).should == 0
254
+ (Money.new(1_00) <=> 2).should == -1
255
+ (Money.new(1_00) <=> -1).should == 1
256
+ (Money.new(10_01) <=> 10).should == 1
257
+ end
258
+
259
+ it "#<=> compares float amounts" do
260
+ (Money.new(1_00) <=> 1.0).should == 0
261
+ (Money.new(1_00) <=> 2.0).should == -1
262
+ (Money.new(1_00) <=> 0.5).should == 1
263
+ (Money.new(10_01) <=> 10.0).should == 1
264
+ end
265
+ end
266
+ end