money 6.0.0.pre5 → 6.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,6 +1,6 @@
1
1
  # Changelog
2
2
 
3
- ## master
3
+ ## 6.0.0
4
4
  - Fix BTC subunit
5
5
  - New option :sign_positive to add a + sign to positive numbers
6
6
  - Only allow to multiply a money by a number (int, float)
@@ -25,6 +25,8 @@
25
25
  - Changed the New Taiwan Dollar symbol position from after the amount to before the amount.
26
26
  - Passing a Money instance to the Money constructor will obtain a new Money object with the same property values as the original
27
27
  - Add deprecation warning to comparators
28
+ - Add Money.disallow_currency_conversion! option
29
+ - Allow to inherits from `Money`
28
30
 
29
31
  ## 5.1.1
30
32
 
data/README.md CHANGED
@@ -240,6 +240,13 @@ There is nothing stopping you from creating bank objects which scrapes
240
240
  Money.default_bank = ExchangeBankWhichScrapesXeDotCom.new
241
241
  ```
242
242
 
243
+ If you wish to disable automatic currency conversion to prevent arithmetic when
244
+ currencies don't match:
245
+
246
+ ``` ruby
247
+ Money.disallow_currency_conversion!
248
+ ```
249
+
243
250
  ### Implementations
244
251
 
245
252
  The following is a list of Money.gem compatible currency exchange rate
@@ -261,7 +268,7 @@ For deprecated methods of integrating with Rails, check [the wiki](https://githu
261
268
 
262
269
  ## Migration Notes
263
270
 
264
- #### Version 6.0.0.pre3
271
+ #### Version 6.0.0
265
272
 
266
273
  - The `Money#dollars` and `Money#amount` methods now return instances of
267
274
  `BigDecimal` rather than `Float`. We should avoid representing monetary
@@ -0,0 +1,24 @@
1
+ require 'money/bank/base'
2
+
3
+ class Money
4
+ module Bank
5
+ # Raised when trying to exchange currencies
6
+ class DifferentCurrencyError < Error; end
7
+
8
+ # Class to ensure client code is operating in a single currency
9
+ # by raising if an exchange attempts to happen.
10
+ #
11
+ # This is useful when an application uses multiple currencies but
12
+ # it usually deals with only one currency at a time so any arithmetic
13
+ # where exchanges happen are erroneous. Using this as the default bank
14
+ # means that that these mistakes don't silently do the wrong thing.
15
+ class SingleCurrency < Base
16
+
17
+ # Raises a DifferentCurrencyError to remove possibility of accidentally
18
+ # exchanging currencies
19
+ def exchange_with(from, to_currency, &block)
20
+ raise DifferentCurrencyError, "No exchanging of currencies allowed: #{from} to #{to_currency}"
21
+ end
22
+ end
23
+ end
24
+ end
@@ -1,5 +1,6 @@
1
1
  # encoding: utf-8
2
2
  require "money/bank/variable_exchange"
3
+ require "money/bank/single_currency"
3
4
  require "money/money/arithmetic"
4
5
  require "money/money/parsing"
5
6
  require "money/money/formatting"
@@ -127,26 +128,34 @@ class Money
127
128
  attr_accessor :conversion_precision
128
129
  end
129
130
 
130
- # Set the default bank for creating new +Money+ objects.
131
- self.default_bank = Bank::VariableExchange.instance
131
+ def self.setup_defaults
132
+ # Set the default bank for creating new +Money+ objects.
133
+ self.default_bank = Bank::VariableExchange.instance
132
134
 
133
- # Set the default currency for creating new +Money+ object.
134
- self.default_currency = Currency.new("USD")
135
+ # Set the default currency for creating new +Money+ object.
136
+ self.default_currency = Currency.new("USD")
135
137
 
136
- # Default to using i18n
137
- self.use_i18n = true
138
+ # Default to using i18n
139
+ self.use_i18n = true
138
140
 
139
- # Default to not using currency symbol assumptions when parsing
140
- self.assume_from_symbol = false
141
+ # Default to not using currency symbol assumptions when parsing
142
+ self.assume_from_symbol = false
141
143
 
142
- # Default to not using infinite precision cents
143
- self.infinite_precision = false
144
+ # Default to not using infinite precision cents
145
+ self.infinite_precision = false
144
146
 
145
- # Default to bankers rounding
146
- self.rounding_mode = BigDecimal::ROUND_HALF_EVEN
147
+ # Default to bankers rounding
148
+ self.rounding_mode = BigDecimal::ROUND_HALF_EVEN
147
149
 
148
- # Default the conversion of Rationals precision to 16
149
- self.conversion_precision = 16
150
+ # Default the conversion of Rationals precision to 16
151
+ self.conversion_precision = 16
152
+ end
153
+
154
+ def self.inherited(base)
155
+ base.setup_defaults
156
+ end
157
+
158
+ setup_defaults
150
159
 
