bd_money 0.0.3 → 0.0.4

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/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.3
1
+ 0.0.4
data/bd_money.gemspec CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{bd_money}
8
- s.version = "0.0.3"
8
+ s.version = "0.0.4"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Adrian Madrid"]
@@ -12,6 +12,12 @@ class Money
12
12
  :up => BigDecimal::ROUND_UP,
13
13
  } unless const_defined?(:ROUND_MODES)
14
14
 
15
+ FORMATS = {
16
+ :default => { :unit => "$", :spacer => " ", :delimiter => ",", :separator => ".", :precision => 2 },
17
+ :no_cents => { :unit => "$", :spacer => " ", :delimiter => ",", :separator => ".", :precision => 0 },
18
+ :no_commas => { :unit => "$", :spacer => " ", :delimiter => "", :separator => ".", :precision => 2 },
19
+ } unless const_defined?(:FORMATS)
20
+
15
21
  REMOVE_RE = %r{[$,_ ]} unless const_defined?(:REMOVE_RE)
16
22
  VALID_RE = %r{^(-)?(\d)+(\.\d{1,12})?$} unless const_defined?(:VALID_RE)
17
23
 
@@ -20,10 +26,11 @@ class Money
20
26
  class MoneyError < StandardError # :nodoc:
21
27
  end
22
28
 
23
- def initialize(value, precision = nil, round_mode = nil)
29
+ def initialize(value, precision = nil, round_mode = nil, format = nil)
24
30
  self.amount = value
25
31
  self.precision = precision if precision
26
32
  self.round_mode = round_mode if round_mode
33
+ self.format = format if format
27
34
  end
28
35
 
29
36
  def amount=(value)
@@ -58,6 +65,15 @@ class Money
58
65
  @round_mode || self.class.round_mode
59
66
  end
60
67
 
68
+ def format=(value)
69
+ raise "Unknown format options [#{value}]" unless FORMATS.key?(value)
70
+ @format = value
71
+ end
72
+
73
+ def format
74
+ @format || self.class.format
75
+ end
76
+
61
77
  def convert(value)
62
78
  self.class.convert value
63
79
  end
@@ -98,23 +114,6 @@ class Money
98
114
  convert amount ^ convert(other).amount
99
115
  end
100
116
 
101
- def round_amount(this_precision = precision, this_round_mode = round_mode)
102
- this_round_mode = BigDecimal.const_get("ROUND_#{this_round_mode.to_s.upcase}") if this_round_mode.is_a?(Symbol)
103
- amount.round this_precision, this_round_mode
104
- end
105
-
106
- def round(this_precision = precision, this_round_mode = round_mode)
107
- convert round_amount(this_precision, this_round_mode)
108
- end
109
-
110
- def to_i(this_round_mode = round_mode)
111
- round_amount(0, this_round_mode).to_i
112
- end
113
-
114
- def to_f(this_precision = precision, this_round_mode = round_mode)
115
- round_amount(this_precision, this_round_mode).to_i
116
- end
117
-
118
117
  def to_credit
119
118
  convert amount.abs
120
119
  end
@@ -145,9 +144,25 @@ class Money
145
144
  amount == 0
146
145
  end
147
146
 
148
- def to_s(this_precision = precision, this_round_mode = round_mode)
147
+ def round_amount(this_precision = precision, this_round_mode = round_mode)
149
148
  this_round_mode = BigDecimal.const_get("ROUND_#{this_round_mode.to_s.upcase}") if this_round_mode.is_a?(Symbol)
150
- amount_str = amount.round(this_precision, this_round_mode).to_s('F')
149
+ amount.round this_precision, this_round_mode
150
+ end
151
+
152
+ def round(this_precision = precision, this_round_mode = round_mode)
153
+ convert round_amount(this_precision, this_round_mode)
154
+ end
155
+
156
+ def to_i(this_round_mode = round_mode)
157
+ round_amount(0, this_round_mode).to_i
158
+ end
159
+
160
+ def to_f(this_precision = precision, this_round_mode = round_mode)
161
+ round_amount(this_precision, this_round_mode).to_i
162
+ end
163
+
164
+ def to_s(this_precision = precision, this_round_mode = round_mode)
165
+ amount_str = round_amount(this_precision, this_round_mode).to_s('F')
151
166
  dollars, cents = amount_str.split('.')
