progressbar 0.21.0 → 1.8.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/LICENSE.txt +19 -0
  5. data/README.md +38 -0
  6. data/Rakefile +2 -14
  7. data/lib/progressbar.rb +14 -284
  8. data/lib/ruby-progressbar/base.rb +161 -0
  9. data/lib/ruby-progressbar/calculators/length.rb +88 -0
  10. data/lib/ruby-progressbar/calculators/length_spec.rb +9 -0
  11. data/lib/ruby-progressbar/calculators/running_average.rb +9 -0
  12. data/lib/ruby-progressbar/components.rb +5 -0
  13. data/lib/ruby-progressbar/components/bar.rb +96 -0
  14. data/lib/ruby-progressbar/components/percentage.rb +29 -0
  15. data/lib/ruby-progressbar/components/rate.rb +43 -0
  16. data/lib/ruby-progressbar/components/time.rb +103 -0
  17. data/lib/ruby-progressbar/components/title.rb +13 -0
  18. data/lib/ruby-progressbar/errors/invalid_progress_error.rb +4 -0
  19. data/lib/ruby-progressbar/format.rb +3 -0
  20. data/lib/ruby-progressbar/format/formatter.rb +27 -0
  21. data/lib/ruby-progressbar/format/molecule.rb +58 -0
  22. data/lib/ruby-progressbar/format/string.rb +36 -0
  23. data/lib/ruby-progressbar/output.rb +61 -0
  24. data/lib/ruby-progressbar/outputs/non_tty.rb +47 -0
  25. data/lib/ruby-progressbar/outputs/tty.rb +32 -0
  26. data/lib/ruby-progressbar/progress.rb +114 -0
  27. data/lib/ruby-progressbar/throttle.rb +25 -0
  28. data/lib/ruby-progressbar/time.rb +30 -0
  29. data/lib/ruby-progressbar/timer.rb +72 -0
  30. data/lib/ruby-progressbar/version.rb +3 -0
  31. data/spec/fixtures/benchmark.rb +28 -0
  32. data/spec/ruby-progressbar/base_spec.rb +949 -0
  33. data/spec/ruby-progressbar/calculators/length_calculator_spec.rb +17 -0
  34. data/spec/ruby-progressbar/calculators/running_average_spec.rb +19 -0
  35. data/spec/ruby-progressbar/components/bar_spec.rb +234 -0
  36. data/spec/ruby-progressbar/components/percentage_spec.rb +9 -0
  37. data/spec/ruby-progressbar/components/rate_spec.rb +9 -0
  38. data/spec/ruby-progressbar/components/throttle_spec.rb +157 -0
  39. data/spec/ruby-progressbar/components/time_spec.rb +307 -0
  40. data/spec/ruby-progressbar/components/title_spec.rb +12 -0
  41. data/spec/ruby-progressbar/format/formatter_spec.rb +9 -0
  42. data/spec/ruby-progressbar/format/molecule_spec.rb +30 -0
  43. data/spec/ruby-progressbar/format/string_spec.rb +9 -0
  44. data/spec/ruby-progressbar/output_spec.rb +7 -0
  45. data/spec/ruby-progressbar/outputs/non_tty_spec.rb +9 -0
  46. data/spec/ruby-progressbar/outputs/tty_spec.rb +9 -0
  47. data/spec/ruby-progressbar/progress_spec.rb +156 -0
  48. data/spec/ruby-progressbar/time_spec.rb +45 -0
  49. data/spec/ruby-progressbar/timer_spec.rb +7 -0
  50. data/spec/spec_helper.rb +6 -0
  51. data/spec/support/time.rb +17 -0
  52. metadata +134 -69
  53. metadata.gz.sig +3 -0
  54. data/.gitignore +0 -23
  55. data/.ruby-version +0 -1
  56. data/.travis.yml +0 -6
  57. data/ChangeLog +0 -113
  58. data/Gemfile +0 -4
  59. data/Gemfile.lock +0 -27
  60. data/LICENSE +0 -1
  61. data/README.rdoc +0 -116
  62. data/progressbar.gemspec +0 -29
  63. data/test/test.rb +0 -125
