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
@@ -1,64 +0,0 @@
1
- class ProgressBar
2
- module LengthCalculator
3
- def initialize(options)
4
- @length_override = ENV['RUBY_PROGRESS_BAR_LENGTH'] || options[:length]
5
- @length_override = @length_override.to_i if @length_override
6
- @current_length = nil
7
-
8
- super()
9
- end
10
-
11
- private
12
- def length
13
- @current_length || reset_length
14
- end
15
-
16
- def length_changed?
17
- @current_length != calculate_length
18
- end
19
-
20
- def calculate_length
21
- @length_override || terminal_width || 80
22
- end
23
-
24
- def reset_length
25
- @current_length = calculate_length
26
- end
27
-
28
- # This code was copied and modified from Rake, available under MIT-LICENSE
29
- # Copyright (c) 2003, 2004 Jim Weirich
30
- def terminal_width
31
- return 80 unless unix?
32
-
33
- result = dynamic_width
34
- (result < 20) ? 80 : result
35
- rescue
36
- 80
37
- end
38
-
39
- begin
40
- require 'io/console'
41
-
42
- def dynamic_width
43
- _rows, columns = IO.console.winsize
44
- columns
45
- end
46
- rescue LoadError
47
- def dynamic_width
48
- dynamic_width_stty.nonzero? || dynamic_width_tput
49
- end
50
-
51
- def dynamic_width_stty
52
- %x{stty size 2>/dev/null}.split[1].to_i
53
- end
54
-
55
- def dynamic_width_tput
56
- %x{tput cols 2>/dev/null}.to_i
57
- end
58
- end
59
-
60
- def unix?
61
- RUBY_PLATFORM =~ /(aix|darwin|linux|(net|free|open)bsd|cygwin|solaris|irix|hpux)/i
62
- end
63
- end
64
- end
@@ -1,7 +0,0 @@
1
- class ProgressBar
2
- class RunningAverageCalculator
3
- def self.calculate(current_average, new_value_to_average, smoothing_factor)
4
- new_value_to_average * (1.0 - smoothing_factor) + current_average * smoothing_factor
5
- end
6
- end
7
- end
@@ -1,210 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe ProgressBar::Components::Bar do
4
- context 'when a new bar is created' do
5
- context 'and no parameters are passed' do
6
- before { @progressbar = ProgressBar::Components::Bar.new }
7
-
8
- describe '#total' do
9
- it 'returns the default total' do
10
- expect(@progressbar.total).to eql ProgressBar::Components::Bar::DEFAULT_TOTAL
11
- end
12
- end
13
-
14
- describe '#progress_mark' do
15
- it 'returns the default mark' do
16
- expect(@progressbar.progress_mark).to eql ProgressBar::Components::Bar::DEFAULT_PROGRESS_MARK
17
- end
18
- end
19
-
20
- describe '#remainder_mark' do
21
- it 'returns the default remainder mark' do
22
- expect(@progressbar.remainder_mark).to eql ProgressBar::Components::Bar::DEFAULT_REMAINDER_MARK
23
- end
24
- end
25
-
26
- context 'and the bar has not been started' do
27
- describe '#progress' do
28
- it 'returns the default beginning position' do
29
- expect(@progressbar.progress).to be_zero
30
- end
31
- end
32
- end
33
-
34
- context 'and the bar has been started with no starting value given' do
35
- before { @progressbar.start }
36
-
37
- describe '#progress' do
38
- it 'returns the default starting value' do
39
- expect(@progressbar.progress).to eql ProgressBar::Components::Progressable::DEFAULT_BEGINNING_POSITION
40
- end
41
- end
42
- end
43
-
44
- context 'and the bar has been started with a starting value' do
45
- before { @progressbar.start :at => 10 }
46
-
47
- describe '#progress' do
48
- it 'returns the given starting value' do
49
- expect(@progressbar.progress).to eql 10
50
- end
51
- end
52
- end
53
- end
54
-
55
- context 'and options are passed' do
56
- before { @progressbar = ProgressBar::Components::Bar.new(:total => 12, :progress_mark => 'x', :remainder_mark => '.') }
57
-
58
- describe '#total' do
59
- it 'returns the overridden total' do
60
- expect(@progressbar.total).to eql 12
61
- end
62
- end
63
-
64
- describe '#progress_mark' do
65
- it 'returns the overridden mark' do
66
- expect(@progressbar.progress_mark).to eql 'x'
67
- end
68
- end
69
-
70
- describe '#remainder_mark' do
71
- it 'returns the overridden mark' do
72
- expect(@progressbar.remainder_mark).to eql '.'
73
- end
74
- end
75
- end
76
- end
77
-
78
- context 'when just begun' do
79
- before do
80
- @progressbar = ProgressBar::Components::Bar.new(:total => 50)
81
- @progressbar.length = 100
82
- @progressbar.start
83
- end
84
-
85
- describe '#percentage_completed' do
86
- it 'calculates the amount' do
87
- expect(@progressbar.percentage_completed).to eql 0
88
- end
89
- end
90
-
91
- describe '#to_s' do
92
- it 'displays the bar with no indication of progress' do
93
- expect(@progressbar.to_s).to eql ' '
94
- end
95
- end
96
- end
97
-
98
- context 'when nothing has been completed' do
99
- before do
100
- @progressbar = ProgressBar::Components::Bar.new(:total => 50)
101
- @progressbar.length = 100
102
- @progressbar.start
103
- end
104
-
105
- context 'and the bar is incremented' do
106
- before { @progressbar.increment }
107
-
108
- it 'adds to the progress amount' do
109
- expect(@progressbar.progress).to eql 1
110
- end
111
-
112
- describe '#percentage_completed' do
113
- it 'calculates the amount completed' do
114
- expect(@progressbar.percentage_completed).to eql 2
115
- end
116
- end
117
-
118
- describe '#to_s' do
119
- it 'displays the bar with an indication of progress' do
120
- expect(@progressbar.to_s).to eql '== '
121
- end
122
- end
123
- end
124
-
125
- describe '#percentage_completed' do
126
- it 'is zero' do
127
- expect(@progressbar.percentage_completed).to eql 0
128
- end
129
- end
130
-
131
- describe '#to_s' do
132
- it 'displays the bar with no indication of progress' do
133
- expect(@progressbar.to_s).to eql ' '
134
- end
135
- end
136
- end
137
-
138
- context 'when a fraction of a percentage has been completed' do
139
- before do
140
- @progressbar = ProgressBar::Components::Bar.new(:total => 200)
141
- @progressbar.length = 100
142
- @progressbar.start :at => 1
143
- end
144
-
145
- describe '#percentage_completed' do
146
- it 'always rounds down' do
147
- expect(@progressbar.percentage_completed).to eql 0
148
- end
149
- end
150
-
151
- describe '#to_s' do
152
- it 'displays the bar with no indication of progress' do
153
- expect(@progressbar.to_s).to eql ' '
154
- end
155
- end
156
- end
157
-
158
- context 'when completed' do
159
- before do
160
- @progressbar = ProgressBar::Components::Bar.new(:total => 50)
161
- @progressbar.length = 100
162
- @progressbar.start :at => 50
163
- end
164
-
165
- context 'and the bar is incremented' do
166
- before { @progressbar.increment }
167
-
168
- it 'does not increment past the total' do
169
- expect(@progressbar.progress).to eql 50
170
- expect(@progressbar.percentage_completed).to eql 100
171
- end
172
-
173
- describe '#to_s' do
174
- it 'displays the bar as 100% complete' do
175
- expect(@progressbar.to_s).to eql '=' * 100
176
- end
177
- end
178
- end
179
-
180
- context 'and the bar is decremented' do
181
- before { @progressbar.decrement }
182
-
183
- it 'removes some progress from the bar' do
184
- expect(@progressbar.progress).to eql 49
185
- expect(@progressbar.percentage_completed).to eql 98
186
- end
187
-
188
- describe '#to_s' do
189
- it 'displays the bar as 98% complete' do
190
- expect(@progressbar.to_s).to eql "#{'=' * 98} "
191
- end
192
- end
193
- end
194
-
195
- describe '#to_s' do
196
- it 'displays the bar as 100% complete' do
197
- expect(@progressbar.to_s).to eql ('=' * 100)
198
- end
199
- end
200
- end
201
-
202
- context "when attempting to set the bar's current value to be greater than the total" do
203
- describe '#new' do
204
- it 'raises an error' do
205
- @progressbar = ProgressBar::Components::Bar.new(:total => 10)
206
- expect { @progressbar.start :at => 11 }.to raise_error(ProgressBar::InvalidProgressError, "You can't set the item's current value to be greater than the total.")
207
- end
208
- end
209
- end
210
- end
@@ -1,91 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe ProgressBar::Components::ElapsedTimer do
4
- before { @timer = ProgressBar::Components::ElapsedTimer.new }
5
-
6
- describe '#to_s' do
7
- context 'when the timer has not been started' do
8
- it 'displays "Time: --:--:--"' do
9
- expect(@timer.to_s).to eql 'Time: --:--:--'
10
- end
11
- end
12
-
13
- context 'when it has just been started' do
14
- it 'displays "Time: 00:00:00"' do
15
- @timer.start
16
- expect(@timer.to_s).to eql 'Time: 00:00:00'
17
- end
18
- end
19
-
20
- context 'when it was started 4 hours, 28 minutes and 13 seconds ago' do
21
- before do
22
- Timecop.travel(-16093) do
23
- @timer.start
24
- end
25
- end
26
-
27
- context 'and it was stopped 32 seconds ago' do
28
- before do
29
- Timecop.travel(-32) do
30
- @timer.stop
31
- end
32
- end
33
-
34
- context 'and #reset is called' do
35
- before { @timer.reset }
36
-
37
- it 'displays "Time: --:--:--"' do
38
- expect(@timer.to_s).to eql 'Time: --:--:--'
39
- end
40
- end
41
-
42
- it 'displays "Time: 04:27:41"' do
43
- expect(@timer.to_s).to eql 'Time: 04:27:41'
44
- end
45
- end
46
-
47
- context 'and #reset is called' do
48
- before { @timer.reset }
49
-
50
- it 'displays "Time: --:--:--"' do
51
- expect(@timer.to_s).to eql 'Time: --:--:--'
52
- end
53
- end
54
-
55
- it 'displays "Time: 04:28:13"' do
56
- expect(@timer.to_s).to eql 'Time: 04:28:13'
57
- end
58
- end
59
- end
60
-
61
- describe '#stopped?' do
62
- context 'when the timer is started' do
63
- before { @timer.start }
64
-
65
- context 'and then it is stopped' do
66
- before { @timer.stop }
67
-
68
- context 'and then it is restarted' do
69
- before { @timer.start }
70
-
71
- it 'is false' do
72
- expect(@timer).not_to be_stopped
73
- end
74
- end
75
- end
76
- end
77
-
78
- context "when the timer has yet to be started" do
79
- it 'is false' do
80
- expect(@timer).not_to be_stopped
81
- end
82
- end
83
-
84
- context "when the timer is stopped without having been started" do
85
- before { @timer.stop }
86
- it 'is false' do
87
- expect(@timer).not_to be_stopped
88
- end
89
- end
90
- end
91
- end
@@ -1,241 +0,0 @@
1
- require 'spec_helper'
2
- require 'support/time'
3
-
4
- describe ProgressBar::Components::EstimatedTimer do
5
- describe '#progress=' do
6
- it 'raises an error when passed a number larger than the total' do
7
- @estimated_time = ProgressBar::Components::EstimatedTimer.new(:total => 100)
8
- expect { @estimated_time.progress = 101 }.to raise_error(ProgressBar::InvalidProgressError, "You can't set the item's current value to be greater than the total.")
9
- end
10
- end
11
-
12
- describe '#to_s' do
13
- context 'when the timer has been started but no progress has been made' do
14
- before do
15
- @estimated_time = ProgressBar::Components::EstimatedTimer.new(:total => 100)
16
- @estimated_time.start
17
- end
18
-
19
- it 'displays an unknown time remaining' do
20
- expect(@estimated_time.to_s).to eql ' ETA: ??:??:??'
21
- end
22
-
23
- context 'and it is incremented' do
24
- it 'should not display unknown time remaining' do
25
- @estimated_time.increment
26
- expect(@estimated_time.to_s).not_to eql ' ETA: ??:??:??'
27
- end
28
- end
29
- end
30
-
31
- context 'when half the progress has been made' do
32
- context 'and smoothing is turned off' do
33
- let(:smoothing) { 0.0 }
34
-
35
- context 'and it took 3:42:12 to do it' do
36
- before do
37
- @estimated_time = ProgressBar::Components::EstimatedTimer.new(:starting_at => 0, :total => 100, :smoothing => smoothing)
38
-
39
- Timecop.travel(-13332) do
40
- @estimated_time.start
41
- 50.times { @estimated_time.increment }
42
- end
43
- end
44
-
45
- context 'when #decrement is called' do
46
- before { 20.times { @estimated_time.decrement } }
47
-
48
- it 'displays the correct time remaining' do
49
- expect(@estimated_time.to_s).to eql ' ETA: 08:38:28'
50
- end
51
- end
52
-
53
- context 'when #reset is called' do
54
- before { @estimated_time.reset }
55
-
56
- it 'displays unknown time remaining' do
57
- expect(@estimated_time.to_s).to eql ' ETA: ??:??:??'
58
- end
59
- end
60
-
61
- it 'displays the correct time remaining' do
62
- expect(@estimated_time.to_s).to eql ' ETA: 03:42:12'
63
- end
64
- end
65
-
66
- context 'when it is estimated to take longer than 99:59:59' do
67
- before do
68
- @estimated_time = ProgressBar::Components::EstimatedTimer.new(:starting_at => 0, :total => 100, :smoothing => smoothing)
69
-
70
- Timecop.travel(-120000) do
71
- @estimated_time.start
72
- 25.times { @estimated_time.increment }
73
- end
74
- end
75
-
76
- context 'and the out of bounds time format has been set to "friendly"' do
77
- before { @estimated_time.out_of_bounds_time_format = :friendly }
78
-
79
- it 'displays "> 4 Days" remaining' do
80
- expect(@estimated_time.to_s).to eql ' ETA: > 4 Days'
81
- end
82
- end
83
-
84
- context 'and the out of bounds time format has been set to "unknown"' do
85
- before { @estimated_time.out_of_bounds_time_format = :unknown }
86
-
87
- it 'displays "??:??:??" remaining' do
88
- expect(@estimated_time.to_s).to eql ' ETA: ??:??:??'
89
- end
90
- end
91
-
92
- it 'displays the correct time remaining' do
93
- expect(@estimated_time.to_s).to eql ' ETA: 100:00:00'
94
- end
95
- end
96
- end
97
-
98
- context 'and smoothing is turned on' do
99
- let(:smoothing) { 0.5 }
100
-
101
- context 'and it took 3:42:12 to do it' do
102
- before do
103
- @estimated_time = ProgressBar::Components::EstimatedTimer.new(:starting_at => 0, :total => 100, :smoothing => smoothing)
104
-
105
- Timecop.travel(-13332) do
106
- @estimated_time.start
107
- 50.times { @estimated_time.increment }
108
- end
109
- end
110
-
111
- context 'when #decrement is called' do
112
- before { 20.times { @estimated_time.decrement } }
113
-
114
- it 'displays the correct time remaining' do
115
- expect(@estimated_time.to_s).to eql ' ETA: 08:14:34'
116
- end
117
- end
118
-
119
- context 'when #reset is called' do
120
- before { @estimated_time.reset }
121
-
122
- it 'displays unknown time remaining' do
123
- expect(@estimated_time.to_s).to eql ' ETA: ??:??:??'
124
- end
125
- end
126
-
127
- it 'displays the correct time remaining' do
128
- expect(@estimated_time.to_s).to eql ' ETA: 03:51:16'
129
- end
130
- end
131
-
132
- context 'when it is estimated to take longer than 99:59:59' do
133
- before do
134
- @estimated_time = ProgressBar::Components::EstimatedTimer.new(:starting_at => 0, :total => 100, :smoothing => smoothing)
135
-
136
- Timecop.travel(-120000) do
137
- @estimated_time.start
138
- 25.times { @estimated_time.increment }
139
- end
140
- end
141
-
142
- context 'and the out of bounds time format has been set to "friendly"' do
143
- before { @estimated_time.out_of_bounds_time_format = :friendly }
144
-
145
- it 'displays "> 4 Days" remaining' do
146
- expect(@estimated_time.to_s).to eql ' ETA: > 4 Days'
147
- end
148
- end
149
-
150
- context 'and the out of bounds time format has been set to "unknown"' do
151
- before { @estimated_time.out_of_bounds_time_format = :unknown }
152
-
153
- it 'displays "??:??:??" remaining' do
154
- expect(@estimated_time.to_s).to eql ' ETA: ??:??:??'
155
- end
156
- end
157
-
158
- it 'displays the correct time remaining' do
159
- expect(@estimated_time.to_s).to eql ' ETA: 105:33:20'
160
- end
161
- end
162
- end
163
- end
164
-
165
- it 'displays a good estimate for regular increments' do
166
- begin
167
- Timecop.freeze(t = Time.now)
168
- n = 10
169
- estimated_time = ProgressBar::Components::EstimatedTimer.new(:total => n)
170
- estimated_time.start
171
- results = (1..n).map do |i|
172
- Timecop.freeze(t + 0.5 * i)
173
- estimated_time.increment
174
- estimated_time.to_s
175
- end
176
-
177
- expect(results).to eql([
178
- ' ETA: 00:00:05',
179
- ' ETA: 00:00:04',
180
- ' ETA: 00:00:04',
181
- ' ETA: 00:00:03',
182
- ' ETA: 00:00:03',
183
- ' ETA: 00:00:02',
184
- ' ETA: 00:00:02',
185
- ' ETA: 00:00:01',
186
- ' ETA: 00:00:01',
187
- ' ETA: 00:00:00',
188
- ])
189
- ensure
190
- Timecop.return
191
- end
192
- end
193
- end
194
-
195
- describe '#out_of_bounds_time_format=' do
196
- context 'when set to an invalid format' do
197
- it 'raises an exception' do
198
- @estimated_time = ProgressBar::Components::EstimatedTimer.new(:total => 100)
199
- expect { @estimated_time.out_of_bounds_time_format = :foo }.to raise_error('Invalid Out Of Bounds time format. Valid formats are [:unknown, :friendly, nil]')
200
- end
201
- end
202
- end
203
-
204
- describe '#start' do
205
-
206
- ###
207
- # Using ruby-debug under jruby pulls in ruby-debug-base, which defines
208
- # Kernel.start. This causes a bug, as EstimatedTimer::As::method_missing calls
209
- # Kernel.start instead of EstimatedTimer.start. This spec duplicates the bug.
210
- # Without the fix, this results in the following exception:
211
- #
212
- # 1) ruby-debug-base doesn't stop the progressbar from working
213
- # Failure/Error: COUNT.times { bar.increment }
214
- # NoMethodError:
215
- # undefined method `+' for nil:NilClass
216
- # # ./lib/ruby-progressbar/components/progressable.rb:33:in `increment'
217
- #
218
- it 'properly delegates' do
219
- @output = StringIO.new('', 'w+')
220
-
221
- module Kernel
222
- def start(options={}, &block)
223
- puts "Kernel.start has been called"
224
- return nil
225
- end
226
- end
227
-
228
- begin
229
- COUNT = 100
230
-
231
- bar = ProgressBar.create(:output => @output, :title => 'ruby-debug-base', :total => COUNT)
232
-
233
- COUNT.times { bar.increment }
234
- ensure
235
- module Kernel
236
- remove_method :start
237
- end
238
- end
239
- end
240
- end
241
- end