percent 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.
@@ -0,0 +1,350 @@
1
+ require 'spec_helper'
2
+
3
+ if defined? ActiveRecord
4
+ describe Percent::ActiveRecord::Percentizable do
5
+ describe '#percentize' do
6
+ shared_examples_for 'Survey methods' do
7
+ it { is_expected.to respond_to(:percent_complete) }
8
+ it { is_expected.to respond_to(:percent_complete=) }
9
+ it { is_expected.to respond_to(:non_fraction_ending_percent) }
10
+ it { is_expected.to respond_to(:non_fraction_ending_percent=) }
11
+ it { is_expected.to respond_to(:percent) }
12
+ it { is_expected.to respond_to(:percent=) }
13
+ it { is_expected.to respond_to(:optional) }
14
+ it { is_expected.to respond_to(:optional=) }
15
+ it { is_expected.to respond_to(:sans_validation) }
16
+ it { is_expected.to respond_to(:sans_validation=) }
17
+ it { is_expected.to respond_to(:sans_frac_validate) }
18
+ it { is_expected.to respond_to(:sans_frac_validate=) }
19
+ it { is_expected.to respond_to(:in_a_weird_range) }
20
+ it { is_expected.to respond_to(:in_a_weird_range=) }
21
+ it { is_expected.to respond_to(:in_fraction_range) }
22
+ it { is_expected.to respond_to(:in_fraction_range=) }
23
+ it { is_expected.to respond_to(:first_percent) }
24
+ it { is_expected.to respond_to(:first_percent=) }
25
+ it { is_expected.to respond_to(:second_percent) }
26
+ it { is_expected.to respond_to(:second_percent=) }
27
+ end
28
+
29
+ let (:subject) do
30
+ Survey.create percent_complete_fraction: 0.1,
31
+ non_fraction_ending: 0.2,
32
+ as_option_percent_fraction: 0.3,
33
+ optional_fraction: 0.4,
34
+ sans_validation_fraction: 0.5,
35
+ sans_frac_validate_fraction: 0.6,
36
+ in_a_weird_range_fraction: 0.7,
37
+ in_fraction_range_fraction: 0.8,
38
+ first_percent_fraction: 0.9,
39
+ second_percent_fraction: 1.0
40
+ end
41
+
42
+ describe 'methods' do
43
+ it_should_behave_like 'Survey methods'
44
+ end
45
+
46
+ context 'inherited class instance' do
47
+ let (:subject) { InheritedPercentizeSurvey.new }
48
+ it_should_behave_like 'Survey methods'
49
+ end
50
+
51
+ describe 'percentized attribute getter' do
52
+ it 'attaches a Percentage object to model field' do
53
+ expect(subject.percent_complete).to be_an_instance_of Percentage
54
+ expect(subject.non_fraction_ending_percent).to be_an_instance_of Percentage
55
+ expect(subject.percent).to be_an_instance_of Percentage
56
+ expect(subject.optional).to be_an_instance_of Percentage
57
+ expect(subject.sans_validation).to be_an_instance_of Percentage
58
+ expect(subject.sans_frac_validate).to be_an_instance_of Percentage
59
+ expect(subject.in_a_weird_range).to be_an_instance_of Percentage
60
+ expect(subject.in_fraction_range).to be_an_instance_of Percentage
61
+ end
62
+
63
+ it 'attaches a Percentage object to multiple model fields' do
64
+ expect(subject.first_percent).to be_an_instance_of Percentage
65
+ expect(subject.second_percent).to be_an_instance_of Percentage
66
+ end
67
+
68
+ it 'returns the expected percentage amount as a Percentage object' do
69
+ expect(subject.percent_complete).to eql Percentage.new(10)
70
+ expect(subject.non_fraction_ending_percent).to eql Percentage.new(20)
71
+ expect(subject.percent).to eql Percentage.new(30)
72
+ expect(subject.optional).to eql Percentage.new(40)
73
+ expect(subject.sans_validation).to eql Percentage.new(50)
74
+ expect(subject.sans_frac_validate).to eql Percentage.new(60)
75
+ expect(subject.in_a_weird_range).to eql Percentage.new(70)
76
+ expect(subject.in_fraction_range).to eql Percentage.new(80)
77
+ expect(subject.first_percent).to eql Percentage.new(90)
78
+ expect(subject.second_percent).to eql Percentage.new(100)
79
+ end
80
+ end
81
+
82
+ describe 'percentized attribute setter' do
83
+ context 'assign value to percentized attribute' do
84
+ it 'assigns the correct value from a Percentage object' do
85
+ subject.percent_complete = Percentage.new(0)
86
+ expect(subject.save).to be_truthy
87
+ expect(subject.percent_complete_fraction).to eql BigDecimal.new(0)
88
+ end
89
+
90
+ it 'assigns the correct value from an integer' do
91
+ subject.percent_complete = 10
92
+ expect(subject.save).to be_truthy
93
+ expect(subject.percent_complete_fraction).to eql BigDecimal.new('0.1')
94
+ end
95
+
96
+ it 'assigns the correct value from a complex number' do
97
+ subject.percent_complete = Complex(20,0)
98
+ expect(subject.save).to be_truthy
99
+ expect(subject.percent_complete_fraction).to eql BigDecimal.new('0.2')
100
+ end
101
+
102
+ it 'assigns the correct value from a decimal' do
103
+ subject.percent_complete = BigDecimal.new(30)
104
+ expect(subject.save).to be_truthy
105
+ expect(subject.percent_complete_fraction).to eql BigDecimal.new('0.3')
106
+ end
107
+
108
+ it 'assigns the correct value from a float' do
109
+ subject.percent_complete = 40.0
110
+ expect(subject.save).to be_truthy
111
+ expect(subject.percent_complete_fraction).to eql BigDecimal.new('0.4')
112
+ end
113
+
114
+ it 'assigns the correct value from a rational number' do
115
+ subject.percent_complete = Rational(100,2)
116
+ expect(subject.save).to be_truthy
117
+ expect(subject.percent_complete_fraction).to eql BigDecimal.new('0.5')
118
+ end
119
+
120
+ it 'assigns the correct value from a string with value "60"' do
121
+ subject.percent_complete = '60'
122
+ expect(subject.save).to be_truthy
123
+ expect(subject.percent_complete_fraction).to eql BigDecimal.new('0.6')
124
+ end
125
+
126
+ it 'assigns the correct value from a string with value "70.0"' do
127
+ subject.percent_complete = '70.0'
128
+ expect(subject.save).to be_truthy
129
+ expect(subject.percent_complete_fraction).to eql BigDecimal.new('0.7')
130
+ end
131
+
132
+ it 'assigns the correct value from a string with value "0.8E2"' do
133
+ subject.percent_complete = '0.8E2'
134
+ expect(subject.save).to be_truthy
135
+ expect(subject.percent_complete_fraction).to eql BigDecimal.new('0.8')
136
+ end
137
+
138
+ it 'assigns the correct value from a string with value "810/9"' do
139
+ subject.percent_complete = '810/9'
140
+ expect(subject.save).to be_truthy
141
+ expect(subject.percent_complete_fraction).to eql BigDecimal.new('0.9')
142
+ end
143
+
144
+ it 'assigns the correct value from a string with value "100%"' do
145
+ subject.percent_complete = '100%'
146
+ expect(subject.save).to be_truthy
147
+ expect(subject.percent_complete_fraction).to eql BigDecimal.new(1)
148
+ end
149
+ end
150
+
151
+ context 'assign value to percentized attribute on create' do
152
+ it 'assigns the correct value from a Percentage object' do
153
+ subject = Survey.create percent_complete: 15.0,
154
+ non_fraction_ending_percent: 0,
155
+ percent: 0,
156
+ sans_frac_validate: 0
157
+ expect(subject.valid?).to be_truthy
158
+ expect(subject.percent_complete_fraction).to eql BigDecimal.new('0.15')
159
+ end
160
+
161
+ it 'assigns the correct value from a number' do
162
+ subject = Survey.create percent_complete: 35.0,
163
+ non_fraction_ending_percent: 0,
164
+ percent: 0,
165
+ sans_frac_validate: 0
166
+ expect(subject.valid?).to be_truthy
167
+ expect(subject.percent_complete_fraction).to eql BigDecimal.new('0.35')
168
+ end
169
+
170
+ it 'assigns the correct value from a string' do
171
+ subject = Survey.create percent_complete: '55',
172
+ non_fraction_ending_percent: 0,
173
+ percent: 0,
174
+ sans_frac_validate: 0
175
+ expect(subject.valid?).to be_truthy
176
+ expect(subject.percent_complete_fraction).to eql BigDecimal.new('0.55')
177
+ end
178
+ end
179
+
180
+ context 'assign value to percentized attribute on update' do
181
+ it 'assigns the correct value from a Percentage object' do
182
+ expect(subject.update_attributes percent_complete: Percentage.new(25)).to be_truthy
183
+ expect(subject.percent_complete_fraction).to eql BigDecimal.new('0.25')
184
+ end
185
+
186
+ it 'assigns the correct value from a number' do
187
+ expect(subject.update_attributes percent_complete: 45.0).to be_truthy
188
+ expect(subject.percent_complete_fraction).to eql BigDecimal.new('0.45')
189
+ end
190
+
191
+ it 'assigns the correct value from a string' do
192
+ expect(subject.update_attributes percent_complete: '65').to be_truthy
193
+ expect(subject.percent_complete_fraction).to eql BigDecimal.new('0.65')
194
+ end
195
+ end
196
+ end
197
+
198
+ describe 'numericality validation' do
199
+ context 'when no validation options are passed' do
200
+ it 'ensures that the percentage can not be nil' do
201
+ subject.percent_complete = nil
202
+ expect(subject).to_not be_valid
203
+ end
204
+
205
+ it 'ensures that the percentage is between 0 and 100' do
206
+ subject.percent_complete = true
207
+ expect(subject).to be_valid
208
+
209
+ subject.percent_complete = false
210
+ expect(subject).to be_valid
211
+
212
+ subject.percent_complete = -1
213
+ expect(subject).to_not be_valid
214
+
215
+ subject.percent_complete = 101
216
+ expect(subject).to_not be_valid
217
+
218
+ subject.percent_complete = 10
219
+ expect(subject).to be_valid
220
+ end
221
+ end
222
+
223
+ context 'when validation options are passed' do
224
+ it 'ensures that the percentage matches the given criteria' do
225
+ subject.in_a_weird_range = -10
226
+ expect(subject).to_not be_valid
227
+
228
+ subject.in_a_weird_range = 0
229
+ expect(subject).to be_valid
230
+
231
+ subject.in_a_weird_range = true
232
+ expect(subject).to be_valid
233
+
234
+ subject.in_a_weird_range = false
235
+ expect(subject).to be_valid
236
+
237
+ subject.in_a_weird_range = 200
238
+ expect(subject).to_not be_valid
239
+
240
+ subject.in_a_weird_range = 100
241
+ expect(subject).to be_valid
242
+ end
243
+ end
244
+
245
+ context 'when false is passed' do
246
+ it 'should not validate any values passed to the attribute' do
247
+ subject.sans_frac_validate_fraction = 'string'
248
+ expect(subject).to be_valid
249
+
250
+ subject.sans_frac_validate_fraction = false
251
+ expect(subject).to be_valid
252
+
253
+ subject.sans_frac_validate_fraction = true
254
+ expect(subject).to be_valid
255
+ end
256
+ end
257
+ end
258
+
259
+ describe 'fraction numericality validation' do
260
+ context 'when no validation options are passed' do
261
+ it 'ensures that the percentage fraction can not be nil' do
262
+ subject.percent_complete_fraction = nil
263
+ expect(subject).to_not be_valid
264
+ end
265
+
266
+ it 'ensures that the percentage fraction is between 0 and 1' do
267
+ subject.percent_complete_fraction = -0.01
268
+ expect(subject).to_not be_valid
269
+
270
+ subject.percent_complete_fraction = 1.01
271
+ expect(subject).to_not be_valid
272
+
273
+ subject.percent_complete_fraction = 0.1
274
+ expect(subject).to be_valid
275
+ end
276
+ end
277
+
278
+ context 'when validation options are passed' do
279
+ it 'ensures that the percentage matches the given criteria' do
280
+ subject.in_fraction_range_fraction = -0.1
281
+ expect(subject).to_not be_valid
282
+
283
+ subject.in_fraction_range_fraction = 0
284
+ expect(subject).to be_valid
285
+
286
+ subject.in_fraction_range_fraction = 2
287
+ expect(subject).to_not be_valid
288
+
289
+ subject.in_fraction_range_fraction = 1
290
+ expect(subject).to be_valid
291
+ end
292
+ end
293
+ end
294
+
295
+ describe 'allow nil validation' do
296
+ context 'when no validation is passed' do
297
+ it 'ensures that the percentage and percentage fraction can not be nil' do
298
+ subject.percent_complete_fraction = nil
299
+ expect(subject).to_not be_valid
300
+ subject.percent_complete = nil
301
+ expect(subject).to_not be_valid
302
+ end
303
+ end
304
+
305
+ context 'when false is passed' do
306
+ it 'ensures that the percentage and percentage fraction can not be nil' do
307
+ subject.percent_complete_fraction = nil
308
+ expect(subject).to_not be_valid
309
+ subject.percent_complete = nil
310
+ expect(subject).to_not be_valid
311
+ end
312
+ end
313
+
314
+ context 'when true is passed' do
315
+ it 'allows the percentage and percentage fraction to be nil' do
316
+ subject.optional_fraction = nil
317
+ expect(subject).to be_valid
318
+ subject.optional = nil
319
+ expect(subject).to be_valid
320
+ end
321
+ end
322
+ end
323
+
324
+ describe 'disable validation' do
325
+ context 'when disable validation is given a true value' do
326
+ it 'should allow any value' do
327
+ subject.sans_validation = nil
328
+ expect(subject).to be_valid
329
+
330
+ subject.sans_validation = 'string'
331
+ expect(subject).to be_valid
332
+
333
+ subject.sans_validation_fraction = nil
334
+ expect(subject).to be_valid
335
+
336
+ subject.sans_validation_fraction = 'string'
337
+ expect(subject).to be_valid
338
+
339
+ subject.sans_validation_fraction = false
340
+ expect(subject).to be_valid
341
+
342
+ subject.sans_validation_fraction = true
343
+ expect(subject).to be_valid
344
+ end
345
+ end
346
+ end
347
+
348
+ end
349
+ end
350
+ end
@@ -0,0 +1,719 @@
1
+ require 'spec_helper'
2
+
3
+ describe Percentage do
4
+ subject { Percentage.new value }
5
+ let (:value) { 0 }
6
+
7
+ describe 'methods' do
8
+ it { is_expected.to respond_to(:value) }
9
+ it { is_expected.to respond_to(:to_i) }
10
+ it { is_expected.to respond_to(:to_c) }
11
+ it { is_expected.to respond_to(:to_d) }
12
+ it { is_expected.to respond_to(:to_f) }
13
+ it { is_expected.to respond_to(:to_r) }
14
+ it { is_expected.to respond_to(:to_complex) }
15
+ it { is_expected.to respond_to(:to_decimal) }
16
+ it { is_expected.to respond_to(:to_float) }
17
+ it { is_expected.to respond_to(:to_rational) }
18
+ it { is_expected.to respond_to(:to_s) }
19
+ it { is_expected.to respond_to(:to_str) }
20
+ it { is_expected.to respond_to(:to_string) }
21
+ it { is_expected.to respond_to(:format) }
22
+ it { is_expected.to respond_to(:to_amount) }
23
+ it { is_expected.to respond_to(:inspect) }
24
+ it { is_expected.to respond_to(:==) }
25
+ it { is_expected.to respond_to(:eql?) }
26
+ it { is_expected.to respond_to(:<=>) }
27
+ it { is_expected.to respond_to(:+) }
28
+ it { is_expected.to respond_to(:-) }
29
+ it { is_expected.to respond_to(:/) }
30
+ it { is_expected.to respond_to(:*) }
31
+ end
32
+
33
+ describe 'class methods' do
34
+ subject { Percentage }
35
+
36
+ it { is_expected.to respond_to(:from_fraction) }
37
+ it { is_expected.to respond_to(:from_amount) }
38
+ end
39
+
40
+ context 'Initialization methods' do
41
+ shared_examples 'a percentage' do |amount|
42
+ let (:decimal_value) { amount.to_d / 100 }
43
+ let (:string_value) { "#{amount.to_f}%" }
44
+
45
+ it 'should equal the given percentage' do
46
+ expect(subject.value).to eql decimal_value
47
+ expect(subject.format).to eql string_value
48
+ end
49
+ end
50
+
51
+ describe '#initialize' do
52
+ context 'with value of 50' do
53
+ let (:value) { 50 }
54
+ it_should_behave_like 'a percentage', 50
55
+ end
56
+
57
+ context 'with value of 0.5' do
58
+ let (:value) { 0.5 }
59
+ it_should_behave_like 'a percentage', 50
60
+ end
61
+
62
+ context 'with a numeric value of 1/2' do
63
+ let (:value) { Rational 1, 2 }
64
+ it_should_behave_like 'a percentage', 50
65
+ end
66
+
67
+ context 'with a numeric value of 0.5E0' do
68
+ let (:value) { BigDecimal.new '0.5' }
69
+ it_should_behave_like 'a percentage', 50
70
+ end
71
+
72
+ context 'with a numeric value of 0.5+0i' do
73
+ let (:value) { Complex(0.5, 0) }
74
+ it_should_behave_like 'a percentage', 50
75
+ end
76
+
77
+ context 'with a string value of "50"' do
78
+ let (:value) { '50' }
79
+ it_should_behave_like 'a percentage', 50
80
+ end
81
+
82
+ context 'with a string value of "50%"' do
83
+ let (:value) { '50%' }
84
+ it_should_behave_like 'a percentage', 50
85
+ end
86
+
87
+ context 'with a string value of "50.0%"' do
88
+ let (:value) { '50.0%' }
89
+ it_should_behave_like 'a percentage', 50
90
+ end
91
+
92
+ context 'with a string value of ".5"' do
93
+ let (:value) { '.5' }
94
+ it_should_behave_like 'a percentage', 50
95
+ end
96
+
97
+ context 'with a string value of "0.5"' do
98
+ let (:value) { '0.5' }
99
+ it_should_behave_like 'a percentage', 50
100
+ end
101
+
102
+ context 'with a string value of "0.5E0"' do
103
+ let (:value) { '0.5E0' }
104
+ it_should_behave_like 'a percentage', 50
105
+ end
106
+
107
+ context 'with a string value of "1/2"' do
108
+ let (:value) { '1/2' }
109
+ it_should_behave_like 'a percentage', 50
110
+ end
111
+
112
+ context 'with a boolean value of true' do
113
+ let (:value) { true }
114
+ it_should_behave_like 'a percentage', 100
115
+ end
116
+
117
+ context 'with a boolean value of false' do
118
+ let (:value) { false }
119
+ it_should_behave_like 'a percentage', 0
120
+ end
121
+ end
122
+
123
+ describe '#self.from_fraction' do
124
+ let (:subject) { Percentage.from_fraction value }
125
+
126
+ context 'with a numeric value of 50.0' do
127
+ let (:value) { 50.0 }
128
+ it_should_behave_like 'a percentage', 5000
129
+ end
130
+
131
+ context 'with a numeric value of 50' do
132
+ let (:value) { 50 }
133
+ it_should_behave_like 'a percentage', 5000
134
+ end
135
+
136
+ context 'with a numeric value of 1' do
137
+ let (:value) { 1 }
138
+ it_should_behave_like 'a percentage', 100
139
+ end
140
+
141
+ context 'with a numeric value of 0' do
142
+ let (:value) { 0 }
143
+ it_should_behave_like 'a percentage', 0
144
+ end
145
+
146
+ context 'with a string value of "50.0"' do
147
+ let (:value) { '50.0' }
148
+ it_should_behave_like 'a percentage', 5000
149
+ end
150
+
151
+ context 'with a string value of "50"' do
152
+ let (:value) { '50' }
153
+ it_should_behave_like 'a percentage', 5000
154
+ end
155
+
156
+ context 'with a string value of "1"' do
157
+ let (:value) { '1' }
158
+ it_should_behave_like 'a percentage', 100
159
+ end
160
+
161
+ context 'with a string value of "0"' do
162
+ let (:value) { '0' }
163
+ it_should_behave_like 'a percentage', 0
164
+ end
165
+ end
166
+
167
+ describe '#self.from_amount' do
168
+ let (:subject) { Percentage.from_amount value }
169
+
170
+ context 'with a numeric value of 50' do
171
+ let (:value) { 50 }
172
+ it_should_behave_like 'a percentage', 50
173
+ end
174
+
175
+ context 'with a numeric value of 50.0' do
176
+ let (:value) { 50.0 }
177
+ it_should_behave_like 'a percentage', 50
178
+ end
179
+
180
+ context 'with a numeric value of 0.5E2' do
181
+ let (:value) { BigDecimal.new 50 }
182
+ it_should_behave_like 'a percentage', 50
183
+ end
184
+
185
+ context 'with a numeric value of 100/2' do
186
+ let (:value) { Rational 100, 2 }
187
+ it_should_behave_like 'a percentage', 50
188
+ end
189
+
190
+ context 'with a string value of "50"' do
191
+ let (:value) { '50' }
192
+ it_should_behave_like 'a percentage', 50
193
+ end
194
+
195
+ context 'with a string value of "50.0"' do
196
+ let (:value) { '50.0' }
197
+ it_should_behave_like 'a percentage', 50
198
+ end
199
+
200
+ context 'with a string value of "0.5E2"' do
201
+ let (:value) { '0.5E2' }
202
+ it_should_behave_like 'a percentage', 50
203
+ end
204
+
205
+ context 'with a string value of "200/4"' do
206
+ let (:value) { '200/4' }
207
+ it_should_behave_like 'a percentage', 50
208
+ end
209
+ end
210
+ end
211
+
212
+ context 'Attributes' do
213
+ describe '#value' do
214
+ context 'when a value is passed to an initialization method' do
215
+ let (:value) { BigDecimal('1.5') }
216
+
217
+ it 'should return that value' do
218
+ expect(subject.value).to eql value
219
+ expect(Percentage.from_fraction(value).value).to eql value
220
+ expect(Percentage.from_amount(value * 100).value).to eql value
221
+ end
222
+ end
223
+
224
+ context 'when nothing is passed to an initialization method' do
225
+ it 'should return 0' do
226
+ expect(Percentage.new.value).to eql BigDecimal(0)
227
+ expect(Percentage.from_fraction.value).to eql BigDecimal(0)
228
+ expect(Percentage.from_amount.value).to eql BigDecimal(0)
229
+ end
230
+ end
231
+ end
232
+ end
233
+
234
+ context 'Conversions' do
235
+ let (:value) { 75 }
236
+
237
+ describe '#to_i' do
238
+ context 'with a numeric value of 75' do
239
+ it 'should return 75' do
240
+ expect(subject.to_i).to eql 75
241
+ end
242
+ end
243
+ end
244
+
245
+ describe '#to_c' do
246
+ context 'with a numeric value of 75' do
247
+ it 'should return 0.75E0+0i' do
248
+ expect(subject.to_c).to eql Complex(BigDecimal.new('0.75'), 0)
249
+ end
250
+ end
251
+ end
252
+
253
+ describe '#to_d' do
254
+ context 'with a numeric value of 75' do
255
+ it 'should return 0.75E0' do
256
+ expect(subject.to_d).to eql BigDecimal.new('0.75')
257
+ end
258
+ end
259
+ end
260
+
261
+ describe '#to_f' do
262
+ context 'with a numeric value of 75' do
263
+ it 'should return 0.75' do
264
+ expect(subject.to_f).to eql 0.75
265
+ end
266
+ end
267
+ end
268
+
269
+ describe '#to_r' do
270
+ context 'with a numeric value of 75' do
271
+ it 'should return 3/4' do
272
+ expect(subject.to_r).to eql Rational(3,4)
273
+ end
274
+ end
275
+ end
276
+
277
+ describe '#to_complex' do
278
+ context 'with a numeric value of 75' do
279
+ it 'should return 0.75E2+0i' do
280
+ expect(subject.to_complex).to eql Complex(BigDecimal.new(75), 0)
281
+ end
282
+ end
283
+ end
284
+
285
+ describe '#to_decimal' do
286
+ context 'with a numeric value of 75' do
287
+ it 'should return 0.75E2' do
288
+ expect(subject.to_decimal).to eql BigDecimal(75)
289
+ end
290
+ end
291
+ end
292
+
293
+ describe '#to_float' do
294
+ context 'with a numeric value of 75' do
295
+ it 'should return 75.0' do
296
+ expect(subject.to_float).to eql 75.0
297
+ end
298
+ end
299
+ end
300
+
301
+ describe '#to_rational' do
302
+ context 'with a numeric value of 75' do
303
+ it 'should return 75/1' do
304
+ expect(subject.to_rational).to eql Rational(75,1)
305
+ end
306
+ end
307
+ end
308
+
309
+ describe '#to_s' do
310
+ context 'with a numeric value of 75' do
311
+ it 'should return "75"' do
312
+ expect(subject.to_s).to eql '75'
313
+ end
314
+ end
315
+
316
+ context 'with a numeric value of 0.75' do
317
+ let (:value) { 0.75 }
318
+ it 'should return "75"' do
319
+ expect(subject.to_s).to eql '75'
320
+ end
321
+ end
322
+
323
+ context 'with a numeric value of 0.755' do
324
+ let (:value) { 0.755 }
325
+ it 'should return "75.5"' do
326
+ expect(subject.to_s).to eql '75.5'
327
+ end
328
+ end
329
+ end
330
+
331
+ describe '#to_str' do
332
+ context 'with a numeric value of 75' do
333
+ it 'should return "0.75"' do
334
+ expect(subject.to_str).to eql '0.75'
335
+ end
336
+ end
337
+ end
338
+
339
+ describe '#to_string' do
340
+ context 'with a numeric value of 75' do
341
+ it 'should return "75%"' do
342
+ expect(subject.to_string).to eql '75%'
343
+ end
344
+ end
345
+
346
+ context 'with a numeric value of 0.75' do
347
+ let (:value) { 0.75 }
348
+ it 'should return "75%"' do
349
+ expect(subject.to_string).to eql '75%'
350
+ end
351
+ end
352
+
353
+ context 'with a numeric value of 0.755' do
354
+ let (:value) { 0.755 }
355
+ it 'should return "75.5%"' do
356
+ expect(subject.to_string).to eql '75.5%'
357
+ end
358
+ end
359
+ end
360
+
361
+ describe "#format" do
362
+ context 'with a value of 0.6666' do
363
+ let (:value) { 0.6666 }
364
+
365
+ context 'when passed no options' do
366
+ it 'should return "66.66%"' do
367
+ expect(subject.format).to eql '66.66%'
368
+ end
369
+ end
370
+
371
+ context 'when passed percent_sign: true' do
372
+ it 'should return "66.66%"' do
373
+ expect(subject.format percent_sign: true).to eql '66.66%'
374
+ end
375
+ end
376
+
377
+ context 'when passed percent_sign: false' do
378
+ it 'should return "66.66"' do
379
+ expect(subject.format percent_sign: false).to eql '66.66'
380
+ end
381
+ end
382
+
383
+ context 'when passed as_decimal: true' do
384
+ it 'should return "0.6666"' do
385
+ expect(subject.format as_decimal: true).to eql '0.6666'
386
+ end
387
+ end
388
+
389
+ context 'when passed rounded: true' do
390
+ it 'should return "67%"' do
391
+ expect(subject.format rounded: true).to eql '67%'
392
+ end
393
+ end
394
+
395
+ context 'when passed no_decimal: true' do
396
+ it 'should return "66%"' do
397
+ expect(subject.format no_decimal: true).to eql '66%'
398
+ end
399
+ end
400
+
401
+ context 'when passed no_decimal_if_whole: true' do
402
+ it 'should return "66.66%"' do
403
+ expect(subject.format no_decimal_if_whole: true).to eql '66.66%'
404
+ end
405
+ end
406
+
407
+ context 'when passed space_before_sign: true' do
408
+ it 'should return "66.66 %"' do
409
+ expect(subject.format space_before_sign: true).to eql '66.66 %'
410
+ end
411
+ end
412
+
413
+ context 'when passed percent_sign: false, rounded: true, space_before_sign: true' do
414
+ it 'should return "67 "' do
415
+ f = subject.format percent_sign: false, rounded: true, space_before_sign: true
416
+ expect(f).to eql '67 '
417
+ end
418
+ end
419
+
420
+ context 'when passed no_decimal: true, space_before_sign: true' do
421
+ it 'should return "66 %"' do
422
+ f = subject.format no_decimal: true, space_before_sign: true
423
+ expect(f).to eql '66 %'
424
+ end
425
+ end
426
+
427
+ context 'when passed percent_sign: false, as_decimal: true, no_decimal: true' do
428
+ it 'should return "0.6666"' do
429
+ f = subject.format percent_sign: false, as_decimal: true, no_decimal: true
430
+ expect(f).to eql '0.6666'
431
+ end
432
+ end
433
+
434
+ context 'when passed no_decimal_if_whole: true, no_decimal: true, rounded: true' do
435
+ it 'should return "67%"' do
436
+ f = subject.format no_decimal_if_whole: true, no_decimal: true, rounded: true
437
+ expect(f).to eql '67%'
438
+ end
439
+ end
440
+
441
+ context 'when passed no_decimal_if_whole: true, no_decimal: true' do
442
+ it 'should return "66%"' do
443
+ f = subject.format no_decimal_if_whole: true, no_decimal: true
444
+ expect(f).to eql '66%'
445
+ end
446
+ end
447
+ end
448
+ end
449
+
450
+ describe '#to_amount' do
451
+ context 'with a numeric value of 75' do
452
+ it 'should return 75' do
453
+ expect(subject.to_amount).to eql 75
454
+ end
455
+ end
456
+
457
+ context 'with a numeric value of 0.75' do
458
+ let (:value) { 0.75 }
459
+ it 'should return 75' do
460
+ expect(subject.to_amount).to eql 75
461
+ end
462
+ end
463
+
464
+ context 'with a numeric value of 0.755' do
465
+ let (:value) { 0.755 }
466
+ it 'should return 75.5' do
467
+ expect(subject.to_amount).to eql 75.5
468
+ end
469
+ end
470
+ end
471
+ end
472
+
473
+ context 'Comparisons' do
474
+ let (:value) { 100 }
475
+ let (:duplicate) { Percentage.new value }
476
+ let (:other) { Percentage.new 99 }
477
+
478
+ shared_examples_for 'full ==' do
479
+ it 'should equal a number with the same value' do
480
+ expect(equivalent == subject).to eql true
481
+ expect(equivalent >= subject).to eql true
482
+ expect(equivalent <= subject).to eql true
483
+ expect(equivalent != subject).to eql false
484
+ expect(equivalent > subject).to eql false
485
+ expect(equivalent < subject).to eql false
486
+
487
+ expect(subject == equivalent).to eql true
488
+ expect(subject >= equivalent).to eql true
489
+ expect(subject <= equivalent).to eql true
490
+ expect(subject != equivalent).to eql false
491
+ expect(subject > equivalent).to eql false
492
+ expect(subject < equivalent).to eql false
493
+ end
494
+
495
+ it 'should not equal a number with a different value' do
496
+ expect(subject == different).to eql false
497
+ expect(subject != different).to eql true
498
+
499
+ expect(different == subject).to eql false
500
+ expect(different != subject).to eql true
501
+ end
502
+ end
503
+
504
+ shared_examples_for 'comparisons' do
505
+ it 'should know when something is greater than' do
506
+ expect(subject > smaller).to be true
507
+ expect(subject > larger ).to be false
508
+ expect(smaller > subject).to be false
509
+ expect(larger > subject).to be true
510
+ end
511
+
512
+ it 'should know when something is less than' do
513
+ expect(subject < smaller).to be false
514
+ expect(subject < larger ).to be true
515
+ expect(smaller < subject).to be true
516
+ expect(larger < subject).to be false
517
+ end
518
+
519
+ it 'should know when something is greater than or equal to' do
520
+ expect(subject >= smaller).to be true
521
+ expect(subject >= larger ).to be false
522
+ expect(smaller >= subject).to be false
523
+ expect(larger >= subject).to be true
524
+ end
525
+
526
+ it 'should know when something is less than or equal to' do
527
+ expect(subject <= smaller).to be false
528
+ expect(subject <= larger ).to be true
529
+ expect(smaller <= subject).to be true
530
+ expect(larger <= subject).to be false
531
+ end
532
+ end
533
+
534
+ describe '#==' do
535
+ context 'comparing with percentage' do
536
+ it 'should equal itself' do
537
+ expect(subject == subject).to eql true
538
+ end
539
+
540
+ it 'should equal a different percentage object with the same value' do
541
+ expect(subject == duplicate).to eql true
542
+ end
543
+
544
+ it 'should not equal a different percentage' do
545
+ expect(subject == other).to eql false
546
+ end
547
+ end
548
+
549
+ context 'comparing with integer' do
550
+ let (:equivalent) { 1 }
551
+ let (:different) { 2 }
552
+ it_should_behave_like 'full =='
553
+ end
554
+
555
+ context 'comparing with complex' do
556
+ let (:equivalent) { Complex(1.0,0) }
557
+ let (:different) { Complex(1.00101,0) }
558
+
559
+ it 'should equal a number with the same value' do
560
+ expect(equivalent == subject).to eql true
561
+ expect(equivalent != subject).to eql false
562
+
563
+ expect(subject == equivalent).to eql true
564
+ expect(subject != equivalent).to eql false
565
+ end
566
+
567
+ it 'should not equal a number with a different value' do
568
+ expect(subject == different).to eql false
569
+ expect(subject != different).to eql true
570
+
571
+ expect(different == subject).to eql false
572
+ expect(different != subject).to eql true
573
+ end
574
+ end
575
+
576
+ context 'comparing with decimal' do
577
+ let (:equivalent) { BigDecimal.new(1) }
578
+ let (:different) { BigDecimal.new('.99') }
579
+ it_should_behave_like 'full =='
580
+ end
581
+
582
+ context 'comparing with float' do
583
+ let (:equivalent) { 1.0 }
584
+ let (:different) { 1.1010 }
585
+ it_should_behave_like 'full =='
586
+ end
587
+
588
+ context 'comparing with rational' do
589
+ let (:equivalent) { Rational(1) }
590
+ let (:different) { Rational(9,8) }
591
+ it_should_behave_like 'full =='
592
+ end
593
+ end
594
+
595
+ describe '#eql?' do
596
+ it 'should equal itself' do
597
+ expect(subject.eql? subject).to eql true
598
+ end
599
+
600
+ it 'should equal a different percentage object with the same value' do
601
+ expect(subject.eql? duplicate).to eql true
602
+ end
603
+
604
+ it 'should not equal a different percentage' do
605
+ expect(subject.eql? other).to eql false
606
+ end
607
+
608
+ it 'should not equal any other numbers with the same value' do
609
+ expect(subject.eql? 1).to eql false
610
+ expect(subject.eql? 1.0).to eql false
611
+ expect(subject.eql? Complex(1, 0)).to eql false
612
+ expect(subject.eql? Rational(1)).to eql false
613
+ expect(subject.eql? BigDecimal.new(1)).to eql false
614
+ end
615
+ end
616
+
617
+ describe 'comparable' do
618
+ it 'is comparable' do
619
+ expect(subject.is_a? Comparable).to be true
620
+ end
621
+
622
+ context 'compared to other percentages' do
623
+ let (:smaller) { other }
624
+ let (:larger) { Percentage.new 101 }
625
+ it_should_behave_like 'comparisons'
626
+ end
627
+
628
+ context 'compared to decimals' do
629
+ let (:smaller) { BigDecimal.new '0.999999' }
630
+ let (:larger) { BigDecimal.new '1.000001' }
631
+ it_should_behave_like 'comparisons'
632
+ end
633
+
634
+ context 'compared to floats' do
635
+ let (:smaller) { 0.999999 }
636
+ let (:larger) { 1.000001 }
637
+ it_should_behave_like 'comparisons'
638
+ end
639
+
640
+ context 'compared to integers' do
641
+ let (:smaller) { 0 }
642
+ let (:larger) { 2 }
643
+ it_should_behave_like 'comparisons'
644
+ end
645
+
646
+ context 'compared to rationals' do
647
+ let (:denominator) { 10 ** 10 }
648
+ let (:smaller) { Rational denominator - 1, denominator }
649
+ let (:larger) { Rational denominator + 1, denominator }
650
+ it_should_behave_like 'comparisons'
651
+ end
652
+ end
653
+ end
654
+
655
+ context 'Mathematical operations' do
656
+ let (:value) { 25 }
657
+ let (:number) { 10 }
658
+
659
+ describe '#+' do
660
+ context 'when adding two percentages' do
661
+ it 'should return the sum of the two percentages' do
662
+ expect(subject + subject).to eql Percentage.new(50)
663
+ end
664
+ end
665
+
666
+ context 'when adding a percent and a number' do
667
+ it 'should return sum of the two' do
668
+ expect(subject + number).to eq 10.25
669
+ expect(number + subject).to eq 10.25
670
+ end
671
+ end
672
+ end
673
+
674
+ describe '#-' do
675
+ context 'when subtracting two percentages' do
676
+ it 'should return the difference of the two percentages' do
677
+ expect(subject - subject).to eql Percentage.new(0)
678
+ end
679
+ end
680
+
681
+ context 'when subtracting a percent and a number' do
682
+ it 'should return the difference between the two' do
683
+ expect(subject - number).to eq -9.75
684
+ expect(number - subject).to eq 9.75
685
+ end
686
+ end
687
+ end
688
+
689
+ describe '#*' do
690
+ context 'when multiplying two percentagess' do
691
+ it 'should return the product of the two percentages' do
692
+ expect(subject * subject).to eql Percentage.from_amount(6.25)
693
+ end
694
+ end
695
+
696
+ context 'when multiplying a percent and a number' do
697
+ it 'should return the product of the two' do
698
+ expect(subject * number).to eq 2.5
699
+ expect(number * subject).to eq 2.5
700
+ end
701
+ end
702
+ end
703
+
704
+ describe '#/' do
705
+ context 'when dividing two percentages' do
706
+ it 'should return the quotient of the two percentages' do
707
+ expect(subject / subject).to eql Percentage.new(100)
708
+ end
709
+ end
710
+
711
+ context 'when subtracting a percent and a number' do
712
+ it 'should return the quotient' do
713
+ expect(subject / number).to eq 0.025
714
+ expect(number / subject).to eq 40.0
715
+ end
716
+ end
717
+ end
718
+ end
719
+ end