ruby-progressbar 1.6.1 → 1.7.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.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +1 -1
  3. data/lib/ruby-progressbar.rb +8 -3
  4. data/lib/ruby-progressbar/base.rb +121 -177
  5. data/lib/ruby-progressbar/calculators/length.rb +75 -0
  6. data/lib/ruby-progressbar/calculators/length_spec.rb +9 -0
  7. data/lib/ruby-progressbar/calculators/running_average.rb +9 -0
  8. data/lib/ruby-progressbar/components.rb +3 -5
  9. data/lib/ruby-progressbar/components/bar.rb +79 -43
  10. data/lib/ruby-progressbar/components/percentage.rb +29 -0
  11. data/lib/ruby-progressbar/components/rate.rb +34 -62
  12. data/lib/ruby-progressbar/components/time.rb +103 -0
  13. data/lib/ruby-progressbar/components/title.rb +13 -0
  14. data/lib/ruby-progressbar/format.rb +2 -1
  15. data/lib/ruby-progressbar/format/formatter.rb +27 -0
  16. data/lib/ruby-progressbar/format/molecule.rb +55 -37
  17. data/lib/ruby-progressbar/format/string.rb +36 -0
  18. data/lib/ruby-progressbar/output.rb +61 -0
  19. data/lib/ruby-progressbar/outputs/non_tty.rb +47 -0
  20. data/lib/ruby-progressbar/outputs/tty.rb +32 -0
  21. data/lib/ruby-progressbar/progress.rb +110 -0
  22. data/lib/ruby-progressbar/throttle.rb +25 -0
  23. data/lib/ruby-progressbar/time.rb +20 -17
  24. data/lib/ruby-progressbar/timer.rb +72 -0
  25. data/lib/ruby-progressbar/version.rb +2 -2
  26. data/spec/fixtures/benchmark.rb +21 -4
  27. data/spec/{lib/ruby-progressbar → ruby-progressbar}/base_spec.rb +55 -62
  28. data/spec/ruby-progressbar/calculators/running_average_spec.rb +19 -0
  29. data/spec/ruby-progressbar/components/bar_spec.rb +234 -0
  30. data/spec/ruby-progressbar/components/percentage_spec.rb +9 -0
  31. data/spec/ruby-progressbar/components/rate_spec.rb +9 -0
  32. data/spec/ruby-progressbar/components/throttle_spec.rb +157 -0
  33. data/spec/ruby-progressbar/components/time_spec.rb +308 -0
  34. data/spec/ruby-progressbar/components/title_spec.rb +12 -0
  35. data/spec/ruby-progressbar/format/formatter_spec.rb +9 -0
  36. data/spec/ruby-progressbar/format/molecule_spec.rb +30 -0
  37. data/spec/ruby-progressbar/format/string_spec.rb +9 -0
  38. data/spec/ruby-progressbar/output_spec.rb +7 -0
  39. data/spec/ruby-progressbar/outputs/non_tty_spec.rb +9 -0
  40. data/spec/ruby-progressbar/outputs/tty_spec.rb +9 -0
  41. data/spec/ruby-progressbar/progress_spec.rb +150 -0
  42. data/spec/ruby-progressbar/time_spec.rb +37 -0
  43. data/spec/ruby-progressbar/timer_spec.rb +7 -0
  44. data/spec/spec_helper.rb +2 -2
  45. data/spec/support/time.rb +3 -1
  46. metadata +55 -35
  47. data/lib/ruby-progressbar/components/elapsed_timer.rb +0 -25
  48. data/lib/ruby-progressbar/components/estimated_timer.rb +0 -90
  49. data/lib/ruby-progressbar/components/progressable.rb +0 -112
  50. data/lib/ruby-progressbar/components/throttle.rb +0 -21
  51. data/lib/ruby-progressbar/components/timer.rb +0 -69
  52. data/lib/ruby-progressbar/format/base.rb +0 -55
  53. data/lib/ruby-progressbar/formatter.rb +0 -112
  54. data/lib/ruby-progressbar/length_calculator.rb +0 -64
  55. data/lib/ruby-progressbar/running_average_calculator.rb +0 -7
  56. data/spec/lib/ruby-progressbar/components/bar_spec.rb +0 -210
  57. data/spec/lib/ruby-progressbar/components/elapsed_timer_spec.rb +0 -91
  58. data/spec/lib/ruby-progressbar/components/estimated_timer_spec.rb +0 -241
  59. data/spec/lib/ruby-progressbar/components/progressable_spec.rb +0 -47
  60. data/spec/lib/ruby-progressbar/components/throttle_spec.rb +0 -100
  61. data/spec/lib/ruby-progressbar/format/molecule_spec.rb +0 -22
  62. data/spec/lib/ruby-progressbar/running_average_calculator_spec.rb +0 -11
  63. data/spec/lib/ruby-progressbar/time_spec.rb +0 -49
