money 3.1.5 → 3.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,27 @@
1
+ Money 3.5.0
2
+ ===========
3
+
4
+ Features
5
+ --------
6
+ - Updated to RSpec2.
7
+ - Use i18n to lookup separator and delimiter signs.
8
+ - Removed all deprecated methods up to v3.5.0, including the following:
9
+ - Using Money#format with params instead of a Hash.
10
+ - Using a Hash with Money#new.
11
+ - Using Bank#exchange, use Bank#exchange_with instead.
12
+
13
+ Bugfixes
14
+ --------
15
+ - Updated Money#to_s to respect :separator and :subunit_to_unit.
16
+ - Fixed Money#format for :subunit_to_unit != 100.
17
+ ([#issue/37](http://github.com/RubyMoney/money/issue/37))
18
+ - Fixed String#to_money for :subunit_to_unit != 100.
19
+ ([#issue/36](http://github.com/RubyMoney/money/issue/36))
20
+ - Removed duplicate currencies.
21
+ ([#issue/38](http://github.com/RubyMoney/money/issue/38))
22
+ - Fixed issue related to JRuby returning 2 for Math.log10(1000).floor instead
23
+ of correctly returning 3.
24
+
1
25
  Money 3.1.5
2
26
  ===========
3
27
 
data/README.md CHANGED
@@ -177,15 +177,6 @@ There is nothing stopping you from creating bank objects which scrapes
177
177
 
178
178
  Money.default_bank = ExchangeBankWhichScrapesXeDotCom.new
179
179
 
180
- ### Upcoming Changes
181
-
182
- Starting in v3.1.0 we will be making two changes to the exchange process. First
183
- a new `Bank::Base` class will be available. This will allow users to more
184
- easily create custom `Bank` classes. Secondly the default `#exchange` method
185
- will be depreciated and a new `#exchange_with` method will be used. Currently
186
- `#exchange` passes the `cents` attribute. `#exchange_with` will pass the
187
- actual `Money` object instead.
188
-
189
180
  ### Implementations
190
181
 
191
182
  The following is a list of Money.gem compatible currency exchange rate
@@ -21,8 +21,8 @@
21
21
  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
22
 
23
23
  require 'bigdecimal'
24
+ require 'i18n' rescue LoadError
24
25
  require 'money/currency'
25
26
  require 'money/money'
26
27
  require 'money/defaults'
27
28
  require 'money/core_extensions'
28
- require 'money/deprecations'
@@ -84,13 +84,6 @@ class Money
84
84
  def setup
85
85
  end
86
86
 
87
- # @deprecated +#exchange+ will be removed in v3.2.0, use +#exchange_with+
88
- # @see Money::Bank::Base#exchange_with
89
- def exchange(cents, from_currency, to_currency, &block)
90
- Money.deprecate "`Money::Bank::Base#exchange' will be removed in v3.2.0, use #exchange_with instead"
91
- exchange_with(Money.new(cents, from_currency), to_currency, &block).cents
92
- end
93
-
94
87
  # Exchanges the given +Money+ object to a new +Money+ object in
95
88
  # +to_currency+.
96
89
  #
@@ -51,7 +51,6 @@ class Money
51
51
  :cad => { :priority => 5, :iso_code => "CAD", :name => "Canadian Dollar", :symbol => "$", :subunit => "Cent", :subunit_to_unit => 100, :separator => ".", :delimiter => "," },
52
52
  :cdf => { :priority => 100, :iso_code => "CDF", :name => "Congolese Franc", :symbol => "Fr", :subunit => "Centime", :subunit_to_unit => 100, :separator => ".", :delimiter => "," },
53
53
  :chf => { :priority => 100, :iso_code => "CHF", :name => "Swiss Franc", :symbol => "Fr", :subunit => "Rappen", :subunit_to_unit => 100, :separator => ".", :delimiter => "," },
54
- :chf => { :priority => 100, :iso_code => "CHF", :name => "Swiss Franc", :symbol => "Fr", :subunit => "Rappen", :subunit_to_unit => 100, :separator => ".", :delimiter => "," },
55
54
  :clp => { :priority => 100, :iso_code => "CLP", :name => "Chilean Peso", :symbol => "$", :subunit => "Peso", :subunit_to_unit => 1, :separator => ",", :delimiter => "." },
56
55
  :cny => { :priority => 100, :iso_code => "CNY", :name => "Chinese Renminbi Yuan", :symbol => "¥", :subunit => "Jiao", :subunit_to_unit => 10, :separator => ".", :delimiter => "," },
57
56
  :cop => { :priority => 100, :iso_code => "COP", :name => "Colombian Peso", :symbol => "$", :subunit => "Centavo", :subunit_to_unit => 100, :separator => ".", :delimiter => "," },
@@ -142,7 +141,6 @@ class Money
142
141
  :ron => { :priority => 100, :iso_code => "RON", :name => "Romanian Leu", :symbol => "L", :subunit => "Ban", :subunit_to_unit => 100, :separator => ".", :delimiter => "," },
143
142
  :rsd => { :priority => 100, :iso_code => "RSD", :name => "Serbian Dinar", :symbol => "din. or дин.", :subunit => "Para", :subunit_to_unit => 100, :separator => ".", :delimiter => "," },
144
143
  :rub => { :priority => 100, :iso_code => "RUB", :name => "Russian Ruble", :symbol => "р.", :subunit => "Kopek", :subunit_to_unit => 100, :separator => ".", :delimiter => "," },
145
- :rub => { :priority => 100, :iso_code => "RUB", :name => "Russian Ruble", :symbol => "руб.", :subunit => "Kopek", :subunit_to_unit => 100, :separator => ".", :delimiter => "," },
146
144
  :rwf => { :priority => 100, :iso_code => "RWF", :name => "Rwandan Franc", :symbol => "Fr", :subunit => "Centime", :subunit_to_unit => 100, :separator => ".", :delimiter => "," },
147
145
  :sar => { :priority => 100, :iso_code => "SAR", :name => "Saudi Riyal", :symbol => "ر.س", :subunit => "Hallallah", :subunit_to_unit => 100, :separator => ".", :delimiter => "," },
148
146
  :sbd => { :priority => 100, :iso_code => "SBD", :name => "Solomon Islands Dollar", :symbol => "$", :subunit => "Cent", :subunit_to_unit => 100, :separator => ".", :delimiter => "," },
@@ -165,7 +163,6 @@ class Money
165
163
  :tnd => { :priority => 100, :iso_code => "TND", :name => "Tunisian Dinar", :symbol => "د.ت", :subunit => "Millime", :subunit_to_unit => 1000, :separator => ".", :delimiter => "," },
166
164
  :top => { :priority => 100, :iso_code => "TOP", :name => "Tongan Paʻanga", :symbol => "T$", :subunit => "Seniti", :subunit_to_unit => 100, :separator => ".", :delimiter => "," },
167
165
  :try => { :priority => 100, :iso_code => "TRY", :name => "Turkish New Lira", :symbol => "YTL", :subunit => "New kuruş", :subunit_to_unit => 100, :separator => ".", :delimiter => "," },
168
- :try => { :priority => 100, :iso_code => "TRY", :name => "Turkish New Lira", :symbol => "₤", :subunit => "New kuruş", :subunit_to_unit => 100, :separator => ".", :delimiter => "," },
169
166
  :ttd => { :priority => 100, :iso_code => "TTD", :name => "Trinidad and Tobago Dollar", :symbol => "$", :subunit => "Cent", :subunit_to_unit => 100, :separator => ".", :delimiter => "," },
170
167
  :twd => { :priority => 100, :iso_code => "TWD", :name => "New Taiwan Dollar", :symbol => "$", :subunit => "Cent", :subunit_to_unit => 100, :separator => ".", :delimiter => "," },
171
168
  :tzs => { :priority => 100, :iso_code => "TZS", :name => "Tanzanian Shilling", :symbol => "Sh", :subunit => "Cent", :subunit_to_unit => 100, :separator => ".", :delimiter => "," },
@@ -343,12 +340,6 @@ class Money
343
340
  "#<#{self.class.name} id: #{id} #{ATTRIBUTES.map { |a| "#{a}: #{send(a)}" }.join(", ")}>"
344
341
  end
345
342
 
346
- # Catches deprecated uses of currency.
347
- def method_missing(method, *args, &block)
348
- Money.deprecate "`currency` is now a `Currency` instance. Call `currency.to_s.#{method}' instead."
349
- iso_code.send(method, *args, &block)
350
- end
351
-
352
343
  # Class Methods
353
344
  class << self
354
345
 
@@ -387,19 +387,7 @@ class Money
387
387
  #
388
388
  def initialize(cents, currency = Money.default_currency, bank = Money.default_bank)
389
389
  @cents = cents.round
390
- if currency.is_a?(Hash)
391
- # Earlier versions of Money wrongly documented the constructor as being able
392
- # to accept something like this:
393
- #
394
- # Money.new(50, :currency => "USD")
395
- #
396
- # We retain compatibility here.
397
- Money.deprecate "Passing :currency as option is deprecated and will be removed in v3.5.0. " +
398
- "Please use `Money.new('#{cents}'#{currency[:currency].nil? ? "" : ", '#{currency[:currency]}'"})'"
399
- @currency = Currency.wrap(currency[:currency] || Money.default_currency)
400
- else
401
- @currency = Currency.wrap(currency)
402
- end
390
+ @currency = Currency.wrap(currency)
403
391
  @bank = bank
404
392
  end
405
393
 
@@ -724,24 +712,40 @@ class Money
724
712
  currency.symbol || "¤"
725
713
  end
726
714
 
727
- # Uses +Currency#delimiter+. If +nil+ is returned, default to ",".
715
+ # If I18n is loaded, looks up key +:number.format.delimiter+.
716
+ # Otherwise and as fallback it uses +Currency#delimiter+.
717
+ # If +nil+ is returned, default to ",".
728
718
  #
729
719
  # @return [String]
730
720
  #
731
721
  # @example
732
722
  # Money.new(100, "USD").delimiter #=> ","
733
- def delimiter
734
- currency.delimiter || ","
723
+ if Object.const_defined?("I18n")
724
+ def delimiter
725
+ I18n.t(:"number.format.delimiter", :default => currency.delimiter || ",")
726
+ end
727
+ else
728
+ def delimiter
729
+ currency.delimiter || ","
730
+ end
735
731
  end
736
732
 
737
- # Uses +Currency#separator+. If +nil+ is returned, default to ".".
733
+ # If I18n is loaded, looks up key +:number.format.seperator+.
734
+ # Otherwise and as fallback it uses +Currency#seperator+.
735
+ # If +nil+ is returned, default to ",".
738
736
  #
739
737
  # @return [String]
740
738
  #
741
739
  # @example
742
740
  # Money.new(100, "USD").separator #=> "."
743
- def separator
744
- currency.separator || "."
741
+ if Object.const_defined?("I18n")
742
+ def separator
743
+ I18n.t(:"number.format.separator", :default => currency.separator || ".")
744
+ end
745
+ else
746
+ def separator
747
+ currency.separator || "."
748
+ end
745
749
  end
746
750
 
747
751
  # Creates a formatted price string according to several rules.
@@ -856,10 +860,15 @@ class Money
856
860
  symbol_value = symbol
857
861
  end
858
862
 
859
- if rules[:no_cents] or currency.subunit_to_unit == 1
860
- formatted = sprintf("#{symbol_value}%d", self.to_f)
861
- else
862
- formatted = sprintf("#{symbol_value}%.2f", self.to_f)
863
+ formatted = case rules[:no_cents]
864
+ when true
865
+ "#{symbol_value}#{self.to_s.to_i}"
866
+ else
867
+ "#{symbol_value}#{self.to_s}"
868
+ end
869
+ if rules.has_key?(:separator) and rules[:separator] and
870
+ rules[:separator] != separator
871
+ formatted.sub!(separator, rules[:separator])
863
872
  end
864
873
 
865
874
  delimiter_value = delimiter
@@ -873,16 +882,7 @@ class Money
873
882
  end
874
883
 
875
884
  # Apply delimiter
876
- formatted.gsub!(/(\d)(?=(?:\d{3})+(?:\.|$))(\d{3}\..*)?/, "\\1#{delimiter_value}\\2")
877
-
878
- separator_value = separator
879
- # Determine separator
880
- if rules.has_key?(:separator) and rules[:separator]
881
- separator_value = rules[:separator]
882
- end
883
-
884
- # Apply separator
885
- formatted.sub!(/\.(\d{2})$/, "#{separator_value}\\1")
885
+ formatted.gsub!(/(\d)(?=(?:\d{3})+(?:\.|,|$))(\d{3}\..*)?/, "\\1#{delimiter_value}\\2")
886
886
 
887
887
  if rules[:with_currency]
888
888
  formatted << " "
@@ -900,8 +900,11 @@ class Money
900
900
  # @example
901
901
  # Money.ca_dollar(100).to_s #=> "1.00"
902
902
  def to_s
903
- return sprintf("%d", cents) if currency.subunit_to_unit == 1
904
- sprintf("%.2f", self.to_f)
903
+ decimal_places = Math.log10(currency.subunit_to_unit).ceil
904
+ unit, subunit = cents.divmod(currency.subunit_to_unit).map{|o| o.to_s}
905
+ return unit if decimal_places == 0
906
+ subunit = (subunit + ("0" * decimal_places))[0, decimal_places]
907
+ "#{unit}#{separator}#{subunit}"
905
908
  end
906
909
 
907
910
  # Return the amount of money as a float. Floating points cannot guarantee
@@ -987,13 +990,6 @@ class Money
987
990
  elsif rules.size == 1
988
991
  rules = rules.pop
989
992
  rules = { rules => true } if rules.is_a?(Symbol)
990
- else
991
- Money.deprecate "Passing options as parameters is deprecated and will be removed in v3.5.0. " +
992
- "Please use `#format(#{rules.map { |r| ":#{r} => true" }.join(", ") })'"
993
- rules = rules.inject({}) do |h,s|
994
- h[s] = true
995
- h
996
- end
997
993
  end
998
994
  rules
999
995
  end
@@ -1095,17 +1091,21 @@ class Money
1095
1091
  # build the string based on major/minor since separator/delimiters have been removed
1096
1092
  # avoiding floating point arithmetic here to ensure accuracy
1097
1093
  cents = (major.to_i * currency.subunit_to_unit)
1098
- # add the minor number as well. this may have any number of digits,
1099
- # so we treat minor as a string and truncate or right-fill it with zeroes
1100
- # until it becomes a two-digit number string, which we add to cents.
1094
+ # Because of an bug in JRuby, we can't just call #floor
1095
+ decimal_places = Math.log10(currency.subunit_to_unit).to_s.to_i
1101
1096
  minor = minor.to_s
1102
- truncated_minor = minor[0..1]
1103
- truncated_minor << "0" * (2 - truncated_minor.size) if truncated_minor.size < 2
1104
- cents += truncated_minor.to_i
1105
- # respect rounding rules
1106
- if minor.size >= 3 && minor[2..2].to_i >= 5
1107
- cents += 1
1108
- end
1097
+ minor = if minor.size < decimal_places
1098
+ (minor + ("0" * decimal_places))[0,decimal_places].to_i
1099
+ elsif minor.size > decimal_places
1100
+ if minor[decimal_places,1].to_i >= 5
1101
+ minor[0,decimal_places].to_i+1
1102
+ else
1103
+ minor[0,decimal_places].to_i
1104
+ end
1105
+ else
1106
+ minor.to_i
1107
+ end
1108
+ cents += minor
1109
1109
 
1110
1110
  # if negative, multiply by -1; otherwise, return positive cents
1111
1111
  negative ? cents * -1 : cents
metadata CHANGED
@@ -1,13 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: money
3
3
  version: !ruby/object:Gem::Version
4
- hash: 9
5
4
  prerelease: false
6
5
  segments:
7
6
  - 3
8
- - 1
9
7
  - 5
10
- version: 3.1.5
8
+ - 0
9
+ version: 3.5.0
11
10
  platform: ruby
12
11
  authors:
13
12
  - Tobias Luetke
@@ -19,51 +18,64 @@ autorequire:
19
18
  bindir: bin
20
19
  cert_chain: []
21
20
 
22
- date: 2010-10-08 00:00:00 -04:00
21
+ date: 2010-12-15 00:00:00 -05:00
23
22
  default_executable:
24
23
  dependencies:
25
24
  - !ruby/object:Gem::Dependency
26
- name: rspec
25
+ name: i18n
27
26
  prerelease: false
28
27
  requirement: &id001 !ruby/object:Gem::Requirement
29
28
  none: false
30
29
  requirements:
31
- - - ">="
30
+ - - ~>
32
31
  - !ruby/object:Gem::Version
33
- hash: 3
34
32
  segments:
35
33
  - 0
36
- version: "0"
37
- type: :development
34
+ - 4
35
+ version: "0.4"
36
+ type: :runtime
38
37
  version_requirements: *id001
39
38
  - !ruby/object:Gem::Dependency
40
- name: yard
39
+ name: rspec
41
40
  prerelease: false
42
41
  requirement: &id002 !ruby/object:Gem::Requirement
43
42
  none: false
44
43
  requirements:
45
44
  - - ">="
46
45
  - !ruby/object:Gem::Version
47
- hash: 3
48
46
  segments:
47
+ - 2
49
48
  - 0
50
- version: "0"
49
+ - 0
50
+ version: 2.0.0
51
51
  type: :development
52
52
  version_requirements: *id002
53
53
  - !ruby/object:Gem::Dependency
54
- name: json
54
+ name: yard
55
55
  prerelease: false
56
56
  requirement: &id003 !ruby/object:Gem::Requirement
57
57
  none: false
58
58
  requirements:
59
59
  - - ">="
60
60
  - !ruby/object:Gem::Version
61
- hash: 3
62
61
  segments:
63
62
  - 0
64
63
  version: "0"
65
64
  type: :development
66
65
  version_requirements: *id003
66
+ - !ruby/object:Gem::Dependency
67
+ name: json
68
+ prerelease: false
69
+ requirement: &id004 !ruby/object:Gem::Requirement
70
+ none: false
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ segments:
75
+ - 0
76
+ version: "0"
77
+ type: :development
78
+ version_requirements: *id004
67
79
  description: This library aids one in handling money and different currencies.
68
80
  email:
69
81
  - hongli@phusion.nl
@@ -79,8 +91,6 @@ files:
79
91
  - lib/money/bank/variable_exchange.rb
80
92
  - lib/money/core_extensions.rb
81
93
  - lib/money/currency.rb
82
- - lib/money/defaults.rb
83
- - lib/money/deprecations.rb
84
94
  - lib/money/money.rb
85
95
  - lib/money.rb
86
96
  - CHANGELOG.md
@@ -100,7 +110,6 @@ required_ruby_version: !ruby/object:Gem::Requirement
100
110
  requirements:
101
111
  - - ">="
102
112
  - !ruby/object:Gem::Version
103
- hash: 3
104
113
  segments:
105
114
  - 0
106
115
  version: "0"
@@ -109,7 +118,6 @@ required_rubygems_version: !ruby/object:Gem::Requirement
109
118
  requirements:
110
119
  - - ">="
111
120
  - !ruby/object:Gem::Version
112
- hash: 23
113
121
  segments:
114
122
  - 1
115
123
  - 3
@@ -1,57 +0,0 @@
1
- # encoding: utf-8
2
-
3
- class Money
4
- # Used to notify users about the deprecated constants.
5
- # @see Money::SYMBOLS, Money::SEPARATOR and Money::DELIMITERS
6
- class DeprecatedHash < Hash
7
-
8
- # Creates a new +DeprecatedHash+ with message that will be displayed when
9
- # accessing +#[]+ and +#[]=+.
10
- def initialize(hash, message)
11
- @message = message
12
- replace(hash)
13
- end
14
-
15
- # Displays @message then calls +super+.
16
- def [](key)
17
- Money.deprecate(@message)
18
- super
19
- end
20
-
21
- # Displays @message then calls +super+.
22
- def []=(value)
23
- Money.deprecate(@message)
24
- super
25
- end
26
-
27
- end
28
-
29
- # @deprecated See Money::Currency#symbol
30
- SYMBOLS = DeprecatedHash.new({
31
- "GBP" => "£",
32
- "JPY" => "¥",
33
- "EUR" => "€",
34
- "ZWD" => "Z$",
35
- "CNY" => "¥",
36
- "INR" => "₨",
37
- "NPR" => "₨",
38
- "SCR" => "₨",
39
- "LKR" => "₨",
40
- "SEK" => "kr",
41
- "GHC" => "¢",
42
- "BRL" => "R$ ",
43
- # Everything else defaults to '¤'
44
- }, "Money::SYMBOLS has no longer effect and will be removed in v3.2.0. See Money::Currency#symbol.")
45
-
46
- # @deprecated See Money::Currency#separator
47
- SEPARATORS = DeprecatedHash.new({
48
- "BRL" => ",",
49
- # Everything else defaults to '.'
50
- }, "Money::SEPARATORS is deprecated and will be removed in v3.2.0. See Money::Currency#separator.")
51
-
52
- # @deprecated See Money::Currency#delimiter
53
- DELIMITERS = DeprecatedHash.new({
54
- "BRL" => ".",
55
- # Everything else defaults to ","
56
- }, "Money::DELIMITERS is deprecated and will be removed in Money v3.2.0. See Money::Currency#delimiter.")
57
- end
@@ -1,24 +0,0 @@
1
- class Money
2
- # Displays a deprecation warning message.
3
- #
4
- # @param [String] message The message to display.
5
- #
6
- # @return [nil]
7
- def self.deprecate(message)
8
- warn "DEPRECATION WARNING: #{message}"
9
- end
10
-
11
-
12
- # Money::VariableExchangeBank is the legacy default bank
13
- # shipped with Money. The class has been superseded by
14
- # Money::Bank::VariableExchange.
15
- #
16
- # @deprecated Use Money::Bank::VariableExchange instead.
17
- class VariableExchangeBank < Bank::VariableExchange # :nodoc:
18
- # Calls +Money#deprecate+ the super.
19
- def initialize(*args)
20
- Money.deprecate "Money::VariableExchangeBank is deprecated and will be removed in v3.2.0. Use Money::Bank::VariableExchange instead."
21
- super
22
- end
23
- end
24
- end