bd_money 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
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