@@ -0,0 +1,9 @@
1
+ require 'rspectacular'
2
+ require 'ruby-progressbar/components/percentage'
3
+
4
+ class ProgressBar
5
+ module Components
6
+ describe Percentage do
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ require 'rspectacular'
2
+ require 'ruby-progressbar/components/rate'
3
+
4
+ class ProgressBar
5
+ module Components
6
+ describe Rate do
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,157 @@
1
+ require 'rspectacular'
2
+ require 'ruby-progressbar/progress'
3
+
4
+ class ProgressBar
5
+ describe Throttle do
6
+ let(:timer) { ProgressBar::Timer.new(:time => ::Time) }
7
+
8
+ it 'yields the first time if the throttle rate is given and the timer is not started' do
9
+ throttle = ProgressBar::Throttle.new(:throttle_rate => 10,
10
+ :throttle_timer => timer)
11
+
12
+ yielded = false
13
+
14
+ throttle.choke do
15
+ yielded = true
16
+ end
17
+
18
+ expect(yielded).to be_a TrueClass
19
+ end
20
+
21
+ it 'does not yield after the initial yield if the period has not passed yet' do
22
+ throttle = ProgressBar::Throttle.new(:throttle_rate => 10,
23
+ :throttle_timer => timer)
24
+ timer.start
25
+
26
+ throttle.choke {}
27
+
28
+ yielded = false
29
+
30
+ (1..9).each do
31
+ Timecop.freeze(1)
32
+
33
+ throttle.choke do
34
+ yielded = true
35
+ end
36
+ end
37
+
38
+ Timecop.return
39
+
40
+ expect(yielded).to be_a FalseClass
41
+ end
42
+
43
+ it 'always yields if forced to, even after the initial yield or if the period ' \
44
+ 'has not passed' do
45
+
46
+ throttle = ProgressBar::Throttle.new(:throttle_rate => 10,
47
+ :throttle_timer => timer)
48
+ timer.start
49
+
50
+ throttle.choke {}
51
+
52
+ yielded = 0
53
+
54
+ (1..25).each do
55
+ Timecop.freeze(1)
56
+
57
+ throttle.choke(:force_update_if => true) do
58
+ yielded += 1
59
+ end
60
+ end
61
+
62
+ Timecop.return
63
+
64
+ expect(yielded).to eql 25
65
+ end
66
+
67
+ it 'yields if the period has passed, even after the initial yield' do
68
+ throttle = ProgressBar::Throttle.new(:throttle_rate => 10,
69
+ :throttle_timer => timer)
70
+ timer.start
71
+
72
+ throttle.choke {}
73
+
74
+ yielded = false
75
+
76
+ Timecop.freeze(11)
77
+
78
+ throttle.choke do
79
+ yielded = true
80
+ end
81
+
82
+ Timecop.return
83
+
84
+ expect(yielded).to eql true
85
+ end
86
+
87
+ it 'does not yield after a previous yield if the period has not passed yet' do
88
+ throttle = ProgressBar::Throttle.new(:throttle_rate => 10,
89
+ :throttle_timer => timer)
90
+
91
+ Timecop.freeze(0)
92
+
93
+ timer.start
94
+
95
+ Timecop.freeze(15)
96
+
97
+ throttle.choke {}
98
+
99
+ yielded = false
100
+
101
+ (16..24).each do
102
+ Timecop.freeze(1)
103
+
104
+ throttle.choke do
105
+ yielded = true
106
+ end
107
+
108
+ expect(yielded).to eql false
109
+ end
110
+
111
+ Timecop.return
112
+ end
113
+
114
+ it 'yields after the period has passed, even after a previous yield' do
115
+ throttle = ProgressBar::Throttle.new(:throttle_rate => 10,
116
+ :throttle_timer => timer)
117
+
118
+ Timecop.freeze(0)
119
+
120
+ timer.start
121
+
122
+ Timecop.freeze(15)
123
+
124
+ throttle.choke {}
125
+
126
+ yielded = false
127
+
128
+ Timecop.freeze(10)
129
+
130
+ throttle.choke do
131
+ yielded = true
132
+ end
133
+
134
+ Timecop.return
135
+
136
+ expect(yielded).to eql true
137
+ end
138
+
139
+ it 'does not throttle if no throttle rate is given' do
140
+ throttle = Throttle.new(:throttle_timer => timer,
141
+ :throttle_rate => nil)
142
+ yield_count = 0
143
+
144
+ (1..25).each do
145
+ Timecop.freeze(1)
146
+
147
+ throttle.choke do
148
+ yield_count += 1
149
+ end
150
+ end
151
+
152
+ Timecop.return
153
+
154
+ expect(yield_count).to eql 25
155
+ end
156
+ end
157
+ end
@@ -0,0 +1,308 @@
1
+ require 'rspectacular'
2
+ require 'ruby-progressbar/components/time'
3
+
4
+ class ProgressBar
5
+ module Components
6
+ 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
+ (1..10).each 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
+ end
231
+
232
+ it 'displays unknown elapsed time when the timer has not been started' do
233
+ progress = Progress.new
234
+ time = Time.new(:timer => timer,
235
+ :progress => progress)
236
+
237
+ expect(time.elapsed_with_label).to eql 'Time: --:--:--'
238
+ end
239
+
240
+ it 'displays elapsed time when the timer has just been started' do
241
+ progress = Progress.new
242
+ time = Time.new(:timer => timer,
243
+ :progress => progress)
244
+
245
+ timer.start
246
+
247
+ expect(time.elapsed_with_label).to eql 'Time: 00:00:00'
248
+ end
249
+
250
+ it 'displays elapsed time if it was previously started' do
251
+ progress = Progress.new
252
+ time = Time.new(:timer => timer,
253
+ :progress => progress)
254
+
255
+ Timecop.freeze(-16_093)
256
+
257
+ timer.start
258
+
259
+ Timecop.return
260
+
261
+ expect(time.elapsed_with_label).to eql 'Time: 04:28:13'
262
+ end
263
+
264
+ it 'displays elapsed time frozen to a specific time if it was previously stopped' do
265
+ progress = Progress.new
266
+ time = Time.new(:timer => timer,
267
+ :progress => progress)
268
+
269
+ Timecop.freeze(-16_093)
270
+
271
+ timer.start
272
+
273
+ Timecop.return
274
+ Timecop.freeze(-32)
275
+
276
+ timer.stop
277
+
278
+ Timecop.return
279
+
280
+ expect(time.elapsed_with_label).to eql 'Time: 04:27:41'
281
+ end
282
+
283
+ it 'displays unknown elapsed time after reset has been called' do
284
+ progress = Progress.new
285
+ time = Time.new(:timer => timer,
286
+ :progress => progress)
287
+
288
+ Timecop.freeze(-16_093)
289
+
290
+ timer.start
291
+
292
+ Timecop.return
293
+
294
+ timer.reset
295
+
296
+ expect(time.elapsed_with_label).to eql 'Time: --:--:--'
297
+ end
298
+
299
+ it 'raises an exception when an invalid out of bounds time format is specified' do
300
+ expect do
301
+ Time.new(:out_of_bounds_time_format => :foo)
302
+ end.
303
+ to raise_error 'Invalid Out Of Bounds time format. Valid formats are ' \
304
+ '[:unknown, :friendly, nil]'
305
+ end
306
+ end
307
+ end
308
+ end