percentable 0.0.1 → 0.1.0
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 +4 -4
- data/README.md +46 -3
- data/lib/percentable/percent.rb +25 -23
- data/lib/percentable/percentize.rb +7 -3
- data/lib/percentable/version.rb +1 -1
- data/percentable.gemspec +1 -0
- data/spec/lib/percentable/numeric_spec.rb +2 -1
- data/spec/lib/percentable/percent_spec.rb +68 -4
- data/spec/lib/percentable/percentize_spec.rb +60 -4
- data/spec/spec_helper.rb +2 -0
- metadata +17 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0fbd045effde2a7949bd1f83593a92c8d320abf1
|
4
|
+
data.tar.gz: 0f629c3a9f5afb113e17a62265d47320cb78ae4d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 21674843db344a6ae56bab761521e302194d7350c891ccc0ee15d567f36ab1902e4590fb6c86878d12130550aaade1f602f9c0883ca35fe66160c7a610bd56eb
|
7
|
+
data.tar.gz: a9709db91180a7edb2498cbaee2a23d4999fdb0087d905ce9f236f2e1b6d6708f9765892ec8953f5b712d1013ea1add97a37be9afe9a9b48c4064542eb8de287
|
data/README.md
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
[](http://badge.fury.io/rb/percentable)
|
2
|
+
[](https://travis-ci.org/ericroberts/percentable)
|
3
|
+
[](https://codeclimate.com/github/ericroberts/percentable)
|
4
|
+
[](https://coveralls.io/r/ericroberts/percentable?branch=master)
|
5
|
+
|
1
6
|
# Percentable
|
2
7
|
|
3
8
|
Small gem to make working with percents easier.
|
@@ -37,7 +42,7 @@ That's the basics of the object itself. You probably want to know about how it w
|
|
37
42
|
percent = Percent.new(10)
|
38
43
|
percent + percent #=> Percent.new(20)
|
39
44
|
percent - percent #=> Percent.new(0)
|
40
|
-
percent * percent #=> Percent.new(
|
45
|
+
percent * percent #=> Percent.new(1)
|
41
46
|
percent / percent #=> Percent.new(1)
|
42
47
|
```
|
43
48
|
|
@@ -51,6 +56,16 @@ percent * 10 #=> Percent.new(500)
|
|
51
56
|
percent / 10 #=> Percent.new(5)
|
52
57
|
```
|
53
58
|
|
59
|
+
And with the number on the other side...
|
60
|
+
|
61
|
+
``` ruby
|
62
|
+
percent = Percent.new(50)
|
63
|
+
10 + percent #=> 15
|
64
|
+
10 - percent #=> 5
|
65
|
+
10 * percent #=> 5
|
66
|
+
10 / percent #=> 20
|
67
|
+
```
|
68
|
+
|
54
69
|
Repeat steps above for Floats, BigDecimals, etc. It should all work.
|
55
70
|
|
56
71
|
### Can I turn other Numerics into Percents?
|
@@ -87,7 +102,7 @@ class OriginalClass
|
|
87
102
|
end
|
88
103
|
end
|
89
104
|
|
90
|
-
class PercentizedClass
|
105
|
+
class PercentizedClass < OriginalClass
|
91
106
|
extend Percentable::Percentize
|
92
107
|
|
93
108
|
percentize :returns_a_percent
|
@@ -97,13 +112,41 @@ percentize_object = PercentizedClass.new
|
|
97
112
|
percentize_object.returns_a_percent #=> Percent.new(10)
|
98
113
|
```
|
99
114
|
|
115
|
+
You can do percentize multiple methods at a time:
|
116
|
+
|
117
|
+
``` ruby
|
118
|
+
class PercentizedClass < OriginalClass
|
119
|
+
extend Percentable::Percentize
|
120
|
+
|
121
|
+
percentize :method1, :method2
|
122
|
+
end
|
123
|
+
```
|
124
|
+
|
125
|
+
You can define defaults for when the percentized method returns nil:
|
126
|
+
|
127
|
+
``` ruby
|
128
|
+
class PercentizedClass < OriginalClass
|
129
|
+
extend Percentable::Percentize
|
130
|
+
|
131
|
+
percentize :method1, :method2, default: 20
|
132
|
+
end
|
133
|
+
|
134
|
+
# assuming method1 on OriginalClass returns nil
|
135
|
+
percentize_object = PercentizedClass.new
|
136
|
+
percentize_object.method1 #=> Percent.new(20)
|
137
|
+
```
|
138
|
+
|
100
139
|
### OK, but why would I want this?
|
101
140
|
|
102
141
|
I don't know, all I can tell you is that I found it useful. Instead of writing methods to translate from 0.1 to 10% all over the place, I now have a class to represent everything to do with percents.
|
103
142
|
|
104
143
|
### Is that it?
|
105
144
|
|
106
|
-
Hey, I only wrote this in a night. Happy to
|
145
|
+
Hey, I only wrote this in a night. Happy to accept contributions from others!
|
146
|
+
|
147
|
+
### Your math is totally wrong and you are an idiot.
|
148
|
+
|
149
|
+
That's not a question. I've had a fair bit of discussion with the fine folks at [Boltmade](http://www.boltmade.com) about how it should behave, and the examples you see above are what we settled on. If you would like to propose a change, the best way would be to edit the README to show examples for how you would like it to act. You can also submit a pull request that changes the code, but if you submit the README first we can have a discussion about whether or not it makes sense. I'm not totally sold on the current implementation and would be happy to discuss changes.
|
107
150
|
|
108
151
|
## Contributing
|
109
152
|
|
data/lib/percentable/percent.rb
CHANGED
@@ -21,9 +21,18 @@ module Percentable
|
|
21
21
|
end
|
22
22
|
|
23
23
|
def coerce other
|
24
|
+
method = caller[0].match("`(.+)'")[1].to_sym
|
25
|
+
|
24
26
|
case other
|
25
27
|
when Numeric
|
26
|
-
|
28
|
+
case method
|
29
|
+
when :+
|
30
|
+
[to_f * other, other]
|
31
|
+
when :-
|
32
|
+
[other, to_f * other]
|
33
|
+
else
|
34
|
+
[other, to_f]
|
35
|
+
end
|
27
36
|
else
|
28
37
|
fail TypeError, "#{self.class} can't be coerced into #{other.class}"
|
29
38
|
end
|
@@ -41,39 +50,32 @@ module Percentable
|
|
41
50
|
to_f <=> other.to_f
|
42
51
|
end
|
43
52
|
|
44
|
-
def + other
|
45
|
-
case other
|
46
|
-
when Percent
|
47
|
-
self.class.new(other.value + value)
|
48
|
-
when Numeric
|
49
|
-
self.class.new(other + value)
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
53
|
def * other
|
54
54
|
case other
|
55
55
|
when Percent
|
56
|
-
self.class.new(
|
56
|
+
self.class.new(to_f * other.value)
|
57
57
|
when Numeric
|
58
|
-
self.class.new(
|
58
|
+
self.class.new(value * other)
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
62
|
+
[:+, :-, :/].each do |operator|
|
63
|
+
define_method operator do |other|
|
64
|
+
case other
|
65
|
+
when Percent
|
66
|
+
self.class.new(value.public_send(operator, other.value))
|
67
|
+
when Numeric
|
68
|
+
self.class.new(value.public_send(operator, other))
|
69
|
+
end
|
68
70
|
end
|
69
71
|
end
|
70
72
|
|
71
|
-
def
|
72
|
-
case
|
73
|
-
when Percent
|
74
|
-
self.class.new(value / other.value)
|
73
|
+
def self.from_numeric(numeric)
|
74
|
+
case numeric
|
75
75
|
when Numeric
|
76
|
-
|
76
|
+
Percent.new(numeric*100)
|
77
|
+
else
|
78
|
+
fail TypeError, 'must inherit from Numeric'
|
77
79
|
end
|
78
80
|
end
|
79
81
|
end
|
@@ -1,8 +1,12 @@
|
|
1
1
|
module Percentable
|
2
2
|
module Percentize
|
3
|
-
def percentize
|
4
|
-
|
5
|
-
|
3
|
+
def percentize *args
|
4
|
+
options = args.pop if args.last.is_a? Hash
|
5
|
+
|
6
|
+
args.each do |method_name|
|
7
|
+
define_method(method_name) do |args=[]|
|
8
|
+
Percent.new(super(*args) || options[:default])
|
9
|
+
end
|
6
10
|
end
|
7
11
|
end
|
8
12
|
end
|
data/lib/percentable/version.rb
CHANGED
data/percentable.gemspec
CHANGED
@@ -1,4 +1,6 @@
|
|
1
|
-
require '
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'bigdecimal'
|
3
|
+
require 'percentable'
|
2
4
|
|
3
5
|
describe Percentable::Percent do
|
4
6
|
subject { Percentable::Percent.new(value) }
|
@@ -68,6 +70,48 @@ describe Percentable::Percent do
|
|
68
70
|
end
|
69
71
|
end
|
70
72
|
|
73
|
+
describe '#to_i' do
|
74
|
+
[0.1, 0.5, 1, 1.8, 2, 2.2].each do |value|
|
75
|
+
context "value of #{value}" do
|
76
|
+
let(:value) { value }
|
77
|
+
|
78
|
+
it "should return #{value.floor} for #{value}" do
|
79
|
+
expect(subject.to_i).to eq value.floor
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe '#coerce' do
|
86
|
+
context 'when other is non numeric' do
|
87
|
+
let(:other) { 'string' }
|
88
|
+
|
89
|
+
it 'should raise a TypeError' do
|
90
|
+
expect { subject.coerce(other) }.to raise_error TypeError
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
context 'math' do
|
95
|
+
let(:value) { 50 }
|
96
|
+
|
97
|
+
it 'should add the value of percent*number' do
|
98
|
+
expect(10 + subject).to eq 15
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'should subtract the value of percent*number' do
|
102
|
+
expect(10 - subject).to eq 5
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'should multiply by the float value of the percent' do
|
106
|
+
expect(10 * subject).to eq 5
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'should divide by the float value of the percent' do
|
110
|
+
expect(10 / subject).to eq 20
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
71
115
|
shared_examples 'it is equal' do |equal_method|
|
72
116
|
it 'should consider itself equal to other percents with the same value' do
|
73
117
|
percent1 = subject.class.new(50)
|
@@ -153,11 +197,11 @@ describe Percentable::Percent do
|
|
153
197
|
|
154
198
|
describe '#*' do
|
155
199
|
context 'multiplying percents' do
|
156
|
-
let(:percent1) { subject.class.new(
|
157
|
-
let(:percent2) { subject.class.new(
|
200
|
+
let(:percent1) { subject.class.new(10) }
|
201
|
+
let(:percent2) { subject.class.new(10) }
|
158
202
|
|
159
203
|
it 'should return the result of multiplying the percents' do
|
160
|
-
expect(percent1 * percent2).to eq subject.class.new(
|
204
|
+
expect(percent1 * percent2).to eq subject.class.new(1)
|
161
205
|
end
|
162
206
|
end
|
163
207
|
|
@@ -232,4 +276,24 @@ describe Percentable::Percent do
|
|
232
276
|
end
|
233
277
|
end
|
234
278
|
end
|
279
|
+
|
280
|
+
describe '.from_numeric' do
|
281
|
+
let(:n) { 0.5 }
|
282
|
+
|
283
|
+
it 'should multiply the input by 100 and return a percent for that value' do
|
284
|
+
expect(subject.class.from_numeric(n)).to eq Percent.new(50)
|
285
|
+
end
|
286
|
+
|
287
|
+
it 'should be considered equal to the numeric it was passed' do
|
288
|
+
expect(subject.class.from_numeric(n)).to eq n
|
289
|
+
end
|
290
|
+
|
291
|
+
context 'when passed a string' do
|
292
|
+
let(:n) { 'string' }
|
293
|
+
|
294
|
+
it 'should raise an argument error' do
|
295
|
+
expect { subject.class.from_numeric(n) }.to raise_error TypeError
|
296
|
+
end
|
297
|
+
end
|
298
|
+
end
|
235
299
|
end
|
@@ -1,22 +1,78 @@
|
|
1
|
-
require '
|
2
|
-
require 'percentable
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'percentable'
|
3
3
|
|
4
4
|
class TestClass
|
5
5
|
def returns_a_percent
|
6
6
|
10
|
7
7
|
end
|
8
|
+
|
9
|
+
def first_percent_method
|
10
|
+
15
|
11
|
+
end
|
12
|
+
|
13
|
+
def second_percent_method
|
14
|
+
20
|
15
|
+
end
|
16
|
+
|
17
|
+
def default_percent_method
|
18
|
+
end
|
19
|
+
|
20
|
+
def default_filled_percent_method
|
21
|
+
100
|
22
|
+
end
|
23
|
+
|
24
|
+
def default_percent_method1
|
25
|
+
end
|
26
|
+
|
27
|
+
def default_percent_method2
|
28
|
+
end
|
29
|
+
|
30
|
+
def default_percent_method3
|
31
|
+
20.5
|
32
|
+
end
|
8
33
|
end
|
9
34
|
|
10
35
|
class Subject < TestClass
|
11
36
|
extend Percentable::Percentize
|
12
37
|
|
13
38
|
percentize :returns_a_percent
|
39
|
+
percentize :first_percent_method, :second_percent_method
|
40
|
+
percentize :default_percent_method, default: 10
|
41
|
+
percentize :default_filled_percent_method, default: 20
|
42
|
+
percentize :default_percent_method1, :default_percent_method2, :default_percent_method3, default: 20
|
14
43
|
end
|
15
44
|
|
16
45
|
describe Percentable::Percentize do
|
17
46
|
subject { Subject.new }
|
47
|
+
let(:ancestor) { TestClass.new }
|
48
|
+
|
49
|
+
[:returns_a_percent, :first_percent_method, :second_percent_method].each do |method|
|
50
|
+
it 'should return a percent with value of TestClass' do
|
51
|
+
expect(subject.public_send(method)).to eq Percentable::Percent.new(ancestor.send(method))
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
context 'when passed a default value' do
|
56
|
+
it 'should return the default value when return value is nil' do
|
57
|
+
expect(subject.default_percent_method).to eq Percentable::Percent.new(10)
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'should not return the default if the value is defined' do
|
61
|
+
expect(subject.default_filled_percent_method).to eq Percentable::Percent.new(100)
|
62
|
+
end
|
63
|
+
|
64
|
+
context 'with multiple methods' do
|
65
|
+
it 'should return the default value when return value is nil' do
|
66
|
+
expect(subject.default_percent_method1).to eq Percentable::Percent.new(20)
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'should return the default value when return value is nil' do
|
70
|
+
expect(subject.default_percent_method2).to eq Percentable::Percent.new(20)
|
71
|
+
end
|
18
72
|
|
19
|
-
|
20
|
-
|
73
|
+
it 'should not return the default when the value is set' do
|
74
|
+
expect(subject.default_percent_method3).to eq Percentable::Percent.new(20.5)
|
75
|
+
end
|
76
|
+
end
|
21
77
|
end
|
22
78
|
end
|
data/spec/spec_helper.rb
ADDED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: percentable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Eric Roberts
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '3.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: coveralls
|
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'
|
55
69
|
description: Small gem to make working with percents easier. Includes methods to make
|
56
70
|
selected rails attributes return percents.
|
57
71
|
email:
|
@@ -76,6 +90,7 @@ files:
|
|
76
90
|
- spec/lib/percentable/numeric_spec.rb
|
77
91
|
- spec/lib/percentable/percent_spec.rb
|
78
92
|
- spec/lib/percentable/percentize_spec.rb
|
93
|
+
- spec/spec_helper.rb
|
79
94
|
homepage: https://github.com/ericroberts/percentable
|
80
95
|
licenses:
|
81
96
|
- MIT
|
@@ -104,3 +119,4 @@ test_files:
|
|
104
119
|
- spec/lib/percentable/numeric_spec.rb
|
105
120
|
- spec/lib/percentable/percent_spec.rb
|
106
121
|
- spec/lib/percentable/percentize_spec.rb
|
122
|
+
- spec/spec_helper.rb
|