Empact-money 2.3.6

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/money.gemspec ADDED
@@ -0,0 +1,64 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{money}
5
+ s.version = "2.3.6"
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-29}
10
+ s.description = %q{This library aids one in handling money and different currencies.}
11
+ s.email = %q{see@reame}
12
+ s.extra_rdoc_files = [
13
+ "README.rdoc"
14
+ ]
15
+ s.files = [
16
+ ".gitignore",
17
+ "History.txt",
18
+ "MIT-LICENSE",
19
+ "Manifest.txt",
20
+ "README.rdoc",
21
+ "Rakefile",
22
+ "VERSION",
23
+ "lib/money.rb",
24
+ "lib/money/acts_as_money.rb",
25
+ "lib/money/core_extensions.rb",
26
+ "lib/money/errors.rb",
27
+ "lib/money/exchange_bank.rb",
28
+ "lib/money/money.rb",
29
+ "money.gemspec",
30
+ "rails/init.rb",
31
+ "spec/db/database.yml",
32
+ "spec/db/schema.rb",
33
+ "spec/money/acts_as_money_spec.rb",
34
+ "spec/money/core_extensions_spec.rb",
35
+ "spec/money/exchange_bank_spec.rb",
36
+ "spec/money/money_spec.rb",
37
+ "spec/spec.opts",
38
+ "spec/spec_helper.rb",
39
+ "tmp/.gitignore"
40
+ ]
41
+ s.homepage = %q{http://github.com/nofxx/money}
42
+ s.rdoc_options = ["--charset=UTF-8"]
43
+ s.require_paths = ["lib"]
44
+ s.rubygems_version = %q{1.3.3}
45
+ s.summary = %q{This library aids one in handling money and different currencies.}
46
+ s.test_files = [
47
+ "spec/money/exchange_bank_spec.rb",
48
+ "spec/money/acts_as_money_spec.rb",
49
+ "spec/money/money_spec.rb",
50
+ "spec/money/core_extensions_spec.rb",
51
+ "spec/db/schema.rb",
52
+ "spec/spec_helper.rb"
53
+ ]
54
+
55
+ if s.respond_to? :specification_version then
56
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
57
+ s.specification_version = 3
58
+
59
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
60
+ else
61
+ end
62
+ else
63
+ end
64
+ end
data/rails/init.rb ADDED
@@ -0,0 +1,3 @@
1
+ require 'money/acts_as_money'
2
+
3
+ ActiveRecord::Base.send :include, ActsAsMoney
@@ -0,0 +1,4 @@
1
+ adapter: sqlite3
2
+ database: tmp/acts_as_money.sqlite3
3
+ pool: 5
4
+ timeout: 5000
data/spec/db/schema.rb ADDED
@@ -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,61 @@
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" do
19
+ EXAMPLES = {
20
+ "20.15" => {:cents => Money.new(20_15), :no_cents => Money.new(20_15)},
21
+ "100" => {:cents => Money.new(100_00), :no_cents => Money.new(100)},
22
+ "100.37" => {:cents => Money.new(100_37), :no_cents => Money.new(100_37)},
23
+ "100,37" => {:cents => Money.new(100_37), :no_cents => Money.new(100_37)},
24
+ "100 000" => {:cents => Money.new(100_000_00), :no_cents => Money.new(100_000)},
25
+ "100.000,45" => {:cents => Money.new(100_000_45), :no_cents => Money.new(100_000_45)},
26
+ "-100.100,45" => {:cents => Money.new(-100_100_45), :no_cents => Money.new(-100_100_45)},
27
+
28
+ "100 USD" => {:cents => Money.new(100_00, "USD"), :no_cents => Money.new(100, "USD")},
29
+ "-100 USD" => {:cents => Money.new(-100_00, "USD"), :no_cents => Money.new(-100, "USD")},
30
+ "100 EUR" => {:cents => Money.new(100_00, "EUR"), :no_cents => Money.new(100, "EUR")},
31
+ "100.37 EUR" => {:cents => Money.new(100_37, "EUR"), :no_cents => Money.new(100_37, "EUR")},
32
+ "100,37 EUR" => {:cents => Money.new(100_37, "EUR"), :no_cents => Money.new(100_37, "EUR")},
33
+
34
+ "USD 100" => {:cents => Money.new(100_00, "USD"), :no_cents => Money.new(100, "USD")},
35
+ "EUR 100" => {:cents => Money.new(100_00, "EUR"), :no_cents => Money.new(100, "EUR")},
36
+ "EUR 100.37" => {:cents => Money.new(100_37, "EUR"), :no_cents => Money.new(100_37, "EUR")},
37
+ "CAD -100.37" => {:cents => Money.new(-100_37, "CAD"), :no_cents => Money.new(-100_37, "CAD")},
38
+ "EUR 100,37" => {:cents => Money.new(100_37, "EUR"), :no_cents => Money.new(100_37, "EUR")},
39
+ "EUR -100,37" => {:cents => Money.new(-100_37, "EUR"), :no_cents => Money.new(-100_37, "EUR")},
40
+
41
+ "BRL 100,37" => {:cents => Money.new(100_37, "BRL"), :no_cents => Money.new(100_37, "BRL")},
42
+ "BRL -100,37" => {:cents => Money.new(-100_37, "BRL"), :no_cents => Money.new(-100_37, "BRL")},
43
+
44
+ "$100 USD" => {:cents => Money.new(100_00, "USD"), :no_cents => Money.new(100, "USD")}
45
+ }
46
+
47
+ EXAMPLES.each_pair do |string, expected_money|
48
+ it "should convert '#{string}' with cents by default" do
49
+ string.to_money.should == expected_money[:cents]
50
+ end
51
+
52
+ it "should convert '#{string}' without cents" do
53
+ string.to_money(true).should == expected_money[:no_cents]
54
+ end
55
+
56
+ it "should convert '#{string}' with cents" do
57
+ string.to_money(false).should == expected_money[:cents]
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,141 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper.rb'
2
+
3
+ describe Money::ExchangeBank do
4
+ before :each do
5
+ @bank = Money::ExchangeBank.new
6
+ end
7
+
8
+ it "returns the previously specified conversion rate" do
9
+ @bank.add_rate("USD", "EUR", 0.788332676)
10
+ @bank.add_rate("EUR", "YEN", 122.631477)
11
+ @bank.get_rate("USD", "EUR").should == 0.788332676
12
+ @bank.get_rate("EUR", "YEN").should == 122.631477
13
+ end
14
+
15
+ it "returns the previously specified conversion rate" do
16
+ @bank.add_rate("USD", "EUR", 0.788332676)
17
+ @bank.add_rate("EUR", "YEN", 122.631477)
18
+ @bank.get_rate("USD", "EUR").should == 0.788332676
19
+ @bank.get_rate("EUR", "YEN").should == 122.631477
20
+ end
21
+
22
+ it "treats currency names case-insensitively" do
23
+ @bank.add_rate("usd", "eur", 1)
24
+ @bank.get_rate("USD", "EUR").should == 1
25
+ @bank.same_currency?("USD", "usd").should be_true
26
+ @bank.same_currency?("EUR", "usd").should be_false
27
+ end
28
+
29
+ it "returns nil if the conversion rate is unknown" do
30
+ @bank.get_rate("American Pesos", "EUR").should be_nil
31
+ end
32
+
33
+ it "exchanges money from one currency to another according to the specified conversion rates" do
34
+ @bank.add_rate("USD", "EUR", 0.5)
35
+ @bank.add_rate("EUR", "YEN", 10)
36
+ @bank.exchange(10_00, "USD", "EUR").should == 5_00
37
+ @bank.exchange(500_00, "EUR", "YEN").should == 5000_00
38
+ end
39
+
40
+ it "rounds the exchanged result down" do
41
+ @bank.add_rate("USD", "EUR", 0.788332676)
42
+ @bank.add_rate("EUR", "YEN", 122.631477)
43
+ @bank.exchange(10_00, "USD", "EUR").should == 7_88
44
+ @bank.exchange(500_00, "EUR", "YEN").should == 6131573
45
+ end
46
+
47
+ it "returns the previously specified conversion rate" do
48
+ @bank.add_rate("EUR", 122.631477)
49
+ @bank.get_rate("EUR").should == 122.631477
50
+ end
51
+
52
+ it "treats currency names case-insensitively" do
53
+ @bank.add_rate("yen", 1)
54
+ @bank.get_rate("YEN").should == 1
55
+ @bank.same_currency?("USD", "usd").should be_true
56
+ @bank.same_currency?("EUR", "usd").should be_false
57
+ end
58
+
59
+ it "should work with a different default currency" do
60
+ Money.default_currency = "BRL"
61
+ @bank.add_rate("yen", 10)
62
+ @bank.exchange(5_00, "brl", "yen").should == 50_00
63
+ Money.default_currency = "USD"
64
+ end
65
+
66
+ it "returns nil if the conversion rate is unknown" do
67
+ @bank.get_rate("American Pesos").should be_nil
68
+ end
69
+
70
+ it "exchanges money from one currency to another according to the specified conversion rates" do
71
+ @bank.add_rate("EUR", 0.5)
72
+ @bank.add_rate("YEN", 5)
73
+ @bank.exchange(10_00, "USD", "EUR").should == 5_00
74
+ @bank.exchange(500_00, "USD", "YEN").should == 2500_00
75
+ @bank.exchange(2500_00, "YEN", "USD").should == 500_00
76
+ end
77
+
78
+ it "should deal fine with FOO_TO_FOO" do
79
+ @bank.add_rate("USD", 2.0)
80
+ @bank.get_rate("USD").should be_nil
81
+ end
82
+
83
+ it "should test some more" do
84
+ @bank.add_rate("EUR", 0.788332676)
85
+ @bank.add_rate("YEN", 122.631477)
86
+ @bank.exchange(10_00, "USD", "EUR").should == 788
87
+ @bank.exchange(500_00, "USD", "YEN").should == 6131573
88
+ end
89
+
90
+ it "raises Money::UnknownRate upon conversion if the conversion rate is unknown" do
91
+ block = lambda { @bank.exchange(10, "USD", "ABC") }
92
+ block.should raise_error(Money::UnknownRate)
93
+ end
94
+
95
+ describe "Fetching Data" do
96
+
97
+ before(:each) do
98
+ URI.should_receive(:parse).with("http://www.ecb.int/stats/eurofxref/eurofxref-daily.xml").and_return(:uri)
99
+ Net::HTTP.should_receive(:get).with(:uri).and_return("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<gesmes:Envelope xmlns:gesmes=\"http://www.gesmes.org/xml/2002-08-01\" xmlns=\"http://www.ecb.int/vocabulary/2002-08-01/eurofxref\">\n\t<gesmes:subject>Reference rates</gesmes:subject>\n\t<gesmes:Sender>\n\t\t<gesmes:name>European Central Bank</gesmes:name>\n\t</gesmes:Sender>\n\t<Cube>\n\t\t<Cube time='2009-05-29'>\n\t\t\t<Cube currency='USD' rate='1.4098'/>\n\t\t\t<Cube currency='JPY' rate='135.22'/>\n\t\t\t<Cube currency='BGN' rate='1.9558'/>\n\t\t\t<Cube currency='CZK' rate='26.825'/>\n\t\t\t<Cube currency='DKK' rate='7.4453'/>\n\t\t\t<Cube currency='EEK' rate='15.6466'/>\n\t\t\t<Cube currency='GBP' rate='0.87290'/>\n\t\t\t<Cube currency='HUF' rate='282.48'/>\n\t\t\t<Cube currency='LTL' rate='3.4528'/>\n\t\t\t<Cube currency='LVL' rate='0.7093'/>\n\t\t\t<Cube currency='PLN' rate='4.4762'/>\n\t\t\t<Cube currency='RON' rate='4.1825'/>\n\t\t\t<Cube currency='SEK' rate='10.6678'/>\n\t\t\t<Cube currency='CHF' rate='1.5128'/>\n\t\t\t<Cube currency='NOK' rate='8.8785'/>\n\t\t\t<Cube currency='HRK' rate='7.3500'/>\n\t\t\t<Cube currency='RUB' rate='43.4455'/>\n\t\t\t<Cube currency='TRY' rate='2.1737'/>\n\t\t\t<Cube currency='AUD' rate='1.7671'/>\n\t\t\t<Cube currency='BRL' rate='2.8320'/>\n\t\t\t<Cube currency='CAD' rate='1.5501'/>\n\t\t\t<Cube currency='CNY' rate='9.6263'/>\n\t\t\t<Cube currency='HKD' rate='10.9273'/>\n\t\t\t<Cube currency='IDR' rate='14539.26'/>\n\t\t\t<Cube currency='INR' rate='66.4260'/>\n\t\t\t<Cube currency='KRW' rate='1764.04'/>\n\t\t\t<Cube currency='MXN' rate='18.4340'/>\n\t\t\t<Cube currency='MYR' rate='4.9167'/>\n\t\t\t<Cube currency='NZD' rate='2.2135'/>\n\t\t\t<Cube currency='PHP' rate='66.516'/>\n\t\t\t<Cube currency='SGD' rate='2.0350'/>\n\t\t\t<Cube currency='THB' rate='48.377'/>\n\t\t\t<Cube currency='ZAR' rate='11.2413'/>\n\t\t</Cube>\n\t</Cube>\n</gesmes:Envelope>")
100
+ end
101
+
102
+ it "should fetch data" do
103
+ Money.stub!(:default_currency).and_return("EUR")
104
+ @bank.fetch_rates
105
+ @bank.get_rate("DKK").should be_close(7.4453, 0.0001)
106
+ @bank.get_rate("BRL").should be_close(2.832, 0.001)
107
+ @bank.exchange(10_00, "EUR", "DKK").should == 74_45
108
+ end
109
+
110
+ it "should fetch diff than eur" do
111
+ Money.stub!(:default_currency).and_return("BRL")
112
+ @bank.fetch_rates
113
+ @bank.get_rate("DKK").should be_close(2.6289, 0.0001)
114
+ @bank.get_rate("EEK").should be_close(5.5249, 0.0001)
115
+ @bank.get_rate("EUR").should be_close(2.832, 0.001)
116
+ end
117
+
118
+ it "should fetch for an unknown one" do
119
+ Money.stub!(:default_currency).and_return("XXX")
120
+ @bank.fetch_rates
121
+ @bank.get_rate("DKK").should be_nil
122
+ @bank.get_rate("EUR", "USD").should be_close(1.4098, 0.001)
123
+ end
124
+
125
+ end
126
+
127
+ describe "Live Fetching" do
128
+
129
+ if ENV["LIVE"]
130
+
131
+ it "should fetch data live" do
132
+ @bank.fetch_rates
133
+ @bank.get_rate("DKK").should_not be_nil
134
+ @bank.get_rate("EUR").should_not be_nil
135
+ end
136
+
137
+ end
138
+
139
+ end
140
+
141
+ end
@@ -0,0 +1,277 @@
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
+ it { Money.new(199).to_i.should eql(199) }
9
+
10
+ it "is associated to the singleton instance of ExchangeBank by default" do
11
+ Money.new(0).bank.object_id.should == Money::ExchangeBank.instance.object_id
12
+ end
13
+
14
+ it "should return the amount of cents passed to the constructor" do
15
+ Money.new(200_00, "USD").cents.should == 200_00
16
+ end
17
+
18
+ it "should rounds the given cents to an integer" do
19
+ Money.new(1.0, "USD").cents.should == 1
20
+ Money.new(1.01, "USD").cents.should == 1
21
+ end
22
+
23
+ it "should use the floor method" do
24
+ Money.new(1.50, "USD").cents.should == 1
25
+ Money.new(1.99, "USD").cents.should == 1
26
+ end
27
+
28
+ it "#currency returns the currency passed to the constructor" do
29
+ Money.new(200_00, "USD").currency.should == "USD"
30
+ end
31
+
32
+ it "#zero? returns whether the amount is 0" do
33
+ Money.new(0, "USD").should be_zero
34
+ Money.new(0, "EUR").should be_zero
35
+ Money.new(1, "USD").should_not be_zero
36
+ Money.new(10, "YEN").should_not be_zero
37
+ Money.new(-1, "EUR").should_not be_zero
38
+ end
39
+
40
+ it "should exchange_to exchanges the amount via its exchange bank" do
41
+ money = Money.new(100_00, "USD")
42
+ money.bank.should_receive(:exchange).with(100_00, "USD", "EUR").and_return(200_00)
43
+ money.exchange_to("EUR")
44
+ end
45
+
46
+ it "should exchange_to exchanges the amount properly" do
47
+ money = Money.new(100_00, "USD")
48
+ money.bank.should_receive(:exchange).with(100_00, "USD", "EUR").and_return(200_00)
49
+ money.exchange_to("EUR").should == Money.new(200_00, "EUR")
50
+ end
51
+
52
+ it "should returns true if and only if their amount and currency are equal" do
53
+ Money.new(1_00, "USD").should == Money.new(1_00, "USD")
54
+ end
55
+
56
+ it "should add retaining the currency" do
57
+ (Money.new(1_00, "USD") + 10).should == Money.new(1_10, "USD")
58
+ end
59
+
60
+ it "should substract retaining the currency" do
61
+ (Money.new(1_00, "USD") - 10).should == Money.new(90, "USD")
62
+ end
63
+
64
+ it "should multiply while retaining the currency" do
65
+ (Money.new(1_00, "USD") * 10).should == Money.new(10_00, "USD")
66
+ end
67
+
68
+ it "should divides while retaining the currency" do
69
+ (Money.new(10_00, "USD") / 10).should == Money.new(1_00, "USD")
70
+ end
71
+
72
+ it "should create a new Money object of 0 cents if empty" do
73
+ Money.empty.should == Money.new(0)
74
+ end
75
+
76
+ it "Money.ca_dollar creates a new Money object of the given value in CAD" do
77
+ Money.ca_dollar(50).should == Money.new(50, "CAD")
78
+ end
79
+
80
+ it "Money.us_dollar creates a new Money object of the given value in USD" do
81
+ Money.us_dollar(50).should == Money.new(50, "USD")
82
+ end
83
+
84
+ it "Money.euro creates a new Money object of the given value in EUR" do
85
+ Money.euro(50).should == Money.new(50, "EUR")
86
+ end
87
+
88
+ it "Money.real creates a new Money object of the given value in BRL" do
89
+ Money.real(50).should == Money.new(50, "BRL")
90
+ end
91
+
92
+ describe "Installments" do
93
+
94
+ it "# divides the money ammout in installments add first" do
95
+ @money = Money.new(10_00).split_in_installments(3)
96
+ @money[0].cents.should eql(334)
97
+ @money[1].cents.should eql(333)
98
+ @money[2].cents.should eql(333)
99
+ end
100
+
101
+ it "# divides the money ammout in installments add last" do
102
+ @money = Money.new(10_00).split_in_installments(3,true)
103
+ @money.to_s.should eql(["3.33", "3.33", "3.34"])
104
+ end
105
+
106
+ it "# divides the money ammout in installments base on payment" do
107
+ money = Money.new(3_00)
108
+ Money.new(10_00).in_installments_of(money)[0].cents.should eql(334)
109
+ Money.new(10_00).in_installments_of(money)[1].cents.should eql(333)
110
+ Money.new(10_00).in_installments_of(money)[2].cents.should eql(333)
111
+ end
112
+
113
+ it "shuld sum array" do
114
+ Money.new(10_00).split_in_installments(3).sum.cents.should eql(1000)
115
+ Money.new(19_99).split_in_installments(3).sum.cents.should eql(1999)
116
+ end
117
+
118
+ it "should calculate tax" do
119
+ Money.new(100).add_tax(20).cents.should eql(120)
120
+ Money.new(100).add_tax(-20).cents.should eql(80)
121
+ Money.new(1218).add_tax(19).cents.should eql(1449)
122
+ Money.new(1218).add_tax(-19).cents.should eql(987)
123
+ Money.new(1000).add_tax(150).cents.should eql(2500)
124
+ Money.new(1000).add_tax(-150).cents.should eql(-500)
125
+ end
126
+
127
+ it "should round to .50 coin" do
128
+ Money.new(14_58).round_to_coin(50).cents.should eql(1450)
129
+ Money.new(14_58).round_to_coin(10).cents.should eql(1450)
130
+ Money.new(14_58).round_to_coin(5).cents.should eql(1455)
131
+ end
132
+
133
+ it "should provide tax breakdown" do
134
+ Money.new(1225).tax_breakdown(19).map{|c| c.to_s}.should eql(['14.58','2.33'])
135
+ end
136
+
137
+ it "should provide reverse tax breakdown" do
138
+ Money.new(-8).tax_reverse_breakdown(19).map{|c| c.to_s}.should eql(['-0.07','-0.01'])
139
+ end
140
+
141
+ it "shuld to_s wallet" do
142
+ @money = Money.new(10_00)
143
+ @money.split_in_installments(3).to_s.should eql(["3.34", "3.33", "3.33"])
144
+ end
145
+
146
+ it "shuld sum array" do
147
+ @money = Money.new(10_00).add_tax(10)
148
+ @money.split_in_installments(3).sum.cents.should eql(1100)
149
+ end
150
+
151
+ end
152
+
153
+ describe "Taxes and Interest" do
154
+
155
+ it "Money rate works" do
156
+ Money.add_rate("EUR", "USD", 10)
157
+ Money.new(10_00, "EUR").exchange_to("USD").should == Money.new(100_00, "USD")
158
+ end
159
+
160
+ it "Money.add_rate works" do
161
+ Money.add_rate("BGL", 10)
162
+ Money.new(10_00, "USD").exchange_to("BGL").should == Money.new(100_00, "BGL")
163
+ end
164
+
165
+ it "Money method missing exchange" do
166
+ Money.add_rate("EUR", "BRL", 10)
167
+ Money.new(10_00, "EUR").as_brl.should == Money.new(100_00, "BRL")
168
+ end
169
+
170
+ it "should calculate compound tax" do
171
+ m = Money.new(1000_00)
172
+ m.compound_interest(12.99,12).to_s.should eql("137.91")
173
+ end
174
+
175
+ it "should simple interest" do
176
+ m = Money.new(1000_00)
177
+ m.simple_interest(12.99,12).to_s.should eql("129.90")
178
+ end
179
+
180
+ it "should calculate compound interest" do
181
+ m = Money.new(2500_00)
182
+ m.compound_interest(12.99,3).to_s.should eql("82.06")
183
+ end
184
+
185
+ it "should calculate compound interest" do
186
+ m = Money.new(2500_00)
187
+ m.compound_interest(12.99,3,6).to_s.should eql("165.91")
188
+ end
189
+
190
+ end
191
+
192
+ describe "Format out " do
193
+
194
+ describe "Options" do
195
+ before(:each) do
196
+ @cash = Money.new(2_00, "JPY")
197
+ end
198
+
199
+ it { @cash.format.should eql("¥2.00") }
200
+ it { @cash.format(:symbol => "R$ ").should eql("R$ 2.00") }
201
+ it { @cash.format(:no_cents => true).should eql("¥2") }
202
+ it { @cash.format(:no_cents => true, :symbol => "R$ ").should eql("R$ 2") }
203
+ it { @cash.format(:html => true).should eql("&yen;2.00") }
204
+
205
+ end
206
+
207
+ it { Money.new(0).format.should eql("$0.00") }
208
+ it { Money.new(0).format(:display_free => true).should eql("free") }
209
+ it { Money.new(0).format(:display_free => "GRATIS").should eql("GRATIS") }
210
+
211
+ it { Money.new(9).format.should eql("$0.09") }
212
+ it { Money.new(99).format.should eql("$0.99") }
213
+ it { Money.new(800).format.should eql("$8.00") }
214
+ it { Money.new(-8000).format(:no_cents => true).should eql("$-80") }
215
+ it { Money.new(80000).format.should eql("$800.00") }
216
+ it { Money.new(800000).format.should eql("$8,000.00") }
217
+ it { Money.new(-8000000, "JPY").format(:no_cents => true).should eql("¥-80.000") }
218
+ it { Money.new(87654321, "BRL").format.should eql("R$876.543,21") }
219
+ it { Money.new(87654321, "brl").format.should eql("R$876.543,21") }
220
+ it { Money.new(800000000, "BRL").format.should eql("R$8.000.000,00") }
221
+ it { Money.new(8000000000, "BRL").format.should eql("R$80.000.000,00") }
222
+ it { Money.new(80000000000, "CAD").format.should eql("$800,000,000.00") }
223
+ it { Money.new(880000000000, "GBP").format(:no_cents => true).should eql("£8,800,000,000") }
224
+ it { Money.new(8800000000088, "EUR").format.should eql("€88,000,000,000.88") }
225
+
226
+ it "should fail nicely if symbol can`t be found" do
227
+ Money.stub!(:default_currency).and_return("XXX")
228
+ Money.new(800).format.should eql("$8.00")
229
+ end
230
+
231
+ describe "Actions involving two Money objects" do
232
+ describe "if the other Money object has the same currency" do
233
+ it "#<=> compares the two objects' amounts" do
234
+ (Money.new(1_00, "USD") <=> Money.new(1_00, "USD")).should == 0
235
+ (Money.new(1_00, "USD") <=> Money.new(99, "USD")).should > 0
236
+ (Money.new(1_00, "USD") <=> Money.new(2_00, "USD")).should < 0
237
+ end
238
+
239
+ it "#+ adds the other object's amount to the current object's amount while retaining the currency" do
240
+ (Money.new(10_00, "USD") + Money.new(90, "USD")).should == Money.new(10_90, "USD")
241
+ end
242
+
243
+ it "#- substracts the other object's amount from the current object's amount while retaining the currency" do
244
+ (Money.new(10_00, "USD") - Money.new(90, "USD")).should == Money.new(9_10, "USD")
245
+ end
246
+ end
247
+
248
+ describe "if the other Money object has a different currency" do
249
+ it "#<=> compares the two objects' amount after converting the other object's amount to its own currency" do
250
+ target = Money.new(200_00, "EUR")
251
+ target.should_receive(:exchange_to).with("USD").and_return(Money.new(300_00, "USD"))
252
+ (Money.new(100_00, "USD") <=> target).should < 0
253
+
254
+ target = Money.new(200_00, "EUR")
255
+ target.should_receive(:exchange_to).with("USD").and_return(Money.new(100_00, "USD"))
256
+ (Money.new(100_00, "USD") <=> target).should == 0
257
+
258
+ target = Money.new(200_00, "EUR")
259
+ target.should_receive(:exchange_to).with("USD").and_return(Money.new(99_00, "USD"))
260
+ (Money.new(100_00, "USD") <=> target).should > 0
261
+ end
262
+
263
+ it "#+ adds the other object's amount, converted to this object's currency, to this object's amount while retaining its currency" do
264
+ other = Money.new(90, "EUR")
265
+ other.should_receive(:exchange_to).with("USD").and_return(Money.new(9_00, "USD"))
266
+ (Money.new(10_00, "USD") + other).should == Money.new(19_00, "USD")
267
+ end
268
+
269
+ it "#- substracts the other object's amount, converted to this object's currency, from this object's amount while retaining its currency" do
270
+ other = Money.new(90, "EUR")
271
+ other.should_receive(:exchange_to).with("USD").and_return(Money.new(9_00, "USD"))
272
+ (Money.new(10_00, "USD") - other).should == Money.new(1_00, "USD")
273
+ end
274
+ end
275
+ end
276
+ end
277
+ end