@@ -0,0 +1,307 @@
1
+ require 'rspectacular'
2
+ require 'ruby-progressbar/components/time'
3
+
4
+ class ProgressBar
5
+ module Components
6
+ RSpec.describe Time do
7
+ let(:timer) { Timer.new(:time => ::Time) }
8
+
9
+ it 'displays an unknown estimated time remaining when the timer has been started ' \
10
+ 'but no progress has been made' do
11
+
12
+ progress = Progress.new(:total => 100)
13
+ time = Time.new(:timer => timer,
14
+ :progress => progress)
15
+
16
+ timer.start
17
+
18
+ expect(time.estimated_with_label).to eql ' ETA: ??:??:??'
19
+ end
20
+
21
+ it 'does not display unknown time remaining when the timer has been started and ' \
22
+ 'it is incremented' do
23
+
24
+ progress = Progress.new(:total => 100)
25
+ time = Time.new(:timer => timer,
26
+ :progress => progress)
27
+
28
+ timer.start
29
+ progress.increment
30
+
31
+ expect(time.estimated_with_label).to eql ' ETA: 00:00:00'
32
+ end
33
+
34
+ it 'displays unsmoothed time remaining when progress has been made' do
35
+ progress = Progress.new(:total => 100, :smoothing => 0.0)
36
+ time = Time.new(:timer => timer,
37
+ :progress => progress)
38
+
39
+ Timecop.freeze(-13_332)
40
+
41
+ timer.start
42
+ 50.times { progress.increment }
43
+
44
+ Timecop.return
45
+
46
+ expect(time.estimated_with_label).to eql ' ETA: 03:42:12'
47
+ end
48
+
49
+ it 'displays unknown time remaining when progress has been made and then progress ' \
50
+ 'is reset' do
51
+
52
+ progress = Progress.new(:total => 100)
53
+ time = Time.new(:timer => timer,
54
+ :progress => progress)
55
+
56
+ Timecop.freeze(-13_332)
57
+
58
+ timer.start
59
+ 50.times { progress.increment }
60
+
61
+ Timecop.return
62
+
63
+ progress.reset
64
+
65
+ expect(time.estimated_with_label).to eql ' ETA: ??:??:??'
66
+ end
67
+
68
+ it 'displays unsmoothed time remaining when progress has been made even after the ' \
69
+ 'bar is decremented' do
70
+
71
+ progress = Progress.new(:total => 100, :smoothing => 0.0)
72
+ time = Time.new(:timer => timer,
73
+ :progress => progress)
74
+
75
+ Timecop.freeze(-13_332)
76
+
77
+ timer.start
78
+ 50.times { progress.increment }
79
+
80
+ Timecop.return
81
+
82
+ 20.times { progress.decrement }
83
+
84
+ expect(time.estimated_with_label).to eql ' ETA: 08:38:28'
85
+ end
86
+
87
+ it 'displays estimated time of "> 4 Days" when estimated time is out of bounds ' \
88
+ 'and the out of bounds format is set to "friendly"' do
89
+
90
+ progress = Progress.new(:total => 100, :smoothing => 0.0)
91
+ time = Time.new(:out_of_bounds_time_format => :friendly,
92
+ :timer => timer,
93
+ :progress => progress)
94
+
95
+ Timecop.freeze(-120_000)
96
+
97
+ timer.start
98
+ 25.times { progress.increment }
99
+
100
+ Timecop.return
101
+
102
+ expect(time.estimated_with_label).to eql ' ETA: > 4 Days'
103
+ end
104
+
105
+ it 'displays estimated time of "??:??:??" when estimated time is out of bounds ' \
106
+ 'and the out of bounds format is set to "unknown"' do
107
+
108
+ progress = Progress.new(:total => 100, :smoothing => 0.0)
109
+ time = Time.new(:out_of_bounds_time_format => :unknown,
110
+ :timer => timer,
111
+ :progress => progress)
112
+
113
+ Timecop.freeze(-120_000)
114
+
115
+ timer.start
116
+ 25.times { progress.increment }
117
+
118
+ Timecop.return
119
+
120
+ expect(time.estimated_with_label).to eql ' ETA: ??:??:??'
121
+ end
122
+
123
+ it 'displays actual estimated time when estimated time is out of bounds and the ' \
124
+ 'out of bounds format is unset' do
125
+
126
+ progress = Progress.new(:total => 100, :smoothing => 0.0)
127
+ time = Time.new(:out_of_bounds_time_format => nil,
128
+ :timer => timer,
129
+ :progress => progress)
130
+
131
+ Timecop.freeze(-120_000)
132
+
133
+ timer.start
134
+ 25.times { progress.increment }
135
+
136
+ Timecop.return
137
+
138
+ expect(time.estimated_with_label).to eql ' ETA: 100:00:00'
139
+ end
140
+
141
+ it 'displays smoothed estimated time properly even when taking decrements into ' \
142
+ 'account' do
143
+
144
+ progress = Progress.new(:total => 100, :smoothing => 0.5)
145
+ time = Time.new(:timer => timer,
146
+ :progress => progress)
147
+
148
+ Timecop.freeze(-13_332)
149
+
150
+ timer.start
151
+ 50.times { progress.increment }
152
+
153
+ Timecop.return
154
+
155
+ 20.times { progress.decrement }
156
+
157
+ expect(time.estimated_with_label).to eql ' ETA: 08:14:34'
158
+ end
159
+
160
+ it 'displays smoothed unknown estimated time when reset is called after progress ' \
161
+ 'is made' do
162
+
163
+ progress = Progress.new(:total => 100, :smoothing => 0.5)
164
+ time = Time.new(:timer => timer,
165
+ :progress => progress)
166
+
167
+ Timecop.freeze(-13_332)
168
+
169
+ timer.start
170
+ 50.times { progress.increment }
171
+
172
+ Timecop.return
173
+
174
+ progress.reset
175
+
176
+ expect(time.estimated_with_label).to eql ' ETA: ??:??:??'
177
+ end
178
+
179
+ it 'displays smoothed estimated time after progress has been made' do
180
+ progress = Progress.new(:total => 100, :smoothing => 0.5)
181
+ time = Time.new(:timer => timer,
182
+ :progress => progress)
183
+
184
+ Timecop.freeze(-13_332)
185
+
186
+ timer.start
187
+ 50.times { progress.increment }
188
+
189
+ Timecop.return
190
+
191
+ expect(time.estimated_with_label).to eql ' ETA: 03:51:16'
192
+ end
193
+
194
+ it 'displays the estimated time remaining properly even for progress increments ' \
195
+ 'very short intervals' do
196
+
197
+ progress = Progress.new(:total => 10, :smoothing => 0.1)
198
+ time = Time.new(:timer => timer,
199
+ :progress => progress)
200
+
201
+ estimated_time_results = []
202
+ now = ::Time.now
203
+
204
+ Timecop.freeze(now)
205
+
206
+ timer.start
207
+
208
+ 10.times do
209
+ Timecop.freeze(now += 0.5)
210
+ progress.increment
211
+
212
+ estimated_time_results << time.estimated_with_label
213
+ end
214
+
215
+ Timecop.return
216
+
217
+ expect(estimated_time_results).to eql(
218
+ [
219
+ ' ETA: 00:00:05',
220
+ ' ETA: 00:00:04',
221
+ ' ETA: 00:00:04',
222
+ ' ETA: 00:00:03',
223
+ ' ETA: 00:00:03',
224
+ ' ETA: 00:00:02',
225
+ ' ETA: 00:00:02',
226
+ ' ETA: 00:00:01',
227
+ ' ETA: 00:00:01',
228
+ ' ETA: 00:00:00',
229
+ ]
230
+ )
231
+ end
232
+
233
+ it 'displays unknown elapsed time when the timer has not been started' do
234
+ progress = Progress.new
235
+ time = Time.new(:timer => timer,
236
+ :progress => progress)
237
+
238
+ expect(time.elapsed_with_label).to eql 'Time: --:--:--'
239
+ end
240
+
241
+ it 'displays elapsed time when the timer has just been started' do
242
+ progress = Progress.new
243
+ time = Time.new(:timer => timer,
244
+ :progress => progress)
245
+
246
+ timer.start
247
+
248
+ expect(time.elapsed_with_label).to eql 'Time: 00:00:00'
249
+ end
250
+
251
+ it 'displays elapsed time if it was previously started' do
252
+ progress = Progress.new
253
+ time = Time.new(:timer => timer,
254
+ :progress => progress)
255
+
256
+ Timecop.freeze(-16_093)
257
+
258
+ timer.start
259
+
260
+ Timecop.return
261
+
262
+ expect(time.elapsed_with_label).to eql 'Time: 04:28:13'
263
+ end
264
+
265
+ it 'displays elapsed time frozen to a specific time if it was previously stopped' do
266
+ progress = Progress.new
267
+ time = Time.new(:timer => timer,
268
+ :progress => progress)
269
+
270
+ Timecop.freeze(-16_093)
271
+
272
+ timer.start
273
+
274
+ Timecop.return
275
+ Timecop.freeze(-32)
276
+
277
+ timer.stop
278
+
279
+ Timecop.return
280
+
281
+ expect(time.elapsed_with_label).to eql 'Time: 04:27:41'
282
+ end
283
+
284
+ it 'displays unknown elapsed time after reset has been called' do
285
+ progress = Progress.new
286
+ time = Time.new(:timer => timer,
287
+ :progress => progress)
288
+
289
+ Timecop.freeze(-16_093)
290
+
291
+ timer.start
292
+
293
+ Timecop.return
294
+
295
+ timer.reset
296
+
297
+ expect(time.elapsed_with_label).to eql 'Time: --:--:--'
298
+ end
299
+
300
+ it 'raises an exception when an invalid out of bounds time format is specified' do
301
+ expect { Time.new(:out_of_bounds_time_format => :foo) }.
302
+ to raise_error 'Invalid Out Of Bounds time format. Valid formats are ' \
303
+ '[:unknown, :friendly, nil]'
304
+ end
305
+ end
306
+ end
307
+ end
@@ -0,0 +1,12 @@
1
+ require 'rspectacular'
2
+ require 'ruby-progressbar/components/title'
3
+
4
+ class ProgressBar
5
+ module Components
6
+ RSpec.describe Title do
7
+ it 'can use the default title if none is specified' do
8
+ expect(Title.new.title).to eql Title::DEFAULT_TITLE
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,9 @@
1
+ require 'rspectacular'
2
+ require 'ruby-progressbar/format/formatter'
3
+
4
+ class ProgressBar
5
+ module Format
6
+ RSpec.describe Formatter do
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,30 @@
1
+ require 'rspectacular'
2
+ require 'ruby-progressbar/format/molecule'
3
+
4
+ class ProgressBar
5
+ module Format
6
+ RSpec.describe Molecule do
7
+ it 'sets the key when initialized' do
8
+ molecule = Molecule.new('t')
9
+
10
+ expect(molecule.key).to eql 't'
11
+ end
12
+
13
+ it 'sets the method name when initialized' do
14
+ molecule = Molecule.new('t')
15
+
16
+ expect(molecule.method_name).to eql [:title_comp, :title]
17
+ end
18
+
19
+ it 'can retrieve the full key for itself' do
20
+ molecule = Molecule.new('t')
21
+
22
+ expect(molecule.full_key).to eql '%t'
23
+ end
24
+
25
+ it 'can determine if it is a bar molecule' do
26
+ expect(Molecule.new('B')).to be_bar_molecule
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,9 @@
1
+ require 'rspectacular'
2
+ require 'ruby-progressbar/format/string'
3
+
4
+ class ProgressBar
5
+ module Format
6
+ RSpec.describe String do
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,7 @@
1
+ require 'rspectacular'
2
+ require 'ruby-progressbar/output'
3
+
4
+ class ProgressBar
5
+ RSpec.describe Output do
6
+ end
7
+ end
@@ -0,0 +1,9 @@
1
+ require 'rspectacular'
2
+ require 'ruby-progressbar/outputs/non_tty'
3
+
4
+ class ProgressBar
5
+ module Outputs
6
+ RSpec.describe NonTty do
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ require 'rspectacular'
2
+ require 'ruby-progressbar/outputs/tty'
3
+
4
+ class ProgressBar
5
+ module Outputs
6
+ RSpec.describe Tty do
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,156 @@
1
+ require 'rspectacular'
2
+ require 'ruby-progressbar/progress'
3
+
4
+ class ProgressBar
5
+ RSpec.describe Progress do
6
+ it 'knows the default total when no parameters are passed' do
7
+ progress = Progress.new
8
+
9
+ expect(progress.total).to eql Progress::DEFAULT_TOTAL
10
+ end
11
+
12
+ it 'knows the default beginning progress when no parameters are passed and ' \
13
+ 'the progress has not been started' do
14
+
15
+ progress = Progress.new
16
+
17
+ expect(progress.progress).to be_zero
18
+ end
19
+
20
+ it 'knows the default starting value when no parameters are passed and the ' \
21
+ 'progress has been started' do
22
+
23
+ progress = Progress.new
24
+
25
+ progress.start
26
+
27
+ expect(progress.progress).to eql Progress::DEFAULT_BEGINNING_POSITION
28
+ end
29
+
30
+ it 'knows the given starting value when no parameters are passed and the ' \
31
+ 'progress is started with a starting value' do
32
+
33
+ progress = Progress.new
34
+
35
+ progress.start :at => 10
36
+
37
+ expect(progress.progress).to eql 10
38
+ end
39
+
40
+ it 'knows how to finish itself even if the total is unknown' do
41
+ progress = Progress.new :total => nil
42
+
43
+ expect(progress.finish).to be_nil
44
+ end
45
+
46
+ it 'knows the overridden total when the total is passed in' do
47
+ progress = Progress.new(:total => 12,
48
+ :progress_mark => 'x',
49
+ :remainder_mark => '.')
50
+
51
+ expect(progress.total).to eql 12
52
+ end
53
+
54
+ it 'knows the percentage completed when begun with no progress' do
55
+ progress = Progress.new
56
+
57
+ progress.start
58
+
59
+ expect(progress.percentage_completed).to eql 0
60
+ end
61
+
62
+ it 'knows the progress after it has been incremented' do
63
+ progress = Progress.new
64
+
65
+ progress.start
66
+ progress.increment
67
+
68
+ expect(progress.progress).to eql 1
69
+ end
70
+
71
+ it 'knows the percentage completed after it has been incremented' do
72
+ progress = Progress.new(:total => 50)
73
+
74
+ progress.start
75
+ progress.increment
76
+
77
+ expect(progress.percentage_completed).to eql 2
78
+ end
79
+
80
+ it 'knows to always round down the percentage completed' do
81
+ progress = Progress.new(:total => 200)
82
+
83
+ progress.start :at => 1
84
+
85
+ expect(progress.percentage_completed).to eql 0
86
+ end
87
+
88
+ it 'cannot increment past the total' do
89
+ progress = Progress.new(:total => 50)
90
+
91
+ progress.start :at => 50
92
+ progress.increment
93
+
94
+ expect(progress.progress).to eql 50
95
+ expect(progress.percentage_completed).to eql 100
96
+ end
97
+
98
+ it 'allow progress to be decremented once it is finished' do
99
+ progress = Progress.new(:total => 50)
100
+
101
+ progress.start :at => 50
102
+ progress.decrement
103
+
104
+ expect(progress.progress).to eql 49
105
+ expect(progress.percentage_completed).to eql 98
106
+ end
107
+
108
+ it 'knows the running average even when progress has been made' do
109
+ progress = Progress.new(:total => 50)
110
+
111
+ progress.running_average = 10
112
+ progress.start :at => 0
113
+
114
+ expect(progress.running_average).to be_zero
115
+
116
+ progress.progress += 40
117
+
118
+ expect(progress.running_average).to eql 36.0
119
+ end
120
+
121
+ it 'knows the running average is reset even after progress is started' do
122
+ progress = Progress.new(:total => 50)
123
+
124
+ progress.running_average = 10
125
+ progress.start :at => 0
126
+
127
+ expect(progress.running_average).to be_zero
128
+
129
+ progress.start :at => 40
130
+
131
+ expect(progress.running_average).to eql 0.0
132
+ end
133
+
134
+ it 'allows the default smoothing to be overridden' do
135
+ expect(Progress.new(:smoothing => 0.3).smoothing).to eql 0.3
136
+ end
137
+
138
+ it 'has a default smoothing value' do
139
+ expect(Progress.new.smoothing).to eql 0.1
140
+ end
141
+
142
+ it 'knows the percentage completed is 100% if the total is zero' do
143
+ progress = Progress.new(:total => 0)
144
+
145
+ expect(progress.percentage_completed).to eql 100
146
+ end
147
+
148
+ it 'raises an error when passed a number larger than the total' do
149
+ progress = Progress.new(:total => 100)
150
+
151
+ expect { progress.progress = 101 }.to \
152
+ raise_error(InvalidProgressError,
153
+ "You can't set the item's current value to be greater than the total.")
154
+ end
155
+ end
156
+ end