bytesize 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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