progressbar 1.8.2 → 1.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/README.md +5 -5
  5. data/Rakefile +0 -0
  6. data/lib/progressbar.rb +2 -0
  7. data/lib/ruby-progressbar/base.rb +24 -2
  8. data/lib/ruby-progressbar/calculators/length.rb +14 -3
  9. data/lib/ruby-progressbar/components/time.rb +6 -2
  10. data/lib/ruby-progressbar/format/formatter.rb +1 -1
  11. data/lib/ruby-progressbar/format/molecule.rb +2 -1
  12. data/lib/ruby-progressbar/output.rb +14 -7
  13. data/lib/ruby-progressbar/outputs/null.rb +33 -0
  14. data/lib/ruby-progressbar/progress.rb +4 -0
  15. data/lib/ruby-progressbar/refinements.rb +1 -0
  16. data/lib/ruby-progressbar/refinements/enumerator.rb +25 -0
  17. data/lib/ruby-progressbar/version.rb +1 -1
  18. metadata +31 -70
  19. metadata.gz.sig +0 -0
  20. data/lib/ruby-progressbar/calculators/length_spec.rb +0 -9
  21. data/spec/fixtures/benchmark.rb +0 -28
  22. data/spec/ruby-progressbar/base_spec.rb +0 -949
  23. data/spec/ruby-progressbar/calculators/length_calculator_spec.rb +0 -19
  24. data/spec/ruby-progressbar/calculators/running_average_spec.rb +0 -19
  25. data/spec/ruby-progressbar/components/bar_spec.rb +0 -234
  26. data/spec/ruby-progressbar/components/percentage_spec.rb +0 -9
  27. data/spec/ruby-progressbar/components/rate_spec.rb +0 -9
  28. data/spec/ruby-progressbar/components/throttle_spec.rb +0 -157
  29. data/spec/ruby-progressbar/components/time_spec.rb +0 -307
  30. data/spec/ruby-progressbar/components/title_spec.rb +0 -12
  31. data/spec/ruby-progressbar/format/formatter_spec.rb +0 -9
  32. data/spec/ruby-progressbar/format/molecule_spec.rb +0 -30
  33. data/spec/ruby-progressbar/format/string_spec.rb +0 -9
  34. data/spec/ruby-progressbar/output_spec.rb +0 -7
  35. data/spec/ruby-progressbar/outputs/non_tty_spec.rb +0 -9
  36. data/spec/ruby-progressbar/outputs/tty_spec.rb +0 -9
  37. data/spec/ruby-progressbar/progress_spec.rb +0 -156
  38. data/spec/ruby-progressbar/time_spec.rb +0 -45
  39. data/spec/ruby-progressbar/timer_spec.rb +0 -7
  40. data/spec/spec_helper.rb +0 -6
  41. data/spec/support/time.rb +0 -17