151
160
  # Create a new money object with value 0.
152
161
  #
@@ -252,6 +261,12 @@ class Money
252
261
  Money.default_bank.add_rate(from_currency, to_currency, rate)
253
262
  end
254
263
 
264
+ # Sets the default bank to be a SingleCurrency bank that raises on
265
+ # currency exchange. Useful when apps operate in a single currency at a time.
266
+ def self.disallow_currency_conversion!
267
+ self.default_bank = Bank::SingleCurrency.instance
268
+ end
269
+
255
270
  # Creates a new Money object of value given in the
256
271
  # +fractional unit+ of the given +currency+.
257
272
  #
@@ -1,7 +1,7 @@
1
1
  # -*- encoding: utf-8 -*-
2
2
  Gem::Specification.new do |s|
3
3
  s.name = "money"
4
- s.version = "6.0.0.pre5"
4
+ s.version = "6.0.0"
5
5
  s.platform = Gem::Platform::RUBY
6
6
  s.authors = ["Tobias Luetke", "Hongli Lai", "Jeremy McNevin",
7
7
  "Shane Emmons", "Simone Carletti"]
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+
3
+ describe Money::Bank::SingleCurrency do
4
+ describe "#exchange_with" do
5
+ it "raises when called" do
6
+ expect {
7
+ subject.exchange_with(Money.new(100, 'USD'), 'EUR')
8
+ }.to raise_exception(Money::Bank::DifferentCurrencyError, "No exchanging of currencies allowed: 1.00 to EUR")
9
+ end
10
+ end
11
+ end
@@ -159,6 +159,21 @@ describe Money do
159
159
  end
160
160
  end
161
161
 
162
+ describe ".disallow_currency_conversions!" do
163
+ before do
164
+ @default_bank = Money.default_bank
165
+ end
166
+
167
+ after do
168
+ Money.default_bank = @default_bank
169
+ end
170
+
171
+ it "disallows conversions when doing money arithmetic" do
172
+ Money.disallow_currency_conversion!
173
+ expect { Money.new(100, "USD") + Money.new(100, "EUR") }.to raise_exception(Money::Bank::DifferentCurrencyError)
174
+ end
175
+ end
176
+
162
177
  describe "#cents" do
163
178
  it "is a synonym of #fractional" do
164
179
  expectation = Money.new(0)
@@ -587,4 +602,16 @@ YAML
587
602
  end
588
603
  end
589
604
  end
605
+
606
+ describe "inheritance" do
607
+ it "allows inheritance" do
608
+ # TypeError:
609
+ # wrong argument type nil (expected Fixnum)
610
+ # ./lib/money/money.rb:63:in `round'
611
+ # ./lib/money/money.rb:63:in `fractional'
612
+ # ./lib/money/money/arithmetic.rb:115:in `-'
613
+ MoneyChild = Class.new(Money)
614
+ (MoneyChild.new(1000) - Money.new(500)).should eq Money.new(500)
615
+ end
616
+ end
590
617
  end
metadata CHANGED
@@ -1,8 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: money
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.0.0.pre5
5
- prerelease: 6
4
+ version: 6.0.0
5
+ prerelease:
6
6
  platform: ruby
7
7
  authors:
8
8
  - Tobias Luetke
@@ -13,7 +13,7 @@ authors:
13
13
  autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
- date: 2013-10-01 00:00:00.000000000 Z
16
+ date: 2013-11-07 00:00:00.000000000 Z
17
17
  dependencies:
18
18
  - !ruby/object:Gem::Dependency
19
19
  name: i18n
@@ -99,6 +99,7 @@ files:
99
99
  - lib/money/currency/heuristics.rb
100
100
  - lib/money/bank/variable_exchange.rb
101
101
  - lib/money/bank/base.rb
102
+ - lib/money/bank/single_currency.rb
102
103
  - lib/money/money.rb
103
104
  - lib/money.rb
104
105
  - spec/support/default_currency_helper.rb
@@ -110,6 +111,7 @@ files:
110
111
  - spec/money_spec.rb
111
112
  - spec/currency/heuristics_spec.rb
112
113
  - spec/spec_helper.rb
114
+ - spec/bank/single_currency_spec.rb
113
115
  - spec/bank/variable_exchange_spec.rb
114
116
  - spec/bank/base_spec.rb
115
117
  - CHANGELOG.md
@@ -136,9 +138,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
136
138
  required_rubygems_version: !ruby/object:Gem::Requirement
137
139
  none: false
138
140
  requirements:
139
- - - ! '>'
141
+ - - ! '>='
140
142
  - !ruby/object:Gem::Version
141
- version: 1.3.1
143
+ version: '0'
144
+ segments:
145
+ - 0
146
+ hash: 2830931323134829129
142
147
  requirements: []
143
148
  rubyforge_project:
144
149
  rubygems_version: 1.8.23