bytesize 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 +7 -0
- data/LICENSE.txt +21 -0
- data/README.md +165 -0
- data/lib/bytesize.rb +1277 -0
- data/lib/bytesize/activerecord.rb +50 -0
- data/lib/bytesize/units.rb +227 -0
- data/lib/bytesize/version.rb +18 -0
- data/spec/bytesize_spec.rb +30 -0
- data/spec/iecbytesize_spec.rb +30 -0
- data/spec/shared_examples.rb +408 -0
- data/spec/test_enum.rb +86 -0
- data/spec/value_class_helper.rb +363 -0
- metadata +104 -0
data/spec/test_enum.rb
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
#!/usr/bin/env ruby -w
|
2
|
+
#
|
3
|
+
# ByteSize
|
4
|
+
#
|
5
|
+
# TestEnum
|
6
|
+
#
|
7
|
+
# An enumerable class that generates integer test values that include a range around each
|
8
|
+
# unit transition point and a random set of intervals in between.
|
9
|
+
#
|
10
|
+
# © 2018 Adam Hunt
|
11
|
+
# Created: 2018-04-07
|
12
|
+
# Modified: 2018-04-07
|
13
|
+
#
|
14
|
+
|
15
|
+
|
16
|
+
|
17
|
+
class TestEnum
|
18
|
+
include Enumerable
|
19
|
+
|
20
|
+
def initialize( base:, num_powers:8, transition_range:(-2..2), random_intervals:5, negative:true )
|
21
|
+
@base = base.to_i
|
22
|
+
@num_powers = num_powers.to_i
|
23
|
+
|
24
|
+
@transition_range = transition_range.is_a?(Range) ? transition_range.freeze : Range.new(*transition_range).freeze
|
25
|
+
if @transition_range.max.nil? then
|
26
|
+
@transition_range = Range( @transition_range.last, @transition_range.first ).freeze
|
27
|
+
end
|
28
|
+
|
29
|
+
@random_intervals = random_intervals.to_i
|
30
|
+
@negative = !! negative
|
31
|
+
end
|
32
|
+
|
33
|
+
attr_reader :base, :num_powers, :transition_range, :random_intervals
|
34
|
+
|
35
|
+
def negative?; @negative; end
|
36
|
+
|
37
|
+
def each
|
38
|
+
return enum_for(:each) unless block_given?
|
39
|
+
|
40
|
+
(( negative? ? -num_powers : 0 )..num_powers).inject(nil) do |last, current|
|
41
|
+
current = current == 0 ? 0 : (base**current.abs) * ( current.negative? ? -1 : 1 )
|
42
|
+
|
43
|
+
unless last.nil? or transition_range.max.nil?
|
44
|
+
interval_range = (last+transition_range.max+1..current+transition_range.min-1)
|
45
|
+
|
46
|
+
unless interval_range.max.nil?
|
47
|
+
if interval_range.size <= random_intervals
|
48
|
+
interval_range.each do |i|
|
49
|
+
yield(i)
|
50
|
+
end
|
51
|
+
else
|
52
|
+
intervals = []
|
53
|
+
random_intervals.times do
|
54
|
+
begin
|
55
|
+
r = rand(interval_range)
|
56
|
+
end while intervals.include?(r)
|
57
|
+
intervals.push(r)
|
58
|
+
end
|
59
|
+
intervals.sort!
|
60
|
+
intervals.each do |i|
|
61
|
+
yield(i)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
if negative? or current != 0
|
69
|
+
transition_range.each do |r|
|
70
|
+
yield( current + r )
|
71
|
+
end
|
72
|
+
else
|
73
|
+
if transition_range.max != 0
|
74
|
+
(0..transition_range.max).each do |r|
|
75
|
+
yield( current + r )
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
current
|
81
|
+
end
|
82
|
+
|
83
|
+
return nil
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
@@ -0,0 +1,363 @@
|
|
1
|
+
#!/usr/bin/env ruby -w
|
2
|
+
#
|
3
|
+
# Value Classes Helper
|
4
|
+
#
|
5
|
+
# © 2018 Adam Hunt
|
6
|
+
# Created: 2018-04-07
|
7
|
+
# Modified: 2018-04-08
|
8
|
+
#
|
9
|
+
|
10
|
+
|
11
|
+
|
12
|
+
shared_examples "correct comparison" do |op_hash|
|
13
|
+
raise( TypeError, "expected #{Hash}, got #{op_hash.class}" ) unless op_hash.is_a?(Hash)
|
14
|
+
|
15
|
+
op_hash.each do |op,v|
|
16
|
+
describe "with \##{op}" do
|
17
|
+
it "returns #{v.inspect}" do
|
18
|
+
expect( a.send( op, b ) ).to be v
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
|
27
|
+
shared_examples "compares to itself correctly" do
|
28
|
+
|
29
|
+
context "when compared to itself" do
|
30
|
+
let(:a){ instance }
|
31
|
+
let(:b){ instance }
|
32
|
+
include_examples "correct comparison", {
|
33
|
+
:== => true,
|
34
|
+
:=== => true,
|
35
|
+
:eql? => true,
|
36
|
+
:equal? => true,
|
37
|
+
:<=> => 0,
|
38
|
+
:> => false,
|
39
|
+
:< => false,
|
40
|
+
:>= => true,
|
41
|
+
:<= => true
|
42
|
+
}
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
|
49
|
+
shared_examples "compares to a duplicate instance correctly" do |reverse:true|
|
50
|
+
|
51
|
+
let(:other){ described_class.new(instance) }
|
52
|
+
|
53
|
+
context "when compared to a duplicate" do
|
54
|
+
let(:a){ instance }
|
55
|
+
let(:b){ other }
|
56
|
+
include_examples "correct comparison", {
|
57
|
+
:== => true,
|
58
|
+
:=== => true,
|
59
|
+
:eql? => true,
|
60
|
+
:equal? => false,
|
61
|
+
:<=> => 0,
|
62
|
+
:> => false,
|
63
|
+
:< => false,
|
64
|
+
:>= => true,
|
65
|
+
:<= => true
|
66
|
+
}
|
67
|
+
end
|
68
|
+
|
69
|
+
if reverse
|
70
|
+
context "a duplicate is compared to it" do
|
71
|
+
let(:a){ other }
|
72
|
+
let(:b){ instance }
|
73
|
+
include_examples "correct comparison", {
|
74
|
+
:== => true,
|
75
|
+
:=== => true,
|
76
|
+
:eql? => true,
|
77
|
+
:equal? => false,
|
78
|
+
:<=> => 0,
|
79
|
+
:> => false,
|
80
|
+
:< => false,
|
81
|
+
:>= => true,
|
82
|
+
:<= => true
|
83
|
+
}
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
|
89
|
+
|
90
|
+
|
91
|
+
shared_examples "compares to an instance of equal value correctly" do |new_class:nil, reverse:true, to_method:(:to_i)|
|
92
|
+
|
93
|
+
let(:num){ instance.send(to_method) }
|
94
|
+
|
95
|
+
if new_class.nil?
|
96
|
+
cont = "when compared to an instance of equal value"
|
97
|
+
rcont = "an instance of equal value is compared to it"
|
98
|
+
let(:other){ described_class.new(num) }
|
99
|
+
else
|
100
|
+
cont = "when compared to an instance of #{new_class} of equal value"
|
101
|
+
rcont = "an instance of #{new_class} of equal value is compared to it"
|
102
|
+
let(:other){ new_class.new(num) }
|
103
|
+
end
|
104
|
+
|
105
|
+
context cont do
|
106
|
+
let(:a){ instance }
|
107
|
+
let(:b){ other }
|
108
|
+
include_examples "correct comparison", {
|
109
|
+
:== => true,
|
110
|
+
:=== => true,
|
111
|
+
:eql? => true,
|
112
|
+
:equal? => false,
|
113
|
+
:<=> => 0,
|
114
|
+
:> => false,
|
115
|
+
:< => false,
|
116
|
+
:>= => true,
|
117
|
+
:<= => true
|
118
|
+
}
|
119
|
+
end
|
120
|
+
|
121
|
+
if reverse
|
122
|
+
context rcont do
|
123
|
+
let(:a){ other }
|
124
|
+
let(:b){ instance }
|
125
|
+
include_examples "correct comparison", {
|
126
|
+
:== => true,
|
127
|
+
:=== => true,
|
128
|
+
:eql? => true,
|
129
|
+
:equal? => false,
|
130
|
+
:<=> => 0,
|
131
|
+
:> => false,
|
132
|
+
:< => false,
|
133
|
+
:>= => true,
|
134
|
+
:<= => true
|
135
|
+
}
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
end
|
140
|
+
|
141
|
+
|
142
|
+
|
143
|
+
shared_examples "compares to an equal numeric correctly" do |value:nil, reverse:true, to_method:(:to_i)|
|
144
|
+
|
145
|
+
let(:other) do
|
146
|
+
unless value.nil?
|
147
|
+
v = value
|
148
|
+
raise( StandardError, "comparison value must be a #{Numeric}" ) unless v.is_a?(Numeric)
|
149
|
+
else
|
150
|
+
v = instance.send(to_method)
|
151
|
+
raise( StandardError, "to_method did not return a #{Numeric}" ) unless v.is_a?(Numeric)
|
152
|
+
end
|
153
|
+
v
|
154
|
+
end
|
155
|
+
|
156
|
+
context "when compared to an equal numeric" do
|
157
|
+
let(:a){ instance }
|
158
|
+
let(:b){ other }
|
159
|
+
include_examples "correct comparison", {
|
160
|
+
:== => true,
|
161
|
+
:=== => true,
|
162
|
+
:eql? => false,
|
163
|
+
:equal? => false,
|
164
|
+
:<=> => 0,
|
165
|
+
:> => false,
|
166
|
+
:< => false,
|
167
|
+
:>= => true,
|
168
|
+
:<= => true
|
169
|
+
}
|
170
|
+
end
|
171
|
+
|
172
|
+
if reverse
|
173
|
+
context "when an equal numeric is compared to it" do
|
174
|
+
let(:a){ other }
|
175
|
+
let(:b){ instance }
|
176
|
+
include_examples "correct comparison", {
|
177
|
+
:== => true,
|
178
|
+
:=== => true,
|
179
|
+
:eql? => false,
|
180
|
+
:equal? => false,
|
181
|
+
:<=> => 0,
|
182
|
+
:> => false,
|
183
|
+
:< => false,
|
184
|
+
:>= => true,
|
185
|
+
:<= => true
|
186
|
+
}
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
end
|
191
|
+
|
192
|
+
|
193
|
+
|
194
|
+
shared_examples "compares to a larger numeric correctly" do |instance_value, num, reverse=true|
|
195
|
+
|
196
|
+
if num.is_a?(Float)
|
197
|
+
raise( NotImplimentedError, " use \"compares to an larger float correctly\" instead" )
|
198
|
+
end
|
199
|
+
|
200
|
+
context "when compared to a larger #{num.class}" do
|
201
|
+
let(:a){ instance }
|
202
|
+
let(:b){ num }
|
203
|
+
include_examples "correct comparison", {
|
204
|
+
:== => false,
|
205
|
+
:=== => false,
|
206
|
+
:eql? => false,
|
207
|
+
:equal? => false,
|
208
|
+
:<=> => -1,
|
209
|
+
:> => false,
|
210
|
+
:< => true,
|
211
|
+
:>= => false,
|
212
|
+
:<= => true
|
213
|
+
}
|
214
|
+
end
|
215
|
+
|
216
|
+
if reverse
|
217
|
+
context "when an equal #{num.class} is compared to it" do
|
218
|
+
let(:a){ num }
|
219
|
+
let(:b){ instance }
|
220
|
+
include_examples "correct comparison", {
|
221
|
+
:== => false,
|
222
|
+
:=== => false,
|
223
|
+
:eql? => false,
|
224
|
+
:equal? => false,
|
225
|
+
:<=> => 1,
|
226
|
+
:> => true,
|
227
|
+
:< => false,
|
228
|
+
:>= => true,
|
229
|
+
:<= => false
|
230
|
+
}
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
end
|
235
|
+
|
236
|
+
|
237
|
+
|
238
|
+
shared_examples "compares to an equal float correctly" do |instance_value, num, reverse=true|
|
239
|
+
|
240
|
+
f = num.to_f
|
241
|
+
|
242
|
+
rounding_error = ( f <=> num )
|
243
|
+
|
244
|
+
context "when compared to an equal #{f.class}" do
|
245
|
+
let(:a){ instance }
|
246
|
+
let(:b){ f }
|
247
|
+
include_examples "correct comparison", {
|
248
|
+
:== => rounding_error.zero?,
|
249
|
+
:=== => rounding_error.zero?,
|
250
|
+
:eql? => false,
|
251
|
+
:equal? => false,
|
252
|
+
:<=> => -rounding_error,
|
253
|
+
:> => rounding_error.negative?,
|
254
|
+
:< => rounding_error.positive?,
|
255
|
+
:>= => ( rounding_error.zero? or rounding_error.negative? ),
|
256
|
+
:<= => ( rounding_error.zero? or rounding_error.positive? )
|
257
|
+
}
|
258
|
+
end
|
259
|
+
|
260
|
+
if reverse
|
261
|
+
context "when an equal #{f.class} is compared to it" do
|
262
|
+
let(:a){ f }
|
263
|
+
let(:b){ instance }
|
264
|
+
include_examples "correct comparison", {
|
265
|
+
:== => rounding_error.zero?,
|
266
|
+
:=== => rounding_error.zero?,
|
267
|
+
:eql? => false,
|
268
|
+
:equal? => false,
|
269
|
+
:<=> => rounding_error,
|
270
|
+
:> => rounding_error.positive?,
|
271
|
+
:< => rounding_error.negative?,
|
272
|
+
:>= => ( rounding_error.zero? or rounding_error.positive? ),
|
273
|
+
:<= => ( rounding_error.zero? or rounding_error.negative? )
|
274
|
+
}
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
278
|
+
end
|
279
|
+
|
280
|
+
|
281
|
+
|
282
|
+
shared_examples "compares to a larger float correctly" do |instance_value, num, reverse=true|
|
283
|
+
|
284
|
+
f = num.to_f
|
285
|
+
|
286
|
+
rounding_error = ( f <=> num )
|
287
|
+
|
288
|
+
rounding_error_collision = ( f <=> instance_value )
|
289
|
+
|
290
|
+
context "when compared to a larger #{f.class}" do
|
291
|
+
let(:a){ instance }
|
292
|
+
let(:b){ f }
|
293
|
+
include_examples "correct comparison", {
|
294
|
+
:== => rounding_error_collision.zero?,
|
295
|
+
:=== => rounding_error_collision.zero?,
|
296
|
+
:eql? => false,
|
297
|
+
:equal? => false,
|
298
|
+
:<=> => -rounding_error_collision,
|
299
|
+
:> => rounding_error_collision.negative?,
|
300
|
+
:< => rounding_error_collision.positive?,
|
301
|
+
:>= => ( rounding_error_collision.zero? or rounding_error_collision.positive? ),
|
302
|
+
:<= => ( rounding_error_collision.zero? or rounding_error_collision.negative? )
|
303
|
+
}
|
304
|
+
end
|
305
|
+
|
306
|
+
if reverse
|
307
|
+
context "when a larger #{f.class} is compared to it" do
|
308
|
+
let(:a){ f }
|
309
|
+
let(:b){ instance }
|
310
|
+
include_examples "correct comparison", {
|
311
|
+
:== => rounding_error_collision.zero?,
|
312
|
+
:=== => rounding_error_collision.zero?,
|
313
|
+
:eql? => false,
|
314
|
+
:equal? => false,
|
315
|
+
:<=> => rounding_error_collision,
|
316
|
+
:> => rounding_error_collision.positive?,
|
317
|
+
:< => rounding_error_collision.negative?,
|
318
|
+
:>= => ( rounding_error_collision.zero? or rounding_error_collision.negative? ),
|
319
|
+
:<= => ( rounding_error_collision.zero? or rounding_error_collision.positive? )
|
320
|
+
}
|
321
|
+
end
|
322
|
+
end
|
323
|
+
|
324
|
+
end
|
325
|
+
|
326
|
+
|
327
|
+
|
328
|
+
shared_examples "correctly reports positive, negative, and zero" do |value|
|
329
|
+
|
330
|
+
describe "#positive?" do
|
331
|
+
let(:v){ instance.positive? }
|
332
|
+
it "returns a boolean" do
|
333
|
+
expect(v).to be(true).or be(false)
|
334
|
+
end
|
335
|
+
expected_value = ( value.positive? )
|
336
|
+
it "returns #{expected_value.inspect}" do
|
337
|
+
expect(v).to be(expected_value)
|
338
|
+
end
|
339
|
+
end
|
340
|
+
|
341
|
+
describe "#negative?" do
|
342
|
+
let(:v){ instance.negative? }
|
343
|
+
it "returns a boolean" do
|
344
|
+
expect(v).to be(true).or be(false)
|
345
|
+
end
|
346
|
+
expected_value = ( value.negative? )
|
347
|
+
it "returns #{expected_value.inspect}" do
|
348
|
+
expect(v).to be(expected_value)
|
349
|
+
end
|
350
|
+
end
|
351
|
+
|
352
|
+
describe "#zero?" do
|
353
|
+
let(:v){ instance.zero? }
|
354
|
+
it "returns a boolean" do
|
355
|
+
expect(v).to be(true).or be(false)
|
356
|
+
end
|
357
|
+
expected_value = ( value.zero? )
|
358
|
+
it "returns #{expected_value.inspect}" do
|
359
|
+
expect(v).to be(expected_value)
|
360
|
+
end
|
361
|
+
end
|
362
|
+
|
363
|
+
end
|
metadata
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: bytesize
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Adam Hunt
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-04-08 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.16'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.16'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.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: ByteSize is a simple Ruby object that stores a size in bytes, while providing
|
56
|
+
human-readible string output with apropriate SI or IEC suffixes. Ample convenience
|
57
|
+
methods are also supplied for quick shorthand.
|
58
|
+
email: bytesize@adamhunt.name
|
59
|
+
executables: []
|
60
|
+
extensions: []
|
61
|
+
extra_rdoc_files: []
|
62
|
+
files:
|
63
|
+
- LICENSE.txt
|
64
|
+
- README.md
|
65
|
+
- lib/bytesize.rb
|
66
|
+
- lib/bytesize/activerecord.rb
|
67
|
+
- lib/bytesize/units.rb
|
68
|
+
- lib/bytesize/version.rb
|
69
|
+
- spec/bytesize_spec.rb
|
70
|
+
- spec/iecbytesize_spec.rb
|
71
|
+
- spec/shared_examples.rb
|
72
|
+
- spec/test_enum.rb
|
73
|
+
- spec/value_class_helper.rb
|
74
|
+
homepage: http://github.com/ajmihunt/bytesize
|
75
|
+
licenses:
|
76
|
+
- MIT
|
77
|
+
metadata: {}
|
78
|
+
post_install_message:
|
79
|
+
rdoc_options: []
|
80
|
+
require_paths:
|
81
|
+
- lib
|
82
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
83
|
+
requirements:
|
84
|
+
- - ">="
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: 2.1.0
|
87
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
88
|
+
requirements:
|
89
|
+
- - ">="
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: '0'
|
92
|
+
requirements: []
|
93
|
+
rubyforge_project:
|
94
|
+
rubygems_version: 2.7.3
|
95
|
+
signing_key:
|
96
|
+
specification_version: 4
|
97
|
+
summary: A simple Ruby object that stores a size in bytes, while providing human-readible
|
98
|
+
string output
|
99
|
+
test_files:
|
100
|
+
- spec/test_enum.rb
|
101
|
+
- spec/value_class_helper.rb
|
102
|
+
- spec/shared_examples.rb
|
103
|
+
- spec/bytesize_spec.rb
|
104
|
+
- spec/iecbytesize_spec.rb
|