safe_money 0.0.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.
- checksums.yaml +7 -0
- data/.gitignore +22 -0
- data/.rspec +3 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +77 -0
- data/Rakefile +5 -0
- data/lib/safe_money/version.rb +3 -0
- data/lib/safe_money.rb +124 -0
- data/safe_money.gemspec +25 -0
- data/spec/safe_money_spec.rb +292 -0
- data/spec/spec_helper.rb +10 -0
- metadata +113 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 7043291fe6f136304f269d617f015cf639874775
|
4
|
+
data.tar.gz: 941bc0966d50a64ecd0872e80563d6eec8ba9c3e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: fe0bcb5313b7423ea74698472f6ce4a30d6d6df07fd3f584f97ba3c101363aef4b17b98f8a99858ce42a11cba007f942b349828015d8902ec977e3e4613977de
|
7
|
+
data.tar.gz: 9d5d0c6cce93f4752acfa79cdcd93083c3a0f437f0e8f3573ec4a1ee5b663c7d287352dc94ef8b6936a481f2c1ace269f477c65e3caf84f1ad4f32c3a708148a
|
data/.gitignore
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
6
|
+
Gemfile.lock
|
7
|
+
InstalledFiles
|
8
|
+
_yardoc
|
9
|
+
coverage
|
10
|
+
doc/
|
11
|
+
lib/bundler/man
|
12
|
+
pkg
|
13
|
+
rdoc
|
14
|
+
spec/reports
|
15
|
+
test/tmp
|
16
|
+
test/version_tmp
|
17
|
+
tmp
|
18
|
+
*.bundle
|
19
|
+
*.so
|
20
|
+
*.o
|
21
|
+
*.a
|
22
|
+
mkmf.log
|
data/.rspec
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Jared Grippe
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
# SafeMoney
|
2
|
+
|
3
|
+
Safe Money helps prevent unwanted arithmetic errors by representing money as an Integer of cents and preventing pennies from being split up.
|
4
|
+
|
5
|
+
If you've ever represented money using floats or ints you've likely made a mistake like this:
|
6
|
+
|
7
|
+
```ruby
|
8
|
+
10.99 / 2 # => 5.495
|
9
|
+
```
|
10
|
+
|
11
|
+
You've just split a penny in half. No good!
|
12
|
+
|
13
|
+
If you're using integers you can make the same mistake but it's even harder to notice
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
1099 / 2 # => 549
|
17
|
+
```
|
18
|
+
|
19
|
+
You've just thrown a penny into the well of bad math.
|
20
|
+
|
21
|
+
|
22
|
+
Safe Money prevents you from making these sorts of mistakes
|
23
|
+
|
24
|
+
```ruby
|
25
|
+
10.99.dollars / 2 # => SafeMoney::ArithmeticError: $10.99 cannot be safely divided by 2
|
26
|
+
```
|
27
|
+
|
28
|
+
## Usage
|
29
|
+
|
30
|
+
```ruby
|
31
|
+
|
32
|
+
100.cents # => $1.00
|
33
|
+
|
34
|
+
100.5.cents # => SafeMoney::CoercionError: 100.5 cannot safely be converted into cents
|
35
|
+
|
36
|
+
10.99.dollars # => $10.99
|
37
|
+
|
38
|
+
10.995.dollars # => SafeMoney::CoercionError: 10.995 cannot safely be converted into cents
|
39
|
+
|
40
|
+
1099.cents # => $10.99
|
41
|
+
|
42
|
+
100.dollars + 15.cents # => $100.15
|
43
|
+
|
44
|
+
100.dollars + 15 # => $100.15
|
45
|
+
|
46
|
+
100 + 10.dollars # => 1100
|
47
|
+
|
48
|
+
100 + 10.cents # => 110
|
49
|
+
|
50
|
+
# Bad Maths
|
51
|
+
1099 * 0.14 # => 153.86
|
52
|
+
10.99 * 0.14 # => 1.5386000000000002
|
53
|
+
1099.cents * 0.14 # => SafeMoney::ArithmeticError: $10.99 cannot be safely multiplied by 0.14
|
54
|
+
|
55
|
+
```
|
56
|
+
|
57
|
+
## Installation
|
58
|
+
|
59
|
+
Add this line to your application's Gemfile:
|
60
|
+
|
61
|
+
gem 'safe_money'
|
62
|
+
|
63
|
+
And then execute:
|
64
|
+
|
65
|
+
$ bundle
|
66
|
+
|
67
|
+
Or install it yourself as:
|
68
|
+
|
69
|
+
$ gem install safe_money
|
70
|
+
|
71
|
+
## Contributing
|
72
|
+
|
73
|
+
1. Fork it ( https://github.com/deadlyicon/safe_money/fork )
|
74
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
75
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
76
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
77
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
data/lib/safe_money.rb
ADDED
@@ -0,0 +1,124 @@
|
|
1
|
+
require "safe_money/version"
|
2
|
+
|
3
|
+
class SafeMoney
|
4
|
+
|
5
|
+
CoercionError = Class.new(TypeError)
|
6
|
+
ArithmeticError = Class.new(ArgumentError)
|
7
|
+
|
8
|
+
class << self
|
9
|
+
|
10
|
+
def cents number
|
11
|
+
return number if number.is_a?(self)
|
12
|
+
raise ArgumentError, 'cents must be Numeric' unless number.is_a?(Numeric)
|
13
|
+
cents = if number.is_a?(Float)
|
14
|
+
raise CoercionError, "#{number} cannot safely be converted into cents" unless number.to_i == number
|
15
|
+
number.to_i
|
16
|
+
else
|
17
|
+
number
|
18
|
+
end
|
19
|
+
new cents
|
20
|
+
end
|
21
|
+
|
22
|
+
alias_method :[], :cents
|
23
|
+
|
24
|
+
def dollars number
|
25
|
+
return number if number.is_a?(self)
|
26
|
+
raise ArgumentError, 'dollars must be Numeric' unless number.is_a?(Numeric)
|
27
|
+
if number != number.round(2)
|
28
|
+
raise CoercionError, "#{number} cannot safely be converted into cents"
|
29
|
+
end
|
30
|
+
cents = (number * 100.00).round
|
31
|
+
new cents
|
32
|
+
end
|
33
|
+
|
34
|
+
private :new
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
def initialize cents
|
39
|
+
raise ArgumentError, 'cents must be an Integer' unless cents.is_a?(Integer)
|
40
|
+
@cents = cents
|
41
|
+
freeze
|
42
|
+
end
|
43
|
+
|
44
|
+
def to_i
|
45
|
+
@cents
|
46
|
+
end
|
47
|
+
|
48
|
+
%w{ even? odd? zero? to_f < <= == > >= <=> eql? to_json coerce }.each do |method_name|
|
49
|
+
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
50
|
+
def #{method_name}(*args, &block)
|
51
|
+
to_i.send(:#{method_name}, *args, &block)
|
52
|
+
end
|
53
|
+
RUBY
|
54
|
+
end
|
55
|
+
|
56
|
+
def to_dollars
|
57
|
+
(@cents * 0.01).round(2)
|
58
|
+
end
|
59
|
+
|
60
|
+
def + number
|
61
|
+
self.class.cents( to_i + number )
|
62
|
+
rescue CoercionError
|
63
|
+
raise ArithmeticError, "#{number} cannot be safely added to #{self}"
|
64
|
+
end
|
65
|
+
|
66
|
+
def - number
|
67
|
+
self.class.cents( to_i - number )
|
68
|
+
rescue CoercionError
|
69
|
+
raise ArithmeticError, "#{number} cannot be safely subtracted from #{self}"
|
70
|
+
end
|
71
|
+
|
72
|
+
def * number
|
73
|
+
self.class.cents( to_f * number )
|
74
|
+
rescue CoercionError
|
75
|
+
raise ArithmeticError, "#{self} cannot be safely multiplied by #{number}"
|
76
|
+
end
|
77
|
+
|
78
|
+
def / number
|
79
|
+
self.class.cents( to_f / number )
|
80
|
+
rescue CoercionError
|
81
|
+
raise ArithmeticError, "#{self} cannot be safely divided by #{number}"
|
82
|
+
end
|
83
|
+
|
84
|
+
alias_method :div, :/
|
85
|
+
|
86
|
+
def -@
|
87
|
+
self.class.cents(-to_i)
|
88
|
+
end
|
89
|
+
|
90
|
+
def positive?
|
91
|
+
self > 0
|
92
|
+
end
|
93
|
+
|
94
|
+
def negative?
|
95
|
+
self < 0
|
96
|
+
end
|
97
|
+
|
98
|
+
def inspect
|
99
|
+
dollars = to_dollars
|
100
|
+
"#{'-' if dollars < 0}$#{sprintf('%.2f', dollars.abs)}"
|
101
|
+
end
|
102
|
+
alias_method :to_s, :inspect
|
103
|
+
alias_method :to_str, :inspect
|
104
|
+
|
105
|
+
def as_json options=nil
|
106
|
+
to_i
|
107
|
+
end
|
108
|
+
|
109
|
+
def to_param
|
110
|
+
to_i.to_s
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
|
115
|
+
class Numeric
|
116
|
+
def dollars
|
117
|
+
SafeMoney.dollars(self)
|
118
|
+
end
|
119
|
+
alias_method :dollar, :dollars
|
120
|
+
def cents
|
121
|
+
SafeMoney.cents(self)
|
122
|
+
end
|
123
|
+
alias_method :cent, :cents
|
124
|
+
end
|
data/safe_money.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'safe_money/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "safe_money"
|
8
|
+
spec.version = SafeMoney::VERSION
|
9
|
+
spec.authors = ["Jared Grippe"]
|
10
|
+
spec.email = ["jared@deadlyicon.com"]
|
11
|
+
spec.summary = %q{represent cents with safe arithmetic}
|
12
|
+
spec.description = %q{represent cents with safe arithmetic}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency 'bundler', '~> 1.6'
|
22
|
+
spec.add_development_dependency 'rake'
|
23
|
+
spec.add_development_dependency 'rspec'
|
24
|
+
spec.add_development_dependency 'pry'
|
25
|
+
end
|
@@ -0,0 +1,292 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe SafeMoney do
|
4
|
+
|
5
|
+
it 'SafeMoney.new(1000) should rais a NoMethodError' do
|
6
|
+
expect{ SafeMoney.new(1000) }.to raise_error NoMethodError
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'SafeMoney.cents(1000) should be frozen' do
|
10
|
+
expect( SafeMoney.cents(1000) ).to be_frozen
|
11
|
+
end
|
12
|
+
|
13
|
+
# SafeMoney.cents
|
14
|
+
|
15
|
+
it 'SafeMoney.cents(1000).inspect should equal "$10.00"' do
|
16
|
+
expect( SafeMoney.cents(1000).inspect ).to eq "$10.00"
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'SafeMoney.cents(10.00).inspect should equal "$0.10"' do
|
20
|
+
expect( SafeMoney.cents(10.00).inspect ).to eq "$0.10"
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'SafeMoney.cents(10.15) should raise a SafeMoney::CoercionError' do
|
24
|
+
expect{ SafeMoney.cents(10.15) }.to raise_error SafeMoney::CoercionError, '10.15 cannot safely be converted into cents'
|
25
|
+
end
|
26
|
+
|
27
|
+
# SafeMoney.dollars
|
28
|
+
|
29
|
+
it 'SafeMoney.dollars(1000).inspect should equal "$1000.00"' do
|
30
|
+
expect( SafeMoney.dollars(1000).inspect ).to eq "$1000.00"
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'SafeMoney.dollars(10.15).inspect should equal "$10.15"' do
|
34
|
+
expect( SafeMoney.dollars(10.15).inspect ).to eq "$10.15"
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'SafeMoney.dollars(10.154) should raise a SafeMoney::CoercionError' do
|
38
|
+
expect{ SafeMoney.dollars(10.154) }.to raise_error SafeMoney::CoercionError, '10.154 cannot safely be converted into cents'
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
it 'SafeMoney.cents(1020) should equal 1020' do
|
43
|
+
expect( SafeMoney.cents(1020) ).to eq 1020
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'SafeMoney.cents(1020).to_dollars should equal 10.20' do
|
47
|
+
expect( SafeMoney.cents(1020).to_dollars ).to eq 10.20
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'SafeMoney.cents(1020).positive? should be true' do
|
51
|
+
expect( SafeMoney.cents(1020).positive? ).to be_truthy
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'SafeMoney.cents(1020).negative? should be false' do
|
55
|
+
expect( SafeMoney.cents(1020).negative? ).to be_falsey
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'SafeMoney.cents(1020).inspect should equal "$10.20"' do
|
59
|
+
expect( SafeMoney.cents(1020).inspect ).to eq "$10.20"
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
it 'SafeMoney.cents(-1020) should equal -1020' do
|
64
|
+
expect( SafeMoney.cents(-1020) ).to eq(-1020)
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'SafeMoney.cents(-1020).to_dollars should equal -10.20' do
|
68
|
+
expect( SafeMoney.cents(-1020).to_dollars ).to eq(-10.20)
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'SafeMoney.cents(-1020).positive? should be false' do
|
72
|
+
expect( SafeMoney.cents(-1020).positive? ).to be_falsey
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'SafeMoney.cents(-1020).negative? should be true' do
|
76
|
+
expect( SafeMoney.cents(-1020).negative? ).to be_truthy
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'SafeMoney.cents(-1020).inspect should equal "-$10.20"' do
|
80
|
+
expect( SafeMoney.cents(-1020).inspect ).to eq "-$10.20"
|
81
|
+
end
|
82
|
+
|
83
|
+
|
84
|
+
|
85
|
+
it 'SafeMoney.dollars(10.20) should equal 1020' do
|
86
|
+
expect( SafeMoney.dollars(10.20) ).to eq 1020
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'SafeMoney.dollars(10.20).to_dollars should equal 10.20' do
|
90
|
+
expect( SafeMoney.dollars(10.20).to_dollars ).to eq 10.20
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'SafeMoney.dollars(10.20).positive? should be true' do
|
94
|
+
expect( SafeMoney.dollars(10.20).positive? ).to be_truthy
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'SafeMoney.dollars(10.20).negative? should be false' do
|
98
|
+
expect( SafeMoney.dollars(10.20).negative? ).to be_falsey
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'SafeMoney.dollars(10.20).inspect should equal "$10.20"' do
|
102
|
+
expect( SafeMoney.dollars(10.20).inspect ).to eq "$10.20"
|
103
|
+
end
|
104
|
+
|
105
|
+
|
106
|
+
it 'SafeMoney.dollars(-10.20) should equal -1020' do
|
107
|
+
expect( SafeMoney.dollars(-10.20) ).to eq(-1020)
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'SafeMoney.dollars(-10.20).to_dollars should equal -10.20' do
|
111
|
+
expect( SafeMoney.dollars(-10.20).to_dollars ).to eq(-10.20)
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'SafeMoney.dollars(-10.20).positive? should be false' do
|
115
|
+
expect( SafeMoney.dollars(-10.20).positive? ).to be_falsey
|
116
|
+
end
|
117
|
+
|
118
|
+
it 'SafeMoney.dollars(-10.20).negative? should be true' do
|
119
|
+
expect( SafeMoney.dollars(-10.20).negative? ).to be_truthy
|
120
|
+
end
|
121
|
+
|
122
|
+
it 'SafeMoney.dollars(-10.20).inspect should equal "-$10.20"' do
|
123
|
+
expect( SafeMoney.dollars(-10.20).inspect ).to eq "-$10.20"
|
124
|
+
end
|
125
|
+
|
126
|
+
|
127
|
+
|
128
|
+
|
129
|
+
it 'SafeMoney.cents(199) == SafeMoney.cents(199) should be true' do
|
130
|
+
expect( SafeMoney.cents(199) == SafeMoney.cents(199) ).to be_truthy
|
131
|
+
end
|
132
|
+
|
133
|
+
it 'SafeMoney.cents(199) == SafeMoney.cents(200) should be false' do
|
134
|
+
expect( SafeMoney.cents(199) == SafeMoney.cents(200) ).to be_falsey
|
135
|
+
end
|
136
|
+
|
137
|
+
it 'SafeMoney.cents(199) > SafeMoney.cents(199) should be false' do
|
138
|
+
expect( SafeMoney.cents(199) > SafeMoney.cents(199) ).to be_falsey
|
139
|
+
end
|
140
|
+
|
141
|
+
it 'SafeMoney.cents(199) < SafeMoney.cents(199) should be false' do
|
142
|
+
expect( SafeMoney.cents(199) < SafeMoney.cents(199) ).to be_falsey
|
143
|
+
end
|
144
|
+
|
145
|
+
it 'SafeMoney.cents(199) > SafeMoney.cents(299) should be false' do
|
146
|
+
expect( SafeMoney.cents(199) > SafeMoney.cents(199) ).to be_falsey
|
147
|
+
end
|
148
|
+
|
149
|
+
it 'SafeMoney.cents(199) < SafeMoney.cents(299) should be true' do
|
150
|
+
expect( SafeMoney.cents(199) < SafeMoney.cents(299) ).to be_truthy
|
151
|
+
end
|
152
|
+
|
153
|
+
it 'SafeMoney.cents(200) > 100 should be true' do
|
154
|
+
expect( SafeMoney.cents(200) > 100 ).to be_truthy
|
155
|
+
end
|
156
|
+
|
157
|
+
it '200 > SafeMoney.cents(100) should be true' do
|
158
|
+
expect( 200 > SafeMoney.cents(100) ).to be_truthy
|
159
|
+
end
|
160
|
+
|
161
|
+
it 'SafeMoney.cents(200) < 100 should be false' do
|
162
|
+
expect( SafeMoney.cents(200) < 100 ).to be_falsey
|
163
|
+
end
|
164
|
+
|
165
|
+
it '200 < SafeMoney.cents(100) should be false' do
|
166
|
+
expect( 200 < SafeMoney.cents(100) ).to be_falsey
|
167
|
+
end
|
168
|
+
|
169
|
+
|
170
|
+
it 'SafeMoney.cents(1245) should equal SafeMoney.cents(1245)' do
|
171
|
+
expect( SafeMoney.cents(1245) ).to eq SafeMoney.cents(1245)
|
172
|
+
end
|
173
|
+
|
174
|
+
it 'SafeMoney.cents(15) + 5 should equal SafeMoney.cents(20)' do
|
175
|
+
expect(SafeMoney.cents(15) + 5).to eq SafeMoney.cents(20)
|
176
|
+
end
|
177
|
+
|
178
|
+
|
179
|
+
it 'SafeMoney.cents(1024) should not raise error' do
|
180
|
+
expect{ SafeMoney.cents(1024) }.to_not raise_error
|
181
|
+
end
|
182
|
+
|
183
|
+
it 'SafeMoney.cents(10.24) should raise SafeMoney::CoercionError' do
|
184
|
+
expect{ SafeMoney.cents(10.24) }.to raise_error SafeMoney::CoercionError, '10.24 cannot safely be converted into cents'
|
185
|
+
end
|
186
|
+
|
187
|
+
it 'SafeMoney.cents(nil) should raise ArgumentError' do
|
188
|
+
expect{ SafeMoney.cents(nil) }.to raise_error ArgumentError, 'cents must be Numeric'
|
189
|
+
end
|
190
|
+
|
191
|
+
it 'SafeMoney.dollars(nil) should raise ArgumentError' do
|
192
|
+
expect{ SafeMoney.cents(nil) }.to raise_error ArgumentError, 'cents must be Numeric'
|
193
|
+
end
|
194
|
+
|
195
|
+
it 'SafeMoney.cents("12") should raise ArgumentError' do
|
196
|
+
expect{ SafeMoney.cents("12") }.to raise_error ArgumentError, 'cents must be Numeric'
|
197
|
+
end
|
198
|
+
|
199
|
+
it 'SafeMoney.dollars("12") should raise ArgumentError' do
|
200
|
+
expect{ SafeMoney.cents("12") }.to raise_error ArgumentError, 'cents must be Numeric'
|
201
|
+
end
|
202
|
+
|
203
|
+
|
204
|
+
|
205
|
+
it 'SafeMoney.cents(100) / 2 equal SafeMoney.cents(50)' do
|
206
|
+
expect( SafeMoney.cents(100) / 2 ).to eq SafeMoney.cents(50)
|
207
|
+
end
|
208
|
+
|
209
|
+
it 'SafeMoney.cents(100) / 2.0 equal SafeMoney.cents(50)' do
|
210
|
+
expect( SafeMoney.cents(100) / 2.0 ).to eq SafeMoney.cents(50)
|
211
|
+
end
|
212
|
+
|
213
|
+
it 'SafeMoney.cents(100) / 0.2 equal SafeMoney.cents(500)' do
|
214
|
+
expect( SafeMoney.cents(100) / 0.2 ).to eq SafeMoney.cents(500)
|
215
|
+
end
|
216
|
+
|
217
|
+
it 'SafeMoney.cents(100) / 0.3 should raise SafeMoney::ArithmeticError' do
|
218
|
+
expect{ SafeMoney.cents(100) / 0.3 }.to raise_error SafeMoney::ArithmeticError, "$1.00 cannot be safely divided by 0.3"
|
219
|
+
end
|
220
|
+
|
221
|
+
it 'SafeMoney.cents(1099) / 0.3 should raise SafeMoney::ArithmeticError' do
|
222
|
+
expect{ SafeMoney.cents(1099) / 2 }.to raise_error SafeMoney::ArithmeticError, "$10.99 cannot be safely divided by 2"
|
223
|
+
end
|
224
|
+
|
225
|
+
it 'SafeMoney.cents(100) * 1 should equal SafeMoney.cents(100)' do
|
226
|
+
expect( SafeMoney.cents(100) * 1 ).to eq SafeMoney.cents(100)
|
227
|
+
end
|
228
|
+
|
229
|
+
it 'SafeMoney.cents(100) * 0.5 should equal SafeMoney.cents(50)' do
|
230
|
+
expect( SafeMoney.cents(100) * 0.5 ).to eq SafeMoney.cents(50)
|
231
|
+
end
|
232
|
+
|
233
|
+
it 'SafeMoney.cents(100) * 0.5467 should raise SafeMoney::ArithmeticError' do
|
234
|
+
expect{ SafeMoney.cents(100) * 0.5467 }.to raise_error SafeMoney::ArithmeticError, "$1.00 cannot be safely multiplied by 0.5467"
|
235
|
+
end
|
236
|
+
|
237
|
+
|
238
|
+
it '12.35.dollars should equal SafeMoney.dollars(12.35)' do
|
239
|
+
expect( 12.35.dollars ).to eq SafeMoney.dollars(12.35)
|
240
|
+
end
|
241
|
+
|
242
|
+
it '12.35.cents should raise a SafeMoney::CoercionError' do
|
243
|
+
expect{ 12.35.cents }.to raise_error SafeMoney::CoercionError
|
244
|
+
end
|
245
|
+
|
246
|
+
it '12.cents should equal SafeMoney.cents(12)' do
|
247
|
+
expect( 12.cents ).to eq SafeMoney.cents(12)
|
248
|
+
end
|
249
|
+
|
250
|
+
it 'SafeMoney.cents(SafeMoney.cents(1234)) should equal SafeMoney.cents(1234)' do
|
251
|
+
money = SafeMoney.cents(1234)
|
252
|
+
expect( SafeMoney.cents(money) ).to be money
|
253
|
+
end
|
254
|
+
|
255
|
+
it 'SafeMoney.dollars(SafeMoney.dollars(1234)) should equal SafeMoney.dollars(1234)' do
|
256
|
+
money = SafeMoney.dollars(1234)
|
257
|
+
expect( SafeMoney.dollars(money) ).to be money
|
258
|
+
end
|
259
|
+
|
260
|
+
it 'SafeMoney.cents(1234).as_json should equal 1234' do
|
261
|
+
expect( SafeMoney.cents(1234).as_json ).to eq 1234
|
262
|
+
end
|
263
|
+
|
264
|
+
it 'SafeMoney.cents(1234).to_json should equal "1234"' do
|
265
|
+
expect( SafeMoney.cents(1234).to_json ).to eq "1234"
|
266
|
+
end
|
267
|
+
|
268
|
+
|
269
|
+
it '-SafeMoney.cents(1234) should equal SafeMoney.cents(-1234)' do
|
270
|
+
expect( -SafeMoney.cents(1234) ).to eq SafeMoney.cents(-1234)
|
271
|
+
end
|
272
|
+
|
273
|
+
# Coercion
|
274
|
+
|
275
|
+
it 'SafeMoney.cents(1099).coerce(10) should equal [10, 1099]' do
|
276
|
+
left, right = SafeMoney.cents(1099).coerce(10)
|
277
|
+
expect( left ).to be_a Integer
|
278
|
+
expect( right ).to be_a Integer
|
279
|
+
expect( left ).to eq 10
|
280
|
+
expect( right ).to eq 1099
|
281
|
+
end
|
282
|
+
|
283
|
+
it 'SafeMoney.cents(1099).coerce(10.5) should equal [10, 1099.0]' do
|
284
|
+
left, right = SafeMoney.cents(1099).coerce(10.5)
|
285
|
+
expect( left ).to be_a Float
|
286
|
+
expect( right ).to be_a Float
|
287
|
+
expect( left ).to eq 10.5
|
288
|
+
expect( right ).to eq 1099.0
|
289
|
+
end
|
290
|
+
|
291
|
+
|
292
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: safe_money
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jared Grippe
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-06-13 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.6'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.6'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: pry
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
description: represent cents with safe arithmetic
|
70
|
+
email:
|
71
|
+
- jared@deadlyicon.com
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- ".gitignore"
|
77
|
+
- ".rspec"
|
78
|
+
- Gemfile
|
79
|
+
- LICENSE.txt
|
80
|
+
- README.md
|
81
|
+
- Rakefile
|
82
|
+
- lib/safe_money.rb
|
83
|
+
- lib/safe_money/version.rb
|
84
|
+
- safe_money.gemspec
|
85
|
+
- spec/safe_money_spec.rb
|
86
|
+
- spec/spec_helper.rb
|
87
|
+
homepage: ''
|
88
|
+
licenses:
|
89
|
+
- MIT
|
90
|
+
metadata: {}
|
91
|
+
post_install_message:
|
92
|
+
rdoc_options: []
|
93
|
+
require_paths:
|
94
|
+
- lib
|
95
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
96
|
+
requirements:
|
97
|
+
- - ">="
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: '0'
|
100
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
101
|
+
requirements:
|
102
|
+
- - ">="
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: '0'
|
105
|
+
requirements: []
|
106
|
+
rubyforge_project:
|
107
|
+
rubygems_version: 2.2.2
|
108
|
+
signing_key:
|
109
|
+
specification_version: 4
|
110
|
+
summary: represent cents with safe arithmetic
|
111
|
+
test_files:
|
112
|
+
- spec/safe_money_spec.rb
|
113
|
+
- spec/spec_helper.rb
|