cashrb 1.2.0 → 1.2.1
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/CHANGELOG.md +5 -0
- data/README.md +80 -76
- data/cashrb.gemspec +3 -3
- data/lib/cashrb/cash.rb +17 -8
- data/test/test_cash.rb +61 -1
- metadata +5 -5
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
cashrb v1.2.1
|
|
2
|
+
=============
|
|
3
|
+
- ensure objects created from internal functions such as (+ - * / % divmod)
|
|
4
|
+
return new objects that are consistent with their parents options
|
|
5
|
+
|
|
1
6
|
cashrb v1.2.0
|
|
2
7
|
=============
|
|
3
8
|
- allow creation using decimal values instead of cents if you'd rather
|
data/README.md
CHANGED
|
@@ -1,83 +1,87 @@
|
|
|
1
1
|
cashrb
|
|
2
2
|
======
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
Lightweight money and currency handler for working with financial calculations.
|
|
5
|
+
Ensures precision without sacrificing speed. Eschews complexity by only
|
|
6
|
+
providing what you need to get your job done.
|
|
5
7
|
|
|
6
8
|
Usage
|
|
7
9
|
-----
|
|
8
10
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
11
|
+
```ruby
|
|
12
|
+
require 'cashrb'
|
|
13
|
+
|
|
14
|
+
# Works with cents to avoid Floating point errors
|
|
15
|
+
n = Cash.new(100)
|
|
16
|
+
n.cents #=> 100
|
|
17
|
+
n.to_s #=> "1.00"
|
|
18
|
+
n.to_f #=> 1.0
|
|
19
|
+
|
|
20
|
+
# Don't like passing cents, set :from => :decimal and use a decimal value
|
|
21
|
+
n = Cash.new(1.11, from: :decimal)
|
|
22
|
+
n.cents #=> 111
|
|
23
|
+
n.to_s #=> "1.11"
|
|
24
|
+
n.to_f #=> 1.11
|
|
25
|
+
|
|
26
|
+
# Hate cents and always want to pass a decimal, just set the default
|
|
27
|
+
Cash.default_from = :decimal
|
|
28
|
+
n = Cash.new(1.11)
|
|
29
|
+
n.cents #=> 111
|
|
30
|
+
|
|
31
|
+
# Define currency as you see fit.
|
|
32
|
+
a = Cash.new(100, currency: :usd)
|
|
33
|
+
b = Cash.new(100, currency: :eur)
|
|
34
|
+
a + b #=> Error! Cash::IncompatibleCurrency
|
|
35
|
+
|
|
36
|
+
# Default is 100 cents in a dollar. Is your currency different, then just
|
|
37
|
+
# tell it.
|
|
38
|
+
n = Cash.new(100, cents_in_dollar: 5)
|
|
39
|
+
n.cents #=> 100
|
|
40
|
+
n.to_s #=> "20.0"
|
|
41
|
+
n.to_f #=> 20.0
|
|
42
|
+
|
|
43
|
+
n = Cash.new(100, cents_in_dollar: 10)
|
|
44
|
+
n.cents #=> 100
|
|
45
|
+
n.to_s #=> "10.0"
|
|
46
|
+
n.to_f #=> 10.0
|
|
47
|
+
|
|
48
|
+
n = Cash.new(100, cents_in_dollar: 1)
|
|
49
|
+
n.cents #=> 100
|
|
50
|
+
n.to_s #=> "100"
|
|
51
|
+
n.to_f #=> 100.0
|
|
52
|
+
|
|
53
|
+
# The default rounding method when dealing with fractional cents is
|
|
54
|
+
# BigDecimal::ROUND_HALF_UP. Would you rather use bankers rounding; just
|
|
55
|
+
# pass it as an argument.
|
|
56
|
+
n = Cash.new(2.5)
|
|
57
|
+
n.cents #=> 3
|
|
58
|
+
|
|
59
|
+
n = Cash.new(2.5, rounding_method: BigDecimal::ROUND_HALF_EVEN)
|
|
60
|
+
n.cents #=> 2
|
|
61
|
+
|
|
62
|
+
# Sick of specifying :cents_in_whole, :rounding_method and :currency; just
|
|
63
|
+
# set their defaults.
|
|
64
|
+
Cash.default_cents_in_whole = 10
|
|
65
|
+
Cash.default_rounding_method = BigDecimal::ROUND_DOWN
|
|
66
|
+
Cash.default_currency = :EUR
|
|
67
|
+
|
|
68
|
+
n = Cash.new(100)
|
|
69
|
+
n.to_s #=> "10.0"
|
|
70
|
+
n.to_f #=> 10.0
|
|
71
|
+
n.currency #=> :EUR
|
|
72
|
+
|
|
73
|
+
n = Cash.new(1.9)
|
|
74
|
+
n.cents #=> 1
|
|
75
|
+
|
|
76
|
+
# If your currency object implements :cents_in_whole, we'll go ahead and
|
|
77
|
+
# use that.
|
|
78
|
+
|
|
79
|
+
module MyCurrency
|
|
80
|
+
def self.cents_in_whole
|
|
81
|
+
10
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
n = Cash.new(9, :currency => MyCurrency)
|
|
86
|
+
n.to_f #=> 0.9
|
|
87
|
+
```
|
data/cashrb.gemspec
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
Gem::Specification.new do |s|
|
|
2
2
|
s.name = "cashrb"
|
|
3
|
-
s.version = "1.2.
|
|
3
|
+
s.version = "1.2.1"
|
|
4
4
|
s.platform = Gem::Platform::RUBY
|
|
5
5
|
s.authors = ["Shane Emmons"]
|
|
6
6
|
s.email = ["semmons99@gmail.com"]
|
|
7
7
|
s.homepage = "http://semmons99.github.com/cashrb/"
|
|
8
|
-
s.summary = "
|
|
9
|
-
s.description = "
|
|
8
|
+
s.summary = "Lightweight money and currency handler for working with financial calculations."
|
|
9
|
+
s.description = "Lightweight money and currency handler for working with financial calculations."
|
|
10
10
|
|
|
11
11
|
s.required_ruby_version = ">= 1.8.7"
|
|
12
12
|
s.required_rubygems_version = ">= 1.3.6"
|
data/lib/cashrb/cash.rb
CHANGED
|
@@ -71,35 +71,35 @@ class Cash
|
|
|
71
71
|
end
|
|
72
72
|
|
|
73
73
|
def +(value)
|
|
74
|
-
Cash.new(@cents + value.cents)
|
|
74
|
+
Cash.new(@cents + value.cents, new_options)
|
|
75
75
|
end
|
|
76
76
|
|
|
77
77
|
def -(value)
|
|
78
|
-
Cash.new(@cents - value.cents)
|
|
78
|
+
Cash.new(@cents - value.cents, new_options)
|
|
79
79
|
end
|
|
80
80
|
|
|
81
81
|
def *(value)
|
|
82
|
-
Cash.new(@cents * bd(value))
|
|
82
|
+
Cash.new(@cents * bd(value), new_options)
|
|
83
83
|
end
|
|
84
84
|
|
|
85
85
|
def /(value)
|
|
86
86
|
@cents / value.cents
|
|
87
87
|
rescue NoMethodError
|
|
88
|
-
Cash.new(@cents / bd(value))
|
|
88
|
+
Cash.new(@cents / bd(value), new_options)
|
|
89
89
|
end
|
|
90
90
|
|
|
91
91
|
def %(value)
|
|
92
|
-
Cash.new(@cents % value.cents)
|
|
92
|
+
Cash.new(@cents % value.cents, new_options)
|
|
93
93
|
rescue NoMethodError
|
|
94
|
-
Cash.new(@cents % bd(value))
|
|
94
|
+
Cash.new(@cents % bd(value), new_options)
|
|
95
95
|
end
|
|
96
96
|
|
|
97
97
|
def divmod(value)
|
|
98
98
|
quotient, remainder = @cents.divmod value.cents
|
|
99
|
-
[quotient, Cash.new(remainder)]
|
|
99
|
+
[quotient, Cash.new(remainder, new_options)]
|
|
100
100
|
rescue NoMethodError
|
|
101
101
|
quotient, remainder = @cents.divmod bd(value)
|
|
102
|
-
[Cash.new(quotient), Cash.new(remainder)]
|
|
102
|
+
[Cash.new(quotient, new_options), Cash.new(remainder, new_options)]
|
|
103
103
|
end
|
|
104
104
|
|
|
105
105
|
def <=>(value)
|
|
@@ -179,4 +179,13 @@ class Cash
|
|
|
179
179
|
rescue NoMethodError
|
|
180
180
|
end
|
|
181
181
|
|
|
182
|
+
def new_options
|
|
183
|
+
{
|
|
184
|
+
:cents_in_whole => @cents_in_whole,
|
|
185
|
+
:rounding_method => @rounding_method,
|
|
186
|
+
:currency => @currency,
|
|
187
|
+
:from => :cents,
|
|
188
|
+
}
|
|
189
|
+
end
|
|
190
|
+
|
|
182
191
|
end
|
data/test/test_cash.rb
CHANGED
|
@@ -143,6 +143,16 @@ class TestCash < MiniTest::Unit::TestCase
|
|
|
143
143
|
end
|
|
144
144
|
end
|
|
145
145
|
|
|
146
|
+
def test_plus_with_modified_defaults
|
|
147
|
+
Cash.default_cents_in_whole = 10
|
|
148
|
+
Cash.default_rounding_method = BigDecimal::ROUND_UP
|
|
149
|
+
Cash.default_currency = :usd
|
|
150
|
+
Cash.default_from = :decimal
|
|
151
|
+
|
|
152
|
+
rs = Cash.new(10) + Cash.new(5)
|
|
153
|
+
assert_equal Cash.new(15), rs
|
|
154
|
+
end
|
|
155
|
+
|
|
146
156
|
def test_minus_with_Cash_Cash
|
|
147
157
|
rs = Cash.new(6) - Cash.new(4)
|
|
148
158
|
assert_equal Cash.new(2), rs
|
|
@@ -154,11 +164,31 @@ class TestCash < MiniTest::Unit::TestCase
|
|
|
154
164
|
end
|
|
155
165
|
end
|
|
156
166
|
|
|
157
|
-
def
|
|
167
|
+
def test_minus_with_modified_defaults
|
|
168
|
+
Cash.default_cents_in_whole = 10
|
|
169
|
+
Cash.default_rounding_method = BigDecimal::ROUND_UP
|
|
170
|
+
Cash.default_currency = :usd
|
|
171
|
+
Cash.default_from = :decimal
|
|
172
|
+
|
|
173
|
+
rs = Cash.new(10) - Cash.new(5)
|
|
174
|
+
assert_equal Cash.new(5), rs
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
def test_multiply_with_Cash_Numeric
|
|
158
178
|
rs = Cash.new(6) * 2
|
|
159
179
|
assert_equal Cash.new(12), rs
|
|
160
180
|
end
|
|
161
181
|
|
|
182
|
+
def test_multiply_with_modified_defaults
|
|
183
|
+
Cash.default_cents_in_whole = 10
|
|
184
|
+
Cash.default_rounding_method = BigDecimal::ROUND_UP
|
|
185
|
+
Cash.default_currency = :usd
|
|
186
|
+
Cash.default_from = :decimal
|
|
187
|
+
|
|
188
|
+
rs = Cash.new(10) * 5
|
|
189
|
+
assert_equal Cash.new(50), rs
|
|
190
|
+
end
|
|
191
|
+
|
|
162
192
|
def test_divide_with_Cash_Cash
|
|
163
193
|
rs = Cash.new(6) / Cash.new(4)
|
|
164
194
|
assert_equal BigDecimal("1.5"), rs
|
|
@@ -175,6 +205,16 @@ class TestCash < MiniTest::Unit::TestCase
|
|
|
175
205
|
assert_equal Cash.new(3), rs
|
|
176
206
|
end
|
|
177
207
|
|
|
208
|
+
def test_divide_with_modified_defaults
|
|
209
|
+
Cash.default_cents_in_whole = 10
|
|
210
|
+
Cash.default_rounding_method = BigDecimal::ROUND_UP
|
|
211
|
+
Cash.default_currency = :usd
|
|
212
|
+
Cash.default_from = :decimal
|
|
213
|
+
|
|
214
|
+
rs = Cash.new(10) / 5
|
|
215
|
+
assert_equal Cash.new(2), rs
|
|
216
|
+
end
|
|
217
|
+
|
|
178
218
|
def test_modulo_with_Cash_Cash
|
|
179
219
|
rs = Cash.new(6) % Cash.new(4)
|
|
180
220
|
assert_equal Cash.new(2), rs
|
|
@@ -191,6 +231,16 @@ class TestCash < MiniTest::Unit::TestCase
|
|
|
191
231
|
assert_equal Cash.new(2), rs
|
|
192
232
|
end
|
|
193
233
|
|
|
234
|
+
def test_modulo_with_modified_defaults
|
|
235
|
+
Cash.default_cents_in_whole = 10
|
|
236
|
+
Cash.default_rounding_method = BigDecimal::ROUND_UP
|
|
237
|
+
Cash.default_currency = :usd
|
|
238
|
+
Cash.default_from = :decimal
|
|
239
|
+
|
|
240
|
+
rs = Cash.new(6) % 7
|
|
241
|
+
assert_equal Cash.new(0.4), rs
|
|
242
|
+
end
|
|
243
|
+
|
|
194
244
|
def test_divmod_with_Cash_Cash
|
|
195
245
|
rs = Cash.new(6).divmod(Cash.new(4))
|
|
196
246
|
assert_equal [BigDecimal("1"), Cash.new(2)], rs
|
|
@@ -207,6 +257,16 @@ class TestCash < MiniTest::Unit::TestCase
|
|
|
207
257
|
assert_equal [Cash.new(1), Cash.new(2)], rs
|
|
208
258
|
end
|
|
209
259
|
|
|
260
|
+
def test_divmod_with_modified_defaults
|
|
261
|
+
Cash.default_cents_in_whole = 10
|
|
262
|
+
Cash.default_rounding_method = BigDecimal::ROUND_UP
|
|
263
|
+
Cash.default_currency = :usd
|
|
264
|
+
Cash.default_from = :decimal
|
|
265
|
+
|
|
266
|
+
rs = Cash.new(6).divmod(40)
|
|
267
|
+
assert_equal [Cash.new(0.1), Cash.new(2)], rs
|
|
268
|
+
end
|
|
269
|
+
|
|
210
270
|
def test_equal_to_when_equal_to
|
|
211
271
|
rs = Cash.new(6) == Cash.new(6)
|
|
212
272
|
assert rs
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: cashrb
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.2.
|
|
4
|
+
version: 1.2.1
|
|
5
5
|
prerelease:
|
|
6
6
|
platform: ruby
|
|
7
7
|
authors:
|
|
@@ -9,9 +9,9 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date: 2011-
|
|
12
|
+
date: 2011-05-09 00:00:00.000000000Z
|
|
13
13
|
dependencies: []
|
|
14
|
-
description:
|
|
14
|
+
description: Lightweight money and currency handler for working with financial calculations.
|
|
15
15
|
email:
|
|
16
16
|
- semmons99@gmail.com
|
|
17
17
|
executables: []
|
|
@@ -48,8 +48,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
48
48
|
requirements:
|
|
49
49
|
- minitest
|
|
50
50
|
rubyforge_project:
|
|
51
|
-
rubygems_version: 1.
|
|
51
|
+
rubygems_version: 1.8.1
|
|
52
52
|
signing_key:
|
|
53
53
|
specification_version: 3
|
|
54
|
-
summary:
|
|
54
|
+
summary: Lightweight money and currency handler for working with financial calculations.
|
|
55
55
|
test_files: []
|