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.
- checksums.yaml +4 -4
- data/Rakefile +1 -1
- data/lib/ruby-progressbar.rb +8 -3
- data/lib/ruby-progressbar/base.rb +121 -177
- data/lib/ruby-progressbar/calculators/length.rb +75 -0
- data/lib/ruby-progressbar/calculators/length_spec.rb +9 -0
- data/lib/ruby-progressbar/calculators/running_average.rb +9 -0
- data/lib/ruby-progressbar/components.rb +3 -5
- data/lib/ruby-progressbar/components/bar.rb +79 -43
- data/lib/ruby-progressbar/components/percentage.rb +29 -0
- data/lib/ruby-progressbar/components/rate.rb +34 -62
- data/lib/ruby-progressbar/components/time.rb +103 -0
- data/lib/ruby-progressbar/components/title.rb +13 -0
- data/lib/ruby-progressbar/format.rb +2 -1
- data/lib/ruby-progressbar/format/formatter.rb +27 -0
- data/lib/ruby-progressbar/format/molecule.rb +55 -37
- data/lib/ruby-progressbar/format/string.rb +36 -0
- data/lib/ruby-progressbar/output.rb +61 -0
- data/lib/ruby-progressbar/outputs/non_tty.rb +47 -0
- data/lib/ruby-progressbar/outputs/tty.rb +32 -0
- data/lib/ruby-progressbar/progress.rb +110 -0
- data/lib/ruby-progressbar/throttle.rb +25 -0
- data/lib/ruby-progressbar/time.rb +20 -17
- data/lib/ruby-progressbar/timer.rb +72 -0
- data/lib/ruby-progressbar/version.rb +2 -2
- data/spec/fixtures/benchmark.rb +21 -4
- data/spec/{lib/ruby-progressbar → ruby-progressbar}/base_spec.rb +55 -62
- data/spec/ruby-progressbar/calculators/running_average_spec.rb +19 -0
- data/spec/ruby-progressbar/components/bar_spec.rb +234 -0
- data/spec/ruby-progressbar/components/percentage_spec.rb +9 -0
- data/spec/ruby-progressbar/components/rate_spec.rb +9 -0
- data/spec/ruby-progressbar/components/throttle_spec.rb +157 -0
- data/spec/ruby-progressbar/components/time_spec.rb +308 -0
- data/spec/ruby-progressbar/components/title_spec.rb +12 -0
- data/spec/ruby-progressbar/format/formatter_spec.rb +9 -0
- data/spec/ruby-progressbar/format/molecule_spec.rb +30 -0
- data/spec/ruby-progressbar/format/string_spec.rb +9 -0
- data/spec/ruby-progressbar/output_spec.rb +7 -0
- data/spec/ruby-progressbar/outputs/non_tty_spec.rb +9 -0
- data/spec/ruby-progressbar/outputs/tty_spec.rb +9 -0
- data/spec/ruby-progressbar/progress_spec.rb +150 -0
- data/spec/ruby-progressbar/time_spec.rb +37 -0
- data/spec/ruby-progressbar/timer_spec.rb +7 -0
- data/spec/spec_helper.rb +2 -2
- data/spec/support/time.rb +3 -1
- metadata +55 -35
- data/lib/ruby-progressbar/components/elapsed_timer.rb +0 -25
- data/lib/ruby-progressbar/components/estimated_timer.rb +0 -90
- data/lib/ruby-progressbar/components/progressable.rb +0 -112
- data/lib/ruby-progressbar/components/throttle.rb +0 -21
- data/lib/ruby-progressbar/components/timer.rb +0 -69
- data/lib/ruby-progressbar/format/base.rb +0 -55
- data/lib/ruby-progressbar/formatter.rb +0 -112
- data/lib/ruby-progressbar/length_calculator.rb +0 -64
- data/lib/ruby-progressbar/running_average_calculator.rb +0 -7
- data/spec/lib/ruby-progressbar/components/bar_spec.rb +0 -210
- data/spec/lib/ruby-progressbar/components/elapsed_timer_spec.rb +0 -91
- data/spec/lib/ruby-progressbar/components/estimated_timer_spec.rb +0 -241
- data/spec/lib/ruby-progressbar/components/progressable_spec.rb +0 -47
- data/spec/lib/ruby-progressbar/components/throttle_spec.rb +0 -100
- data/spec/lib/ruby-progressbar/format/molecule_spec.rb +0 -22
- data/spec/lib/ruby-progressbar/running_average_calculator_spec.rb +0 -11
- data/spec/lib/ruby-progressbar/time_spec.rb +0 -49
@@ -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
|