metadata.gz.sig CHANGED
Binary file
@@ -1,9 +0,0 @@
1
- require 'rspectacular'
2
- require 'ruby-progressbar/calculators/length'
3
-
4
- class ProgressBar
5
- module Calculators
6
- describe Length do
7
- end
8
- end
9
- end
@@ -1,28 +0,0 @@
1
- # bundle exec ruby-prof --printer=graph_html
2
- # --file=../results.html
3
- # --require 'ruby-progressbar'
4
- # --sort=total ./spec/fixtures/benchmark.rb
5
-
6
- total = 100_000
7
- # output = File.open('/Users/jfelchner/Downloads/benchmark.txt', 'w+')
8
- output = $stdout
9
-
10
- # Progressbar gem
11
- # bar = ProgressBar.new('Progress', total)
12
- #
13
- # total.times do |i|
14
- # bar.inc
15
- # end
16
- #
17
- # bar.finish
18
-
19
- # Ruby/ProgressBar
20
- bar = ProgressBar.create(:output => output,
21
- :length => 80,
22
- :start => 0,
23
- :total => total)
24
-
25
- total.times do |_i|
26
- # bar.log i
27
- bar.increment
28
- end
@@ -1,949 +0,0 @@
1
- require 'spec_helper'
2
- require 'support/time'
3
- require 'stringio'
4
-
5
- # rubocop:disable Metrics/LineLength, Style/UnneededInterpolation
6
- RSpec.describe ProgressBar::Base do
7
- let(:output) do
8
- StringIO.new('', 'w+').tap do |io|
9
- allow(io).to receive(:tty?).and_return true
10
- end
11
- end
12
-
13
- let(:non_tty_output) do
14
- StringIO.new('', 'w+').tap do |io|
15
- allow(io).to receive(:tty?).and_return false
16
- end
17
- end
18
-
19
- let(:progressbar) { ProgressBar::Base.new(:output => output, :length => 80, :throttle_rate => 0.0) }
20
-
21
- context 'when the terminal width is shorter than the string being output' do
22
- it 'can properly handle outputting the bar when the length changes on the fly to less than the minimum width' do
23
- progressbar = ProgressBar::Base.new(:output => output, :title => 'a' * 25, :format => '%t%B', :throttle_rate => 0.0)
24
-
25
- allow(progressbar.send(:output).send(:length_calculator)).to receive(:terminal_width).
26
- and_return 30
27
-
28
- progressbar.start
29
-
30
- allow(progressbar.send(:output).send(:length_calculator)).to receive(:terminal_width).
31
- and_return 20
32
-
33
- progressbar.increment
34
-
35
- output.rewind
36
- expect(output.read).to match(/\raaaaaaaaaaaaaaaaaaaaaaaaa \r\s+\raaaaaaaaaaaaaaaaaaaaaaaaa\r\z/)
37
- end
38
-
39
- context 'and the bar length is calculated' do
40
- it 'returns the proper string' do
41
- progressbar = ProgressBar::Base.new(:output => output, :title => ('*' * 21), :starting_at => 5, :total => 10, :autostart => false)
42
-
43
- allow(progressbar.send(:output).send(:length_calculator)).to receive(:terminal_width).
44
- and_return 20
45
-
46
- expect(progressbar.to_s('%t%w')).to eql '*********************'
47
- end
48
- end
49
-
50
- context 'and the incomplete bar length is calculated' do
51
- it 'returns the proper string' do
52
- progressbar = ProgressBar::Base.new(:output => output, :title => ('*' * 21), :autostart => false)
53
-
54
- allow(progressbar.send(:output).send(:length_calculator)).to receive(:terminal_width).
55
- and_return 20
56
-
57
- expect(progressbar.to_s('%t%i')).to eql '*********************'
58
- end
59
-
60
- it 'returns the proper string' do
61
- progressbar = ProgressBar::Base.new(:output => output, :title => ('*' * 21), :starting_at => 5, :total => 10, :autostart => false)
62
-
63
- allow(progressbar.send(:output).send(:length_calculator)).to receive(:terminal_width).
64
- and_return 20
65
-
66
- expect(progressbar.to_s('%t%i')).to eql '*********************'
67
- end
68
- end
69
-
70
- context 'and the full bar length is calculated (but lacks the space to output the entire bar)' do
71
- it 'returns the proper string' do
72
- progressbar = ProgressBar::Base.new(:output => output, :title => ('*' * 19), :starting_at => 5, :total => 10, :autostart => false)
73
-
74
- allow(progressbar.send(:output).send(:length_calculator)).to receive(:terminal_width).
75
- and_return 20
76
-
77
- expect(progressbar.to_s('%t%B')).to eql '******************* '
78
- end
79
-
80
- it 'returns the proper string' do
81
- progressbar = ProgressBar::Base.new(:output => output, :title => ('*' * 19), :starting_at => 5, :total => 10, :autostart => false)
82
-
83
- allow(progressbar.send(:output).send(:length_calculator)).to receive(:terminal_width).
84
- and_return 20
85
-
86
- expect(progressbar.to_s('%t%w%i')).to eql '******************* '
87
- end
88
- end
89
- end
90
-
91
- context 'when a new bar is created' do
92
- context 'and no options are passed' do
93
- let(:progressbar) { ProgressBar::Base.new }
94
-
95
- describe '#title' do
96
- it 'returns the default title' do
97
- expect(progressbar.send(:title).to_s).to eql ProgressBar::Components::Title::DEFAULT_TITLE
98
- end
99
- end
100
-
101
- describe '#output' do
102
- it 'returns the default output stream' do
103
- expect(progressbar.send(:output).send(:stream)).to eql ProgressBar::Output::DEFAULT_OUTPUT_STREAM
104
- end
105
- end
106
-
107
- describe '#length' do
108
- context 'when the RUBY_PROGRESS_BAR_LENGTH environment variable exists' do
109
- before { ENV['RUBY_PROGRESS_BAR_LENGTH'] = '44' }
110
- after { ENV['RUBY_PROGRESS_BAR_LENGTH'] = nil }
111
-
112
- it 'returns the length of the environment variable as an integer' do
113
- progressbar = ProgressBar::Base.new
114
- expect(progressbar.send(:output).send(:length_calculator).send(:length)).to eql 44
115
- end
116
- end
117
-
118
- context 'when the RUBY_PROGRESS_BAR_LENGTH environment variable does not exist' do
119
- before { ENV['RUBY_PROGRESS_BAR_LENGTH'] = nil }
120
-
121
- context 'but the length option was passed in' do
122
- it 'returns the length specified in the option' do
123
- progressbar = ProgressBar::Base.new(:length => 88)
124
- expect(progressbar.send(:output).send(:length_calculator).send(:length)).to eql 88
125
- end
126
- end
127
-
128
- context 'and no length option was passed in' do
129
- it 'returns the width of the terminal if it is a Unix environment' do
130
- allow(progressbar.send(:output).send(:length_calculator)).to receive(:terminal_width).and_return(99)
131
- progressbar.send(:output).send(:length_calculator).send(:reset_length)
132
- expect(progressbar.send(:output).send(:length_calculator).send(:length)).to eql 99
133
- end
134
-
135
- it 'returns 80 if it is not a Unix environment' do
136
- allow(progressbar.send(:output).send(:length_calculator)).to receive(:unix?).and_return(false)
137
- progressbar.send(:output).send(:length_calculator).send(:reset_length)
138
- expect(progressbar.send(:output).send(:length_calculator).send(:length)).to eql 80
139
- end
140
- end
141
- end
142
- end
143
- end
144
-
145
- context 'and options are passed' do
146
- let(:progressbar) { ProgressBar::Base.new(:title => 'We All Float', :total => 12, :output => STDOUT, :progress_mark => 'x', :length => 88, :starting_at => 5) }
147
-
148
- describe '#title' do
149
- it 'returns the overridden title' do
150
- expect(progressbar.send(:title).to_s).to eql 'We All Float'
151
- end
152
- end
153
-
154
- describe '#output' do
155
- it 'returns the overridden output stream' do
156
- expect(progressbar.send(:output).send(:stream)).to eql STDOUT
157
- end
158
- end
159
-
160
- describe '#length' do
161
- it 'returns the overridden length' do
162
- expect(progressbar.send(:output).send(:length_calculator).send(:length)).to eql 88
163
- end
164
- end
165
- end
166
-
167
- context 'if the bar was started 4 minutes ago' do
168
- before do
169
- Timecop.travel(-240) do
170
- progressbar.start
171
- end
172
- end
173
-
174
- context 'and within 2 minutes it was halfway done' do
175
- before do
176
- Timecop.travel(-120) do
177
- 50.times { progressbar.increment }
178
- end
179
- end
180
-
181
- describe '#finish' do
182
- before do
183
- Timecop.travel(-120) do
184
- progressbar.finish
185
- end
186
- end
187
-
188
- it 'completes the bar' do
189
- output.rewind
190
- expect(output.read).to match(/Progress: \|#{'=' * 68}\|\n/)
191
- end
192
-
193
- it 'shows the elapsed time instead of the estimated time since the bar is completed' do
194
- expect(progressbar.to_s('%e')).to eql 'Time: 00:02:00'
195
- end
196
-
197
- it 'calculates the elapsed time to 00:02:00' do
198
- expect(progressbar.to_s('%a')).to eql 'Time: 00:02:00'
199
- end
200
- end
201
- end
202
- end
203
-
204
- context 'which includes ANSI SGR codes in the format string' do
205
- it 'properly calculates the length of the bar by removing the long version of the ANSI codes from the calculated length' do
206
- @color_code = "\e[0m\e[32m\e[7m\e[1m"
207
- @reset_code = "\e[0m"
208
- @progress_mark = "#{@color_code} #{@reset_code}"
209
- progressbar = ProgressBar::Base.new(:format => "#{@color_code}Processing... %b%i#{@reset_code}#{@color_code} %p%%#{@reset_code}",
210
- :progress_mark => @progress_mark,
211
- :output => output,
212
- :length => 24,
213
- :starting_at => 3,
214
- :total => 6,
215
- :throttle_rate => 0.0)
216
-
217
- progressbar.increment
218
- progressbar.increment
219
-
220
- output.rewind
221
- expect(output.read).to include "#{@color_code}Processing... #{@progress_mark * 3}#{' ' * 3}#{@reset_code}#{@color_code} 50%#{@reset_code}\r#{@color_code}Processing... #{@progress_mark * 3}#{' ' * 3}#{@reset_code}#{@color_code} 66%#{@reset_code}\r#{@color_code}Processing... #{@progress_mark * 4}#{' ' * 2}#{@reset_code}#{@color_code} 83%#{@reset_code}\r"
222
- end
223
-
224
- it 'properly calculates the length of the bar by removing the short version of the ANSI codes from the calculated length' do
225
- @color_code = "\e[0;32;7;1m"
226
- @reset_code = "\e[0m"
227
- @progress_mark = "#{@color_code} #{@reset_code}"
228
- progressbar = ProgressBar::Base.new(:format => "#{@color_code}Processing... %b%i#{@reset_code}#{@color_code} %p%%#{@reset_code}",
229
- :progress_mark => @progress_mark,
230
- :output => output,
231
- :length => 24,
232
- :starting_at => 3,
233
- :total => 6,
234
- :throttle_rate => 0.0)
235
-
236
- progressbar.increment
237
- progressbar.increment
238
-
239
- output.rewind
240
- expect(output.read).to include "#{@color_code}Processing... #{@progress_mark * 3}#{' ' * 3}#{@reset_code}#{@color_code} 50%#{@reset_code}\r#{@color_code}Processing... #{@progress_mark * 3}#{' ' * 3}#{@reset_code}#{@color_code} 66%#{@reset_code}\r#{@color_code}Processing... #{@progress_mark * 4}#{' ' * 2}#{@reset_code}#{@color_code} 83%#{@reset_code}\r"
241
- end
242
- end
243
-
244
- context 'for a TTY enabled device' do
245
- it 'can log messages' do
246
- progressbar = ProgressBar::Base.new(:output => output, :length => 20, :starting_at => 3, :total => 6, :throttle_rate => 0.0)
247
- progressbar.increment
248
- progressbar.log 'We All Float'
249
- progressbar.increment
250
-
251
- output.rewind
252
- expect(output.read).to include "Progress: |==== |\rProgress: |===== |\r \rWe All Float\nProgress: |===== |\rProgress: |====== |\r"
253
- end
254
- end
255
-
256
- context 'for a non-TTY enabled device' do
257
- it 'can log messages' do
258
- progressbar = ProgressBar::Base.new(:output => non_tty_output, :length => 20, :starting_at => 4, :total => 6, :throttle_rate => 0.0)
259
- progressbar.increment
260
- progressbar.log 'We All Float'
261
- progressbar.increment
262
- progressbar.finish
263
-
264
- non_tty_output.rewind
265
- expect(non_tty_output.read).to include "We All Float\nProgress: |========|\n"
266
- end
267
-
268
- it 'can output the bar properly so that it does not spam the screen' do
269
- progressbar = ProgressBar::Base.new(:output => non_tty_output, :length => 20, :starting_at => 0, :total => 6, :throttle_rate => 0.0)
270
-
271
- 6.times { progressbar.increment }
272
-
273
- non_tty_output.rewind
274
- expect(non_tty_output.read).to eql "\n\nProgress: |========|\n"
275
- end
276
-
277
- it 'can output the bar properly if finished in the middle of its progress' do
278
- progressbar = ProgressBar::Base.new(:output => non_tty_output, :length => 20, :starting_at => 0, :total => 6, :throttle_rate => 0.0)
279
-
280
- 3.times { progressbar.increment }
281
-
282
- progressbar.finish
283
-
284
- non_tty_output.rewind
285
- expect(non_tty_output.read).to eql "\n\nProgress: |========|\n"
286
- end
287
-
288
- it 'can output the bar properly if stopped in the middle of its progress' do
289
- progressbar = ProgressBar::Base.new(:output => non_tty_output, :length => 20, :starting_at => 0, :total => 6, :throttle_rate => 0.0)
290
-
291
- 3.times { progressbar.increment }
292
-
293
- progressbar.stop
294
-
295
- non_tty_output.rewind
296
- expect(non_tty_output.read).to eql "\n\nProgress: |====\n"
297
- end
298
-
299
- it 'ignores changes to the title due to the fact that the bar length cannot change' do
300
- progressbar = ProgressBar::Base.new(:output => non_tty_output, :length => 20, :starting_at => 0, :total => 6, :throttle_rate => 0.0)
301
-
302
- 3.times { progressbar.increment }
303
-
304
- progressbar.title = 'Testing'
305
- progressbar.stop
306
-
307
- non_tty_output.rewind
308
-
309
- expect(non_tty_output.read).to eql "\n\nProgress: |====\n"
310
- end
311
-
312
- it 'allows the title to be customized when the bar is created' do
313
- progressbar = ProgressBar::Base.new(:output => non_tty_output, :title => 'Custom', :length => 20, :starting_at => 0, :total => 6, :throttle_rate => 0.0)
314
-
315
- 3.times { progressbar.increment }
316
-
317
- progressbar.stop
318
-
319
- non_tty_output.rewind
320
-
321
- expect(non_tty_output.read).to eql "\n\nCustom: |=====\n"
322
- end
323
- end
324
- end
325
-
326
- context 'when a bar is about to be completed' do
327
- let(:progressbar) { ProgressBar::Base.new(:starting_at => 5, :total => 6, :output => output, :length => 20, :throttle_rate => 0.0) }
328
-
329
- context 'and it is incremented' do
330
- before { progressbar.increment }
331
-
332
- it 'registers as being "finished"' do
333
- expect(progressbar).to be_finished
334
- end
335
-
336
- it 'prints a new line' do
337
- output.rewind
338
- expect(output.read.end_with?("\n")).to eql true
339
- end
340
-
341
- it 'does not continue to print bars if finish is subsequently called' do
342
- progressbar.finish
343
-
344
- output.rewind
345
- expect(output.read).to end_with " \rProgress: |====== |\rProgress: |========|\n"
346
- end
347
- end
348
- end
349
-
350
- context 'when a bar with autofinish=false is about to be completed' do
351
- let(:progressbar) { ProgressBar::Base.new(:autofinish => false, :starting_at => 5, :total => 6, :output => output, :length => 20, :throttle_rate => 0.0) }
352
-
353
- context 'and it is incremented' do
354
- before { progressbar.increment }
355
-
356
- it 'does not automatically finish' do
357
- expect(progressbar).not_to be_finished
358
- end
359
-
360
- it 'does not prints a new line' do
361
- output.rewind
362
-
363
- expect(output.read.end_with?("\n")).to eql false
364
- end
365
-
366
- it 'allows reset' do
367
- progressbar.finish
368
- expect(progressbar).to be_finished
369
-
370
- progressbar.reset
371
-
372
- expect(progressbar).not_to be_finished
373
- end
374
-
375
- it 'does prints a new line when manually finished' do
376
- progressbar.finish
377
- expect(progressbar).to be_finished
378
-
379
- output.rewind
380
-
381
- expect(output.read.end_with?("\n")).to eql true
382
- end
383
-
384
- it 'does not continue to print bars if finish is subsequently called' do
385
- progressbar.finish
386
-
387
- output.rewind
388
-
389
- expect(output.read).to end_with " \rProgress: |====== |\rProgress: |========|\rProgress: |========|\n"
390
- end
391
- end
392
- end
393
-
394
- context 'when a bar has an unknown amount to completion' do
395
- let(:progressbar) { ProgressBar::Base.new(:total => nil, :output => output, :length => 80, :unknown_progress_animation_steps => ['=--', '-=-', '--=']) }
396
-
397
- it 'is represented correctly' do
398
- expect(progressbar.to_s('%i')).to eql '=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=-'
399
- end
400
-
401
- it 'is represented after being incremented once' do
402
- progressbar.increment
403
- expect(progressbar.to_s('%i')).to eql '-=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--='
404
- end
405
-
406
- it 'is represented after being incremented twice' do
407
- progressbar.increment
408
- progressbar.increment
409
- expect(progressbar.to_s('%i')).to eql '--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--'
410
- end
411
-
412
- it 'displays the proper ETA' do
413
- progressbar.increment
414
-
415
- expect(progressbar.to_s('%i%e')).to eql '-=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=- ETA: ??:??:??'
416
- expect(progressbar.to_s('%i%E')).to eql '-=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=- ETA: ??:??:??'
417
- end
418
- end
419
-
420
- context 'when a bar is started' do
421
- let(:progressbar) { ProgressBar::Base.new(:starting_at => 0, :total => 100, :output => output, :length => 80, :throttle_rate => 0.0) }
422
-
423
- context 'and it is incremented any number of times' do
424
- before { 10.times { progressbar.increment } }
425
-
426
- describe '#progress_mark=' do
427
- it 'changes the mark used to represent progress and updates the output' do
428
- progressbar.progress_mark = 'x'
429
-
430
- output.rewind
431
- expect(output.read).to match(/\rProgress: \|xxxxxx#{' ' * 62}\|\r\z/)
432
- end
433
- end
434
-
435
- describe '#remainder_mark=' do
436
- it 'changes the mark used to represent the remaining part of the bar and updates the output' do
437
- progressbar.remainder_mark = 'x'
438
-
439
- output.rewind
440
- expect(output.read).to match(/\rProgress: \|======#{'x' * 62}\|\r\z/)
441
- end
442
- end
443
-
444
- describe '#title=' do
445
- it 'changes the title used to represent the items being progressed and updates the output' do
446
- progressbar.title = 'Items'
447
-
448
- output.rewind
449
- expect(output.read).to match(/\rItems: \|=======#{' ' * 64}\|\r\z/)
450
- end
451
- end
452
-
453
- describe '#reset' do
454
- before { progressbar.reset }
455
-
456
- it 'resets the bar back to the starting value' do
457
- output.rewind
458
- expect(output.read).to match(/\rProgress: \|#{' ' * 68}\|\r\z/)
459
- end
460
- end
461
-
462
- describe '#stop' do
463
- before { progressbar.stop }
464
-
465
- it 'forcibly halts the bar wherever it is and cancels it' do
466
- output.rewind
467
- expect(output.read).to match(/\rProgress: \|======#{' ' * 62}\|\n\z/)
468
- end
469
-
470
- it 'does not output the bar multiple times if the bar is already stopped' do
471
- output.rewind
472
- progressbar.stop
473
- output.rewind
474
-
475
- expect(output.read).to start_with "#{' ' * 80}"
476
- end
477
- end
478
-
479
- describe '#resume' do
480
- it 'does not output the bar multiple times' do
481
- output.rewind
482
- progressbar.resume
483
- output.rewind
484
-
485
- expect(output.read).to start_with "#{' ' * 80}"
486
- end
487
- end
488
- end
489
- end
490
-
491
- context 'when a bar is started from 10/100' do
492
- let(:progressbar) { ProgressBar::Base.new(:starting_at => 10, :total => 100, :output => output, :length => 112) }
493
-
494
- context 'and it is incremented any number of times' do
495
- before { 10.times { progressbar.increment } }
496
-
497
- describe '#reset' do
498
- before { progressbar.reset }
499
-
500
- it 'resets the bar back to the starting value' do
501
- output.rewind
502
- expect(output.read).to match(/\rProgress: \|==========#{' ' * 90}\|\r\z/)
503
- end
504
- end
505
- end
506
- end
507
-
508
- describe '#clear' do
509
- it 'clears the current terminal line and/or bar text' do
510
- progressbar.clear
511
-
512
- output.rewind
513
- expect(output.read).to match(/^#{progressbar.send(:output).send(:clear_string)}/)
514
- end
515
- end
516
-
517
- describe '#start' do
518
- it 'clears the current terminal line' do
519
- progressbar.start
520
-
521
- output.rewind
522
- expect(output.read).to match(/^#{progressbar.send(:output).send(:clear_string)}/)
523
- end
524
-
525
- it 'prints the bar for the first time' do
526
- progressbar.start
527
-
528
- output.rewind
529
- expect(output.read).to match(/Progress: \| \|\r\z/)
530
- end
531
-
532
- it 'prints correctly if passed a position to start at' do
533
- progressbar.start(:at => 20)
534
-
535
- output.rewind
536
- expect(output.read).to match(/Progress: \|============= \|\r\z/)
537
- end
538
- end
539
-
540
- context 'when the bar has not been completed' do
541
- let(:progressbar) { ProgressBar::Base.new(:length => 112, :starting_at => 0, :total => 50, :output => output, :throttle_rate => 0.0) }
542
-
543
- describe '#increment' do
544
- before { progressbar.increment }
545
-
546
- it 'displays the bar with the correct formatting' do
547
- output.rewind
548
- expect(output.read).to match(/Progress: \|== \|\r\z/)
549
- end
550
- end
551
- end
552
-
553
- context 'when a new bar is created with a specific format' do
554
- context '#format' do
555
- let(:progressbar) { ProgressBar::Base.new(:format => '%B %p%%') }
556
-
557
- context 'if called with no arguments' do
558
- before { progressbar.format = nil }
559
-
560
- it 'resets the format back to the default' do
561
- expect(progressbar.to_s).to match(/^Progress: \|\s+\|\z/)
562
- end
563
- end
564
-
565
- context 'if called with a specific format string' do
566
- before { progressbar.format = '%t' }
567
-
568
- it 'sets it as the new format for the bar' do
569
- expect(progressbar.to_s).to match(/^Progress\z/)
570
- end
571
- end
572
- end
573
-
574
- context '#to_s' do
575
- context 'when no time has elapsed' do
576
- it 'displays zero for the rate' do
577
- Timecop.freeze do
578
- progressbar = ProgressBar::Base.new(:length => 100, :starting_at => 0)
579
-
580
- expect(progressbar.to_s('%r')).to match(/^0\z/)
581
- end
582
- end
583
- end
584
-
585
- context 'when any time has elasped' do
586
- context 'and the standard rate is applied' do
587
- it 'displays zero for %r if no progress has been made' do
588
- progressbar = ProgressBar::Base.new(:length => 100, :starting_at => 20)
589
-
590
- Timecop.travel(2) do
591
- expect(progressbar.to_s('%r')).to match(/^0\z/)
592
- end
593
- end
594
-
595
- it 'displays zero for %R if no progress has been made' do
596
- progressbar = ProgressBar::Base.new(:length => 100, :starting_at => 20)
597
-
598
- Timecop.travel(2) do
599
- expect(progressbar.to_s('%R')).to match(/^0.00\z/)
600
- end
601
- end
602
-
603
- it 'takes into account the starting position when calculating %r' do
604
- Timecop.freeze do
605
- progressbar = ProgressBar::Base.new(:length => 100, :starting_at => 20)
606
- progressbar.start
607
- progressbar.progress += 20
608
-
609
- Timecop.travel(2) do
610
- expect(progressbar.to_s('%r')).to match(/^10\z/)
611
- end
612
- end
613
- end
614
-
615
- it 'takes into account the starting position when calculating %R' do
616
- Timecop.freeze do
617
- progressbar = ProgressBar::Base.new(:length => 100, :starting_at => 20)
618
- progressbar.start
619
- progressbar.progress += 13
620
-
621
- Timecop.travel(2) do
622
- expect(progressbar.to_s('%R')).to match(/^6.50\z/)
623
- end
624
- end
625
- end
626
-
627
- it 'displays the rate when passed the "%r" format flag' do
628
- Timecop.freeze do
629
- progressbar = ProgressBar::Base.new(:length => 100, :starting_at => 0)
630
- progressbar.start
631
- progressbar.progress += 20
632
-
633
- Timecop.travel(2) do
634
- expect(progressbar.to_s('%r')).to match(/^10\z/)
635
- end
636
- end
637
- end
638
-
639
- it 'displays the rate when passed the "%R" format flag' do
640
- Timecop.freeze do
641
- progressbar = ProgressBar::Base.new(:length => 100, :starting_at => 0)
642
- progressbar.start
643
- progressbar.progress += 10
644
-
645
- Timecop.travel(6) do
646
- expect(progressbar.to_s('%R')).to match(/^1.67\z/)
647
- end
648
- end
649
- end
650
- end
651
-
652
- context 'and the a custom rate is applied' do
653
- it 'displays zero for %r if no progress has been made' do
654
- progressbar = ProgressBar::Base.new(:length => 100, :starting_at => 20, :rate_scale => lambda { |rate| rate / 2 })
655
-
656
- Timecop.travel(2) do
657
- expect(progressbar.to_s('%r')).to match(/^0\z/)
658
- end
659
- end
660
-
661
- it 'displays zero for %R if no progress has been made' do
662
- progressbar = ProgressBar::Base.new(:length => 100, :starting_at => 20, :rate_scale => lambda { |rate| rate / 2 })
663
-
664
- Timecop.travel(2) do
665
- expect(progressbar.to_s('%R')).to match(/^0.00\z/)
666
- end
667
- end
668
-
669
- it 'takes into account the starting position when calculating %r' do
670
- Timecop.freeze do
671
- progressbar = ProgressBar::Base.new(:length => 100, :starting_at => 20, :rate_scale => lambda { |rate| rate / 2 })
672
- progressbar.start
673
- progressbar.progress += 20
674
-
675
- Timecop.travel(2) do
676
- expect(progressbar.to_s('%r')).to match(/^5\z/)
677
- end
678
- end
679
- end
680
-
681
- it 'takes into account the starting position when calculating %R' do
682
- Timecop.freeze do
683
- progressbar = ProgressBar::Base.new(:length => 100, :starting_at => 20, :rate_scale => lambda { |rate| rate / 2 })
684
- progressbar.start
685
- progressbar.progress += 13
686
-
687
- Timecop.travel(2) do
688
- expect(progressbar.to_s('%R')).to match(/^3.25\z/)
689
- end
690
- end
691
- end
692
-
693
- it 'displays the rate when passed the "%r" format flag' do
694
- Timecop.freeze do
695
- progressbar = ProgressBar::Base.new(:length => 100, :starting_at => 0, :rate_scale => lambda { |rate| rate / 2 })
696
- progressbar.start
697
- progressbar.progress += 20
698
-
699
- Timecop.travel(2) do
700
- expect(progressbar.to_s('%r')).to match(/^5\z/)
701
- end
702
- end
703
- end
704
-
705
- it 'displays the rate when passed the "%R" format flag' do
706
- Timecop.freeze do
707
- progressbar = ProgressBar::Base.new(:length => 100, :starting_at => 0, :rate_scale => lambda { |rate| rate / 2 })
708
- progressbar.start
709
- progressbar.progress += 10
710
-
711
- Timecop.travel(6) do
712
- expect(progressbar.to_s('%R')).to match(/^0.83\z/)
713
- end
714
- end
715
- end
716
- end
717
- end
718
-
719
- it 'displays the title when passed the "%t" format flag' do
720
- expect(progressbar.to_s('%t')).to match(/^Progress\z/)
721
- end
722
-
723
- it 'displays the title when passed the "%T" format flag' do
724
- expect(progressbar.to_s('%T')).to match(/^Progress\z/)
725
- end
726
-
727
- it 'displays the bar when passed the "%B" format flag (including empty space)' do
728
- progressbar = ProgressBar::Base.new(:length => 100, :starting_at => 20)
729
- expect(progressbar.to_s('%B')).to match(/^#{'=' * 20}#{' ' * 80}\z/)
730
- end
731
-
732
- it 'displays the bar when passed the combined "%b%i" format flags' do
733
- progressbar = ProgressBar::Base.new(:length => 100, :starting_at => 20)
734
- expect(progressbar.to_s('%b%i')).to match(/^#{'=' * 20}#{' ' * 80}\z/)
735
- end
736
-
737
- it 'displays the bar when passed the "%b" format flag (excluding empty space)' do
738
- progressbar = ProgressBar::Base.new(:length => 100, :starting_at => 20)
739
- expect(progressbar.to_s('%b')).to match(/^#{'=' * 20}\z/)
740
- end
741
-
742
- it 'displays the incomplete space when passed the "%i" format flag' do
743
- progressbar = ProgressBar::Base.new(:length => 100, :starting_at => 20)
744
- expect(progressbar.to_s('%i')).to match(/^#{' ' * 80}\z/)
745
- end
746
-
747
- it 'displays the bar when passed the "%w" format flag' do
748
- progressbar = ProgressBar::Base.new(:output => output, :length => 100, :starting_at => 0)
749
-
750
- expect(progressbar.to_s('%w')).to match(/^\z/)
751
- 4.times { progressbar.increment }
752
- expect(progressbar.to_s('%w')).to match(/^====\z/)
753
- progressbar.increment
754
- expect(progressbar.to_s('%w')).to match(/^= 5 =\z/)
755
- 5.times { progressbar.increment }
756
- expect(progressbar.to_s('%w')).to match(/^=== 10 ===\z/)
757
- progressbar.decrement
758
- expect(progressbar.to_s('%w')).to match(/^=== 9 ===\z/)
759
- 91.times { progressbar.increment }
760
- expect(progressbar.to_s('%w')).to match(/^#{'=' * 47} 100 #{'=' * 48}\z/)
761
- end
762
-
763
- it 'calculates the remaining negative space properly with an integrated percentage bar of 0 percent' do
764
- progressbar = ProgressBar::Base.new(:output => output, :length => 100, :total => 200, :starting_at => 0)
765
-
766
- expect(progressbar.to_s('%w%i')).to match(/^\s{100}\z/)
767
- 9.times { progressbar.increment }
768
- expect(progressbar.to_s('%w%i')).to match(/^====\s{96}\z/)
769
- progressbar.increment
770
- expect(progressbar.to_s('%w%i')).to match(/^= 5 =\s{95}\z/)
771
- end
772
-
773
- it 'can display a percentage, even if the total is unknown' do
774
- progressbar = ProgressBar::Base.new(:output => output, :length => 100, :total => nil, :starting_at => 0)
775
-
776
- expect(progressbar.to_s('%p')).to match(/\A0\z/)
777
- expect(progressbar.to_s('%P')).to match(/\A0\.0\z/)
778
- end
779
-
780
- it 'can display a percentage, even if the total is zero' do
781
- progressbar = ProgressBar::Base.new(:output => output, :length => 100, :total => 0, :starting_at => 0)
782
-
783
- expect(progressbar.to_s('%p')).to match(/\A100\z/)
784
- expect(progressbar.to_s('%P')).to match(/\A100\.0\z/)
785
- end
786
-
787
- it 'displays the current capacity when passed the "%c" format flag' do
788
- progressbar = ProgressBar::Base.new(:output => output, :starting_at => 0)
789
-
790
- expect(progressbar.to_s('%c')).to match(/^0\z/)
791
- progressbar.increment
792
- expect(progressbar.to_s('%c')).to match(/^1\z/)
793
- progressbar.decrement
794
- expect(progressbar.to_s('%c')).to match(/^0\z/)
795
- end
796
-
797
- it 'displays the total capacity when passed the "%C" format flag' do
798
- progressbar = ProgressBar::Base.new(:total => 100)
799
-
800
- expect(progressbar.to_s('%C')).to match(/^100\z/)
801
- end
802
-
803
- it 'displays the percentage complete when passed the "%p" format flag' do
804
- progressbar = ProgressBar::Base.new(:starting_at => 33, :total => 200)
805
-
806
- expect(progressbar.to_s('%p')).to match(/^16\z/)
807
- end
808
-
809
- it 'displays the justified percentage complete when passed the "%j" format flag' do
810
- progressbar = ProgressBar::Base.new(:starting_at => 33, :total => 200)
811
-
812
- expect(progressbar.to_s('%j')).to match(/^ 16\z/)
813
- end
814
-
815
- it 'displays the percentage complete when passed the "%P" format flag' do
816
- progressbar = ProgressBar::Base.new(:starting_at => 33, :total => 200)
817
-
818
- expect(progressbar.to_s('%P')).to match(/^16.50\z/)
819
- end
820
-
821
- it 'displays the justified percentage complete when passed the "%J" format flag' do
822
- progressbar = ProgressBar::Base.new(:starting_at => 33, :total => 200)
823
-
824
- expect(progressbar.to_s('%J')).to match(/^ 16.50\z/)
825
- end
826
-
827
- it 'displays only up to 2 decimal places when using the "%P" flag' do
828
- progressbar = ProgressBar::Base.new(:starting_at => 66, :total => 99)
829
-
830
- expect(progressbar.to_s('%P')).to match(/^66.66\z/)
831
- end
832
-
833
- it 'displays a literal percent sign when using the "%%" flag' do
834
- progressbar = ProgressBar::Base.new(:starting_at => 66, :total => 99)
835
-
836
- expect(progressbar.to_s('%%')).to match(/^%\z/)
837
- end
838
-
839
- it 'displays a literal percent sign when using the "%%" flag' do
840
- progressbar = ProgressBar::Base.new(:starting_at => 66, :total => 99)
841
-
842
- expect(progressbar.to_s('%%')).to match(/^%\z/)
843
- end
844
-
845
- context 'when called after #start' do
846
- before do
847
- Timecop.travel(-3_723) do
848
- progressbar.start
849
- end
850
- end
851
-
852
- context 'and the bar is reset' do
853
- before { progressbar.reset }
854
-
855
- it 'displays "??:??:??" until finished when passed the %e flag' do
856
- expect(progressbar.to_s('%a')).to match(/^Time: --:--:--\z/)
857
- end
858
- end
859
-
860
- it 'displays the time elapsed when using the "%a" flag' do
861
- expect(progressbar.to_s('%a')).to match(/^Time: 01:02:03\z/)
862
- end
863
- end
864
-
865
- context 'when called before #start' do
866
- it 'displays unknown time until finished when passed the "%e" flag' do
867
- progressbar = ProgressBar::Base.new
868
- expect(progressbar.to_s('%e')).to match(/^ ETA: \?\?:\?\?:\?\?\z/)
869
- end
870
-
871
- context 'when started_at is set to a value greater than 0' do
872
- it 'displays unknown time until finished when passed the "%e" flag' do
873
- progressbar = ProgressBar::Base.new(:starting_at => 1)
874
- expect(progressbar.to_s('%e')).to match(/^ ETA: \?\?:\?\?:\?\?\z/)
875
- end
876
- end
877
- end
878
-
879
- context 'when called after #start' do
880
- let(:progressbar) do
881
- Timecop.travel(-3_723) do
882
- progressbar = ProgressBar::Base.new(:starting_at => 0, :output => output, :smoothing => 0.0)
883
- progressbar.start
884
- progressbar.progress = 50
885
- progressbar
886
- end
887
- end
888
-
889
- context 'and the bar is reset' do
890
- before { progressbar.reset }
891
-
892
- it 'displays "??:??:??" until finished when passed the "%e" flag' do
893
- expect(progressbar.to_s('%e')).to match(/^ ETA: \?\?:\?\?:\?\?\z/)
894
- end
895
- end
896
-
897
- it 'displays the estimated time remaining when using the "%e" flag' do
898
- expect(progressbar.to_s('%e')).to match(/^ ETA: 01:02:03\z/)
899
- end
900
- end
901
-
902
- context 'when it could take 100 hours or longer to finish' do
903
- let(:progressbar) do
904
- Timecop.travel(-120_000) do
905
- progressbar = ProgressBar::Base.new(:starting_at => 0, :total => 100, :output => output, :smoothing => 0.0)
906
- progressbar.start
907
- progressbar.progress = 25
908
- progressbar
909
- end
910
- end
911
-
912
- it 'displays "> 4 Days" until finished when passed the "%E" flag' do
913
- expect(progressbar.to_s('%E')).to match(/^ ETA: > 4 Days\z/)
914
- end
915
-
916
- it 'displays "??:??:??" until finished when passed the "%e" flag' do
917
- expect(progressbar.to_s('%e')).to match(/^ ETA: \?\?:\?\?:\?\?\z/)
918
- end
919
-
920
- it 'displays the exact estimated time until finished when passed the "%f" flag' do
921
- expect(progressbar.to_s('%f')).to match(/^ ETA: 100:00:00\z/)
922
- end
923
- end
924
- end
925
- end
926
-
927
- context 'when the bar is started after having total set to 0' do
928
- let(:progressbar) { ProgressBar::Base.new(:output => output, :autostart => false) }
929
-
930
- it 'does not throw an error' do
931
- progressbar.total = 0
932
-
933
- expect { progressbar.start }.not_to raise_error
934
- end
935
- end
936
-
937
- context 'when the bar has no items to process' do
938
- context 'and it has not been started' do
939
- let(:progressbar) { ProgressBar::Base.new(:started_at => 0, :total => 0, :autostart => false, :smoothing => 0.0, :format => ' %c/%C |%w>%i| %e ', :output => output) }
940
-
941
- it 'does not throw an error if told to stop' do
942
- progressbar.stop
943
-
944
- expect { progressbar.start }.not_to raise_error
945
- end
946
- end
947
- end
948
- end
949
- # rubocop:enable Metrics/LineLength