ruby-progressbar 1.6.1 → 1.7.0

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. 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