152
167
  return dollars if this_precision == 0
153
168
  if cents.size >= this_precision
@@ -159,6 +174,28 @@ class Money
159
174
 
160
175
  alias :inspect :to_s
161
176
 
177
+ def formatted(*args)
178
+ defaults = args.first.is_a?(::Symbol) ? FORMATS[args.shift] : FORMATS[:default]
179
+ options = args.last.is_a?(::Hash) ? args.pop : { }
180
+
181
+ unit = options[:unit] || defaults[:unit]
182
+ spacer = options[:spacer] || defaults[:spacer]
183
+ delimiter = options[:delimiter] || defaults[:delimiter]
184
+ separator = options[:separator] || defaults[:separator]
185
+ precision = options[:precision] || defaults[:precision]
186
+ separator = '' if precision == 0
187
+
188
+ number = to_s precision
189
+ begin
190
+ parts = number.to_s.split('.')
191
+ parts[0].gsub!(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{delimiter}")
192
+ number = parts.join(separator)
193
+ "#{unit}#{spacer}#{number}"
194
+ rescue
195
+ number
196
+ end
197
+ end
198
+
162
199
  def respond_to?(meth)
163
200
  amount.respond_to?(meth) || super
164
201
  end
@@ -192,6 +229,15 @@ class Money
192
229
  @round_mode || :half_up
193
230
  end
194
231
 
232
+ def format=(value)
233
+ raise "Unknown format options [#{value}]" unless FORMATS.key?(value)
234
+ @format = value
235
+ end
236
+
237
+ def format
238
+ @format || :default
239
+ end
240
+
195
241
  def convert(value)
196
242
  return value if value.is_a?(Money)
197
243
  new value
@@ -190,6 +190,7 @@ describe Money do
190
190
  it { Money.new('0.0').should be_zero }
191
191
  end
192
192
  end
193
+
193
194
  describe "to_s" do
194
195
  describe "no decimals" do
195
196
  let(:amt) { '3' }
@@ -269,6 +270,22 @@ describe Money do
269
270
  it { subject.to_s(6).should == amt }
270
271
  end
271
272
  end
273
+
274
+ describe "format" do
275
+ let(:amt){ '1234567.12'}
276
+ let(:neg_amt){ '-1234567.12'}
277
+ it {subject.formatted().should == '$ 1,234,567.12'}
278
+ it {subject.formatted(:no_cents).should == '$ 1,234,567'}
279
+ it {subject.formatted(:no_commas).should == '$ 1234567.12'}
280
+ it {subject.formatted(:precision => 1).should == '$ 1,234,567.1'}
281
+ it {subject.formatted(:no_commas, :precision => 1).should == '$ 1234567.1'}
282
+ it {neg_subject.formatted().should == '$ -1,234,567.12'}
283
+ it {neg_subject.formatted(:no_cents).should == '$ -1,234,567'}
284
+ it {neg_subject.formatted(:no_commas).should == '$ -1234567.12'}
285
+ it {neg_subject.formatted(:precision => 1).should == '$ -1,234,567.1'}
286
+ it {neg_subject.formatted(:no_commas, :precision => 1).should == '$ -1234567.1'}
287
+ end
288
+
272
289
  describe "forwarded" do
273
290
  describe "power" do
274
291
  subject { Money.new(amt).power 2 }
@@ -276,6 +293,7 @@ describe Money do
276
293
  it { subject.to_s.should == '12.46' }
277
294
  end
278
295
  end
296
+
279
297
  describe "Rounding" do
280
298
  let(:pos_amt1) { Money.new '1.4' }
281
299
  let(:pos_amt2) { Money.new '1.5' }
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bd_money
3
3
  version: !ruby/object:Gem::Version
4
- hash: 25
4
+ hash: 23
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 3
10
- version: 0.0.3
9
+ - 4
10
+ version: 0.0.4
11
11
  platform: ruby
12
12
  authors:
13
13
  - Adrian Madrid