percentable 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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a86a351aaeedff408bbab5f914b294f8a898f4a0
4
+ data.tar.gz: 99d9e1bb82f6ff9e5f9242518240d113f5c9f31f
5
+ SHA512:
6
+ metadata.gz: 304b7c8663f0b5a6764d0e9b6739765d054c1a768a9247b20fa65d1e108e66405e9338f26f74213ac2eb39c03d42e4a7664f9d700cb60eca6175ee2833f9356d
7
+ data.tar.gz: b8323fc3c48aa7b7a1e448bea8694bbc23b3bea7a9c2fb206e4b52121b6aad1b2bba554a9c441dfc93291b10512f908ecad1649447e433d9eb28765d3c47ab8e
data/.gitignore ADDED
@@ -0,0 +1,24 @@
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
23
+ .ruby-version
24
+ .ruby-gemset
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format documentation
data/.travis.yml ADDED
@@ -0,0 +1,6 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 2.0.0
5
+ - 2.1
6
+ - ruby-head
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in percentable.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Eric Roberts
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,114 @@
1
+ # Percentable
2
+
3
+ Small gem to make working with percents easier.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'percentable'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install percentable
18
+
19
+ ## Usage
20
+
21
+ ### So how do I use this thing?
22
+
23
+ Well, you can use this a couple of ways.
24
+
25
+ ``` ruby
26
+ percent = Percent.new(50)
27
+ percent.value #=> 50.0
28
+ percent.to_s #=> '50%'
29
+ percent.to_f #=> 0.5
30
+ percent == 50 #=> false
31
+ percent == 0.5 #=> true
32
+ ```
33
+
34
+ That's the basics of the object itself. You probably want to know about how it works with other percents though, right?
35
+
36
+ ``` ruby
37
+ percent = Percent.new(10)
38
+ percent + percent #=> Percent.new(20)
39
+ percent - percent #=> Percent.new(0)
40
+ percent * percent #=> Percent.new(100)
41
+ percent / percent #=> Percent.new(1)
42
+ ```
43
+
44
+ And even more importantly, how it works with other Numeric objects:
45
+
46
+ ``` ruby
47
+ percent = Percent.new(50)
48
+ percent + 10 #=> Percent.new(60)
49
+ percent - 10 #=> Percent.new(40)
50
+ percent * 10 #=> Percent.new(500)
51
+ percent / 10 #=> Percent.new(5)
52
+ ```
53
+
54
+ Repeat steps above for Floats, BigDecimals, etc. It should all work.
55
+
56
+ ### Can I turn other Numerics into Percents?
57
+
58
+ Yes, yes you can.
59
+
60
+ ``` ruby
61
+ 10.to_percent #=> Percent.new(10)
62
+ ```
63
+
64
+ ### How do I use this with Rails?
65
+
66
+ Well let's say you have a User model, and on that user model you have a health attribute. You want to set that to a number that represents the percent. Just use the extend Percentable::Percentize method, and then use the percentize method to make sure you are returned percent objects always. Example below:
67
+
68
+ ``` ruby
69
+ class User < ActiveRecord::Base
70
+ extend Percentable::Percentize
71
+
72
+ percentize :health
73
+ end
74
+
75
+ user = User.new(health: 100)
76
+ user.health #=> Percent.new(100)
77
+ ```
78
+
79
+ ### What if I don't use Rails but want to use percentize?
80
+
81
+ That works too, there's nothing Rails specific about `Percentable::Percentize`. Example below:
82
+
83
+ ``` ruby
84
+ class OriginalClass
85
+ def returns_a_percent
86
+ 10
87
+ end
88
+ end
89
+
90
+ class PercentizedClass
91
+ extend Percentable::Percentize
92
+
93
+ percentize :returns_a_percent
94
+ end
95
+
96
+ percentize_object = PercentizedClass.new
97
+ percentize_object.returns_a_percent #=> Percent.new(10)
98
+ ```
99
+
100
+ ### OK, but why would I want this?
101
+
102
+ 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
+
104
+ ### Is that it?
105
+
106
+ Hey, I only wrote this in a night. Happy to except contributions from others!
107
+
108
+ ## Contributing
109
+
110
+ 1. Fork it ( https://github.com/ericroberts/percentable/fork )
111
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
112
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
113
+ 4. Push to the branch (`git push origin my-new-feature`)
114
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,4 @@
1
+ require_relative 'percentable/version'
2
+ require_relative 'percentable/numeric'
3
+ require_relative 'percentable/percent'
4
+ require_relative 'percentable/percentize'
@@ -0,0 +1,11 @@
1
+ module Percentable
2
+ module Numeric
3
+ def to_percent
4
+ Percentable::Percent.new(self)
5
+ end
6
+ end
7
+ end
8
+
9
+ class Numeric
10
+ include Percentable::Numeric
11
+ end
@@ -0,0 +1,82 @@
1
+ module Percentable
2
+ class Percent < ::Numeric
3
+ def initialize(value)
4
+ @value = value.to_f
5
+ end
6
+
7
+ def value
8
+ @value ||= 0.to_f
9
+ end
10
+
11
+ def to_s
12
+ '%g%%' % value
13
+ end
14
+
15
+ def to_f
16
+ value/100
17
+ end
18
+
19
+ def to_i
20
+ value.to_i
21
+ end
22
+
23
+ def coerce other
24
+ case other
25
+ when Numeric
26
+ [to_f, other]
27
+ else
28
+ fail TypeError, "#{self.class} can't be coerced into #{other.class}"
29
+ end
30
+ end
31
+
32
+ def == other
33
+ (other.class == self.class && other.value == self.value) || other == self.to_f
34
+ end
35
+
36
+ def eql? other
37
+ self.send(:==, other)
38
+ end
39
+
40
+ def <=> other
41
+ to_f <=> other.to_f
42
+ end
43
+
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
+ def * other
54
+ case other
55
+ when Percent
56
+ self.class.new(other.value * value)
57
+ when Numeric
58
+ self.class.new(other * value)
59
+ end
60
+ end
61
+
62
+ def - other
63
+ case other
64
+ when Percent
65
+ self.class.new(value - other.value)
66
+ when Numeric
67
+ self.class.new(value - other)
68
+ end
69
+ end
70
+
71
+ def / other
72
+ case other
73
+ when Percent
74
+ self.class.new(value / other.value)
75
+ when Numeric
76
+ self.class.new(value / other)
77
+ end
78
+ end
79
+ end
80
+ end
81
+
82
+ Percent = Percentable::Percent
@@ -0,0 +1,9 @@
1
+ module Percentable
2
+ module Percentize
3
+ def percentize field
4
+ define_method(field) do |args=[]|
5
+ Percent.new(super(*args))
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,3 @@
1
+ module Percentable
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'percentable/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "percentable"
8
+ spec.version = Percentable::VERSION
9
+ spec.authors = ["Eric Roberts"]
10
+ spec.email = ["ericroberts@gmail.com"]
11
+ spec.summary = "Small gem to make working with percents easier."
12
+ spec.description = "Small gem to make working with percents easier. Includes methods to make selected rails attributes return percents."
13
+ spec.homepage = "https://github.com/ericroberts/percentable"
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", "~> 3.0"
24
+ end
@@ -0,0 +1,20 @@
1
+ require 'percentable/numeric'
2
+ require 'bigdecimal'
3
+
4
+ describe Numeric do
5
+ [1, 1.0, BigDecimal.new(1, 10)].each do |numeric|
6
+ subject { numeric }
7
+
8
+ context numeric.class.name do
9
+ describe '#to_percent' do
10
+ it 'should respond to it' do
11
+ expect(subject).to respond_to :to_percent
12
+ end
13
+
14
+ it 'should return the value as percent' do
15
+ expect(subject.to_percent).to eq Percentable::Percent.new(subject)
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,235 @@
1
+ require 'percentable/percent'
2
+
3
+ describe Percentable::Percent do
4
+ subject { Percentable::Percent.new(value) }
5
+ let(:value) { nil }
6
+
7
+ describe '#initialize' do
8
+ context 'with value represented as string' do
9
+ let(:value) { '50%' }
10
+
11
+ it 'should have a value of 50' do
12
+ expect(subject.value).to eq 50
13
+ end
14
+ end
15
+ end
16
+
17
+ describe '#to_s' do
18
+ context 'with value of 50' do
19
+ let(:value) { 50 }
20
+
21
+ it 'should return 50%' do
22
+ expect(subject.to_s).to eq '50%'
23
+ end
24
+ end
25
+
26
+ context 'with value of 0.025' do
27
+ let(:value) { 0.025 }
28
+
29
+ it 'should return 0.025%' do
30
+ expect(subject.to_s).to eq '0.025%'
31
+ end
32
+ end
33
+ end
34
+
35
+ describe '#to_f' do
36
+ context 'with value of 50' do
37
+ let(:value) { 50 }
38
+
39
+ it 'should return 0.5' do
40
+ expect(subject.to_f).to eq 0.5
41
+ end
42
+ end
43
+
44
+ context 'with value of 10.5' do
45
+ let(:value) { 10.5 }
46
+
47
+ it 'should return 0.105' do
48
+ expect(subject.to_f).to eq 0.105
49
+ end
50
+ end
51
+ end
52
+
53
+ describe '#zero?' do
54
+ context 'with value of 0' do
55
+ let(:value) { 0 }
56
+
57
+ it 'should return true' do
58
+ expect(subject.zero?).to be true
59
+ end
60
+ end
61
+
62
+ context 'with any other value' do
63
+ let(:value) { 10 }
64
+
65
+ it 'should return false' do
66
+ expect(subject.zero?).to be false
67
+ end
68
+ end
69
+ end
70
+
71
+ shared_examples 'it is equal' do |equal_method|
72
+ it 'should consider itself equal to other percents with the same value' do
73
+ percent1 = subject.class.new(50)
74
+ percent2 = subject.class.new(50)
75
+
76
+ expect(percent1.send(equal_method, percent2)).to be true
77
+ end
78
+
79
+ it 'should consider itself equal to a float matching the float value' do
80
+ float = 0.015
81
+ percent = subject.class.new(float*100)
82
+
83
+ expect(percent.send(equal_method, float)).to be true
84
+ end
85
+
86
+ it 'should consider itself equal to an integer matching the float value' do
87
+ integer = 2
88
+ percent = subject.class.new(integer*100)
89
+
90
+ expect(percent.send(equal_method, integer)).to be true
91
+ end
92
+ end
93
+
94
+ describe '#==' do
95
+ it_should_behave_like 'it is equal', :==
96
+ end
97
+
98
+ describe '#eql?' do
99
+ it_should_behave_like 'it is equal', :eql?
100
+ end
101
+
102
+ describe '#+' do
103
+ context 'adding percents' do
104
+ let(:percent1) { subject.class.new(50) }
105
+ let(:percent2) { subject.class.new(50) }
106
+
107
+ it 'should return the sum of both percents' do
108
+ expect(percent1 + percent2).to eq subject.class.new(100)
109
+ end
110
+ end
111
+
112
+ context 'adding integers' do
113
+ let(:integer) { 1 }
114
+ let(:percent) { subject.class.new(50) }
115
+
116
+ it 'should return the sum of percent and integer' do
117
+ expect(percent + integer).to eq subject.class.new(51)
118
+ end
119
+ end
120
+
121
+ context 'adding floats' do
122
+ let(:float) { 1.0 }
123
+ let(:percent) { subject.class.new(25) }
124
+
125
+ it 'should return the sum of percent and float' do
126
+ expect(percent + float).to eq subject.class.new(26)
127
+ end
128
+ end
129
+ end
130
+
131
+ describe '#-' do
132
+ context 'subtracting percents' do
133
+ let(:percent1) { subject.class.new(50) }
134
+ let(:percent2) { subject.class.new(10) }
135
+
136
+ it 'should return the result after subtraction' do
137
+ expect(percent1 - percent2).to eq subject.class.new(40)
138
+ end
139
+ end
140
+
141
+ context 'subtracting other numerics' do
142
+ let(:value) { 20 }
143
+
144
+ [1, 1.0, BigDecimal.new(1.0, 10)].each do |numeric|
145
+ context numeric.class.name do
146
+ it "should return the result after subtracting the #{numeric.class.name} from the percent" do
147
+ expect(subject - numeric).to eq subject.class.new(19)
148
+ end
149
+ end
150
+ end
151
+ end
152
+ end
153
+
154
+ describe '#*' do
155
+ context 'multiplying percents' do
156
+ let(:percent1) { subject.class.new(9) }
157
+ let(:percent2) { subject.class.new(9) }
158
+
159
+ it 'should return the result of multiplying the percents' do
160
+ expect(percent1 * percent2).to eq subject.class.new(81)
161
+ end
162
+ end
163
+
164
+ context 'multiplying other numerics' do
165
+ let(:numeric) { 2 }
166
+ let(:percent) { subject.class.new(20) }
167
+
168
+ it 'should return the result of multipling the percent by the number' do
169
+ expect(percent * numeric).to eq subject.class.new(40)
170
+ end
171
+ end
172
+ end
173
+
174
+ describe '#/' do
175
+ context 'dividing percents' do
176
+ let(:percent1) { subject.class.new(50) }
177
+ let(:percent2) { subject.class.new(10) }
178
+
179
+ it 'should return the result after division' do
180
+ expect(percent1 / percent2).to eq subject.class.new(5)
181
+ end
182
+ end
183
+
184
+ context 'dividing other numerics' do
185
+ let(:value) { 20 }
186
+
187
+ [5, 5.0, BigDecimal.new(5.0, 10)].each do |numeric|
188
+ context numeric.class.name do
189
+ it "should return the result after subtracting the #{numeric.class.name} from the percent" do
190
+ expect(subject / numeric).to eq subject.class.new(4)
191
+ end
192
+ end
193
+ end
194
+ end
195
+ end
196
+
197
+ describe 'comparable' do
198
+ it 'is comparable' do
199
+ expect(Comparable === subject).to be true
200
+ end
201
+
202
+ context 'compared to other percents' do
203
+ let(:larger_percent) { subject.class.new(100) }
204
+ let(:smaller_percent) { subject.class.new(50) }
205
+
206
+ it 'should be able to tell when things are larger' do
207
+ expect(larger_percent > smaller_percent).to be true
208
+ end
209
+
210
+ it 'should be able to tell when things are smaller' do
211
+ expect(smaller_percent < larger_percent).to be true
212
+ end
213
+ end
214
+
215
+ context 'compared to integers' do
216
+ context 'when integer is larger' do
217
+ let(:integer) { 30 }
218
+ let(:percent) { subject.class.new(10) }
219
+
220
+ it 'should say the percent is smaller' do
221
+ expect(percent < integer).to be true
222
+ end
223
+ end
224
+
225
+ context 'when integer is smaller' do
226
+ let(:integer) { 1 }
227
+ let(:percent) { subject.class.new(101) }
228
+
229
+ it 'should say the percent is larger' do
230
+ expect(percent > integer).to be true
231
+ end
232
+ end
233
+ end
234
+ end
235
+ end
@@ -0,0 +1,22 @@
1
+ require 'percentable/percent'
2
+ require 'percentable/percentize'
3
+
4
+ class TestClass
5
+ def returns_a_percent
6
+ 10
7
+ end
8
+ end
9
+
10
+ class Subject < TestClass
11
+ extend Percentable::Percentize
12
+
13
+ percentize :returns_a_percent
14
+ end
15
+
16
+ describe Percentable::Percentize do
17
+ subject { Subject.new }
18
+
19
+ it 'should return a percent with value of TestClass' do
20
+ expect(subject.returns_a_percent).to eq Percentable::Percent.new(10)
21
+ end
22
+ end
metadata ADDED
@@ -0,0 +1,106 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: percentable
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Eric Roberts
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-07-30 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: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ description: Small gem to make working with percents easier. Includes methods to make
56
+ selected rails attributes return percents.
57
+ email:
58
+ - ericroberts@gmail.com
59
+ executables: []
60
+ extensions: []
61
+ extra_rdoc_files: []
62
+ files:
63
+ - ".gitignore"
64
+ - ".rspec"
65
+ - ".travis.yml"
66
+ - Gemfile
67
+ - LICENSE.txt
68
+ - README.md
69
+ - Rakefile
70
+ - lib/percentable.rb
71
+ - lib/percentable/numeric.rb
72
+ - lib/percentable/percent.rb
73
+ - lib/percentable/percentize.rb
74
+ - lib/percentable/version.rb
75
+ - percentable.gemspec
76
+ - spec/lib/percentable/numeric_spec.rb
77
+ - spec/lib/percentable/percent_spec.rb
78
+ - spec/lib/percentable/percentize_spec.rb
79
+ homepage: https://github.com/ericroberts/percentable
80
+ licenses:
81
+ - MIT
82
+ metadata: {}
83
+ post_install_message:
84
+ rdoc_options: []
85
+ require_paths:
86
+ - lib
87
+ required_ruby_version: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - ">="
90
+ - !ruby/object:Gem::Version
91
+ version: '0'
92
+ required_rubygems_version: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ requirements: []
98
+ rubyforge_project:
99
+ rubygems_version: 2.2.2
100
+ signing_key:
101
+ specification_version: 4
102
+ summary: Small gem to make working with percents easier.
103
+ test_files:
104
+ - spec/lib/percentable/numeric_spec.rb
105
+ - spec/lib/percentable/percent_spec.rb
106
+ - spec/lib/percentable/percentize_spec.rb