ruby-progressbar 1.2.0 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -12,6 +12,7 @@ Supported Rubies
12
12
  * MRI Ruby 1.8.7
13
13
  * MRI Ruby 1.9.2
14
14
  * MRI Ruby 1.9.3
15
+ * MRI Ruby 2.0.0
15
16
  * JRuby (in 1.8 compat mode)
16
17
  * JRuby (in 1.9 compat mode)
17
18
 
@@ -98,6 +99,7 @@ The following are the list of options you can use:
98
99
  * `:total` - _(Defaults to `100`)_ The total number of the items that can be completed.
99
100
  * `:starting_at` - _(Defaults to `0`)_ The number of items that should be considered completed when the bar first starts. This is also the default number that the bar will be set to if `#reset` is called.
100
101
  * `:progress_mark` - _(Defaults to `=`)_ The mark which indicates the amount of progress that has been made.
102
+ * `:remainder_mark` - _(Defaults to ` `)_ The mark which indicates the remaining amount of progress to be made.
101
103
  * `:format` - _(Defaults to `%t: |%B|`)_ The format string which determines how the bar is displayed. See [**Formatting**](#formatting) below.
102
104
  * `:length` - _(Defaults to full width if possible, otherwise `80`)_ The preferred width of the entire progress bar including any format options.
103
105
  * `:output` - _(Defaults to `STDOUT`)_ All output will be sent to this object. Can be any object which responds to `.print`.
@@ -267,6 +269,7 @@ _Note: If the terminal width is less than 20 characters or ruby-progressbar is b
267
269
  The following items can be set at any time. Changes cause an immediate bar refresh so no other action is needed:
268
270
 
269
271
  * `#progress_mark=`: Sets the string used to represent progress along the bar.
272
+ * `#remainder_mark=`: Sets the string used to represent the empty part of the bar.
270
273
  * `#title=`: Sets the string used to represent the items the bar is tracking (or I guess whatever else you want it to be).
271
274
  * `#format(format_string)`: If you need to adjust the format that the bar uses when rendering itself, just pass in a string in the same format as describe [above](#formatting).
272
275
 
@@ -321,9 +324,35 @@ You can have an array of as many elements as you'd like and they will be used in
321
324
 
322
325
  Whatever element is chosen is repeated along the entire 'incomplete' portion of the bar.
323
326
 
324
- Road Map
325
- --------------------------------
326
- We're planning on adding a bunch of really nice features to this gem over the next few weeks. We want to keep the simple usage simple but allow for powerful features if they're needed. Our `1.0` release is the first step in that direction.
327
+ ### Non-TTY Output
328
+
329
+ Typically, when the progress bar is updated, the entire previous bar is 'overwritten' with the updated information. Unfortunately when the bar is being output on a non-TTY enabled output stream (such as a file or pipe), that standard behavior of outputting the progress bar will not work. This is mainly due to the fact that we can't easily go back and replace the content that the bar had previously written.
330
+
331
+ To try to solve this, ruby-progressbar, when it determines that it is being used on a non-TTY device, will override any format which was set in the initializer to something which more closely resembles this:
332
+
333
+ Progress: |=============
334
+
335
+ Notice that there are no dynamically updating segments like counters or ETA. Dynamic segments are not compatible with non-TTY devices because, by their very nature, they must be updated on each refresh of the bar and as stated previously, that is not possible in non-TTY mode.
336
+
337
+ Also notice that there is no end cap on the righthand side of the bar. Again, we cannot output something which is past the point at which we next need to output text. If we added an end cap, that would mean that any additional progress text would be placed _after_ the end cap. Definitely not what we want.
338
+
339
+ So how does it work? First we output the title and the first end cap:
340
+
341
+ Progress: |
342
+
343
+ Next, every time we increment the bar, we check whether the progress bar has grown. If it has, we output _only the additional portion_ of the bar to the output.
344
+
345
+ For example, given the previous title output, if we increment the bar once, we would get:
346
+
347
+ Progress: |=
348
+
349
+ But in this case, only one `=` was output. Not the entire `Progress: |=`.
350
+
351
+ Once the bar gets to be completely finished though:
352
+
353
+ Progress: |====================================================================|
354
+
355
+ The end cap can now be added (since there is no more progress to be displayed).
327
356
 
328
357
  Issues
329
358
  --------------------------------
@@ -7,6 +7,7 @@ class ProgressBar
7
7
 
8
8
  def initialize(options = {})
9
9
  self.output = options[:output] || DEFAULT_OUTPUT_STREAM
10
+ autostart = options.fetch(:autostart, true)
10
11
 
11
12
  super(options)
12
13
 
@@ -15,7 +16,7 @@ class ProgressBar
15
16
  @elapsed_time = Components::ElapsedTimer.new
16
17
  @throttle = Components::Throttle.new(options)
17
18
 
18
- start :at => options[:starting_at]
19
+ start :at => options[:starting_at] if autostart
19
20
  end
20
21
 
21
22
  ###
@@ -53,19 +54,19 @@ class ProgressBar
53
54
  # Stopping The Bar
54
55
  #
55
56
  def finish
56
- with_update { with_progressables(:finish) }
57
+ with_update { with_progressables(:finish) } unless finished?
57
58
  end
58
59
 
59
60
  def pause
60
- with_update { with_timers(:pause) }
61
+ with_update { with_timers(:pause) } unless paused?
61
62
  end
62
63
 
63
64
  def stop
64
- with_update { with_timers(:stop) }
65
+ with_update { with_timers(:stop) } unless stopped?
65
66
  end
66
67
 
67
68
  def resume
68
- with_update { with_timers(:resume) }
69
+ with_update { with_timers(:resume) } if stopped?
69
70
  end
70
71
 
71
72
  def reset
@@ -92,6 +93,10 @@ class ProgressBar
92
93
  with_update { @bar.progress_mark = mark }
93
94
  end
94
95
 
96
+ def remainder_mark=(mark)
97
+ with_update { @bar.remainder_mark = mark }
98
+ end
99
+
95
100
  def title=(title)
96
101
  with_update { super }
97
102
  end
@@ -100,9 +105,13 @@ class ProgressBar
100
105
  # Output
101
106
  #
102
107
  def clear
108
+ self.last_update_length = 0
109
+
103
110
  if output.tty?
104
111
  output.print clear_string
105
112
  output.print "\r"
113
+ else
114
+ output.print "\n"
106
115
  end
107
116
  end
108
117
 
@@ -128,12 +137,17 @@ class ProgressBar
128
137
  end
129
138
 
130
139
  private
131
- attr_accessor :output
140
+ attr_accessor :output,
141
+ :last_update_length
132
142
 
133
143
  def clear_string
134
144
  "#{" " * length}"
135
145
  end
136
146
 
147
+ def last_update_length
148
+ @last_update_length ||= 0
149
+ end
150
+
137
151
  def with_progressables(*args)
138
152
  @bar.send(*args)
139
153
  @estimated_time.send(*args)
@@ -150,23 +164,37 @@ class ProgressBar
150
164
  end
151
165
 
152
166
  def update(options = {})
153
- if output.tty? || stopped?
154
- with_timers(:stop) if finished?
167
+ with_timers(:stop) if finished?
155
168
 
156
- @throttle.choke( stopped? || options[:force] ) do
157
- if length_changed?
158
- clear
159
- reset_length
160
- end
169
+ if length_changed?
170
+ clear
171
+ reset_length
172
+ end
161
173
 
162
- output.print self.to_s + eol
163
- output.flush
174
+ @throttle.choke( stopped? || options[:force] ) do
175
+ if output.tty?
176
+ formatted_string = self.to_s
177
+ output_string = formatted_string
178
+ else
179
+ formatted_string = self.to_s(DEFAULT_NON_TTY_FORMAT_STRING)
180
+ formatted_string = formatted_string[0...-1] unless finished?
181
+
182
+ output_string = formatted_string[last_update_length..-1]
164
183
  end
184
+
185
+ self.last_update_length = formatted_string.length
186
+
187
+ output.print output_string + eol
188
+ output.flush
165
189
  end
166
190
  end
167
191
 
168
192
  def eol
169
- stopped? ? "\n" : "\r"
193
+ if output.tty?
194
+ stopped? ? "\n" : "\r"
195
+ else
196
+ stopped? ? "\n" : ""
197
+ end
170
198
  end
171
199
  end
172
200
  end
@@ -4,9 +4,11 @@ class ProgressBar
4
4
  include Progressable
5
5
 
6
6
  DEFAULT_PROGRESS_MARK = '='
7
+ DEFAULT_REMAINDER_MARK = ' '
7
8
  DEFAULT_UNKNOWN_PROGRESS_ANIMATION_STEPS = ['=---', '-=--', '--=-', '---=']
8
9
 
9
10
  attr_accessor :progress_mark
11
+ attr_accessor :remainder_mark
10
12
  attr_accessor :length
11
13
  attr_accessor :unknown_progress_animation_steps
12
14
 
@@ -15,6 +17,7 @@ class ProgressBar
15
17
 
16
18
  self.unknown_progress_animation_steps = options[:unknown_progress_animation_steps] || DEFAULT_UNKNOWN_PROGRESS_ANIMATION_STEPS
17
19
  self.progress_mark = options[:progress_mark] || DEFAULT_PROGRESS_MARK
20
+ self.remainder_mark = options[:remainder_mark] || DEFAULT_REMAINDER_MARK
18
21
  end
19
22
 
20
23
  def to_s(options = {:format => :standard})
@@ -44,7 +47,7 @@ class ProgressBar
44
47
 
45
48
  unknown_incomplete_string[0, incomplete_length]
46
49
  else
47
- ' ' * incomplete_length
50
+ remainder_mark * incomplete_length
48
51
  end
49
52
  end
50
53
 
@@ -10,6 +10,7 @@ class ProgressBar
10
10
 
11
11
  def process(environment)
12
12
  processed_string = @format_string.dup
13
+ ansi_sgr_codes = %r{\e\[[\d;]+m}
13
14
 
14
15
  non_bar_molecules.each do |molecule|
15
16
  processed_string.gsub!("%#{molecule.key}", environment.send(molecule.method_name).to_s)
@@ -20,8 +21,9 @@ class ProgressBar
20
21
 
21
22
  processed_string.gsub! '%%', '%'
22
23
 
23
- leftover_bar_length = environment.send(:length) - processed_string.length + placeholder_length
24
- leftover_bar_length = leftover_bar_length < 0 ? 0 : leftover_bar_length
24
+ processed_string_length = processed_string.gsub(ansi_sgr_codes, '').length
25
+ leftover_bar_length = environment.send(:length) - processed_string_length + placeholder_length
26
+ leftover_bar_length = leftover_bar_length < 0 ? 0 : leftover_bar_length
25
27
 
26
28
  bar_molecules.each do |molecule|
27
29
  processed_string.gsub!("%#{molecule.key}", environment.send(molecule.method_name, leftover_bar_length).to_s)
@@ -1,7 +1,8 @@
1
1
  class ProgressBar
2
2
  module Formatter
3
- DEFAULT_FORMAT_STRING = '%t: |%B|'
4
- DEFAULT_TITLE = 'Progress'
3
+ DEFAULT_FORMAT_STRING = '%t: |%B|'
4
+ DEFAULT_NON_TTY_FORMAT_STRING = '%t: |%b|'
5
+ DEFAULT_TITLE = 'Progress'
5
6
 
6
7
  def initialize(options)
7
8
  self.format_string = options[:format] || DEFAULT_FORMAT_STRING
@@ -1,3 +1,3 @@
1
1
  class ProgressBar
2
- VERSION = '1.2.0'
2
+ VERSION = '1.3.0'
3
3
  end
@@ -2,86 +2,89 @@ require 'spec_helper'
2
2
  require 'stringio'
3
3
 
4
4
  describe ProgressBar::Base do
5
- before do
6
- @output = StringIO.new('', 'w+')
7
- @output.stub(:tty?).and_return true
8
-
9
- @non_tty_output = StringIO.new('', 'w+')
10
- @non_tty_output.stub(:tty?).and_return false
5
+ let(:output) do
6
+ StringIO.new('', 'w+').tap do |io|
7
+ io.stub(:tty?).and_return true
8
+ end
9
+ end
11
10
 
12
- @progressbar = ProgressBar::Base.new(:output => @output, :length => 80, :throttle_rate => 0.0)
13
- @output.rewind
11
+ let(:non_tty_output) do
12
+ StringIO.new('', 'w+').tap do |io|
13
+ io.stub(:tty?).and_return false
14
+ end
14
15
  end
15
16
 
17
+ let(:progressbar) { ProgressBar::Base.new(:output => output, :length => 80, :throttle_rate => 0.0) }
18
+
16
19
  context 'when the terminal width is shorter than the string being output' do
17
20
  it 'can properly handle outputting the bar when the length changes on the fly to less than the minimum width' do
18
21
  IO.stub_chain(:console, :winsize).and_return [1, 30]
19
- @progressbar = ProgressBar::Base.new(:output => @output, :title => 'a' * 25, :format => '%t%B', :throttle_rate => 0.0)
22
+ progressbar = ProgressBar::Base.new(:output => output, :title => 'a' * 25, :format => '%t%B', :throttle_rate => 0.0)
20
23
 
21
- @progressbar.start
24
+ progressbar.start
22
25
 
23
26
  IO.stub_chain(:console, :winsize).and_return [1, 20]
24
- @progressbar.increment
27
+ progressbar.increment
25
28
 
26
- @output.rewind
27
- @output.read.should match /\raaaaaaaaaaaaaaaaaaaaaaaaa \r\s+\raaaaaaaaaaaaaaaaaaaaaaaaa\r\z/
29
+ output.rewind
30
+ output.read.should match /\raaaaaaaaaaaaaaaaaaaaaaaaa \r\s+\raaaaaaaaaaaaaaaaaaaaaaaaa\r\z/
28
31
  end
29
32
 
30
33
  context 'and the bar length is calculated' do
31
34
  it 'returns the proper string' do
32
35
  IO.stub_chain(:console, :winsize).and_return [1, 20]
33
- @progressbar = ProgressBar::Base.new(:output => @output, :title => ('*' * 21), :starting_at => 5, :total => 10)
36
+ progressbar = ProgressBar::Base.new(:output => output, :title => ('*' * 21), :starting_at => 5, :total => 10)
34
37
 
35
- @progressbar.to_s('%t%w').should eql '*********************'
38
+ progressbar.to_s('%t%w').should eql '*********************'
36
39
  end
37
40
  end
38
41
 
39
42
  context 'and the incomplete bar length is calculated' do
40
43
  it 'returns the proper string' do
41
44
  IO.stub_chain(:console, :winsize).and_return [1, 20]
42
- @progressbar = ProgressBar::Base.new(:output => @output, :title => ('*' * 21))
45
+ progressbar = ProgressBar::Base.new(:output => output, :title => ('*' * 21))
43
46
 
44
- @progressbar.to_s('%t%i').should eql '*********************'
47
+ progressbar.to_s('%t%i').should eql '*********************'
45
48
  end
46
49
 
47
50
  it 'returns the proper string' do
48
51
  IO.stub_chain(:console, :winsize).and_return [1, 20]
49
- @progressbar = ProgressBar::Base.new(:output => @output, :title => ('*' * 21), :starting_at => 5, :total => 10)
52
+ progressbar = ProgressBar::Base.new(:output => output, :title => ('*' * 21), :starting_at => 5, :total => 10)
50
53
 
51
- @progressbar.to_s('%t%i').should eql '*********************'
54
+ progressbar.to_s('%t%i').should eql '*********************'
52
55
  end
53
56
  end
54
57
 
55
58
  context 'and the full bar length is calculated (but lacks the space to output the entire bar)' do
56
59
  it 'returns the proper string' do
57
60
  IO.stub_chain(:console, :winsize).and_return [1, 20]
58
- @progressbar = ProgressBar::Base.new(:output => @output, :title => ('*' * 19), :starting_at => 5, :total => 10)
61
+ progressbar = ProgressBar::Base.new(:output => output, :title => ('*' * 19), :starting_at => 5, :total => 10)
59
62
 
60
- @progressbar.to_s('%t%B').should eql '******************* '
63
+ progressbar.to_s('%t%B').should eql '******************* '
61
64
  end
62
65
 
63
66
  it 'returns the proper string' do
64
67
  IO.stub_chain(:console, :winsize).and_return [1, 20]
65
- @progressbar = ProgressBar::Base.new(:output => @output, :title => ('*' * 19), :starting_at => 5, :total => 10)
68
+ progressbar = ProgressBar::Base.new(:output => output, :title => ('*' * 19), :starting_at => 5, :total => 10)
66
69
 
67
- @progressbar.to_s('%t%w%i').should eql '******************* '
70
+ progressbar.to_s('%t%w%i').should eql '******************* '
68
71
  end
69
72
  end
70
73
  end
71
74
 
72
75
  context 'when a new bar is created' do
73
76
  context 'and no options are passed' do
74
- before { @progressbar = ProgressBar::Base.new }
77
+ let(:progressbar) { ProgressBar::Base.new }
75
78
 
76
79
  describe '#title' do
77
80
  it 'returns the default title' do
78
- @progressbar.send(:title).to_s.should eql ProgressBar::Base::DEFAULT_TITLE
81
+ progressbar.send(:title).to_s.should eql ProgressBar::Base::DEFAULT_TITLE
79
82
  end
80
83
  end
81
84
 
82
85
  describe '#output' do
83
86
  it 'returns the default output stream' do
84
- @progressbar.send(:output).should eql ProgressBar::Base::DEFAULT_OUTPUT_STREAM
87
+ progressbar.send(:output).should eql ProgressBar::Base::DEFAULT_OUTPUT_STREAM
85
88
  end
86
89
  end
87
90
 
@@ -91,8 +94,8 @@ describe ProgressBar::Base do
91
94
  after { ENV['RUBY_PROGRESS_BAR_LENGTH'] = nil }
92
95
 
93
96
  it 'returns the length of the environment variable as an integer' do
94
- @progressbar = ProgressBar::Base.new
95
- @progressbar.send(:length).should eql 44
97
+ progressbar = ProgressBar::Base.new
98
+ progressbar.send(:length).should eql 44
96
99
  end
97
100
  end
98
101
 
@@ -101,22 +104,22 @@ describe ProgressBar::Base do
101
104
 
102
105
  context 'but the length option was passed in' do
103
106
  it 'returns the length specified in the option' do
104
- @progressbar = ProgressBar::Base.new(:length => 88)
105
- @progressbar.send(:length).should eql 88
107
+ progressbar = ProgressBar::Base.new(:length => 88)
108
+ progressbar.send(:length).should eql 88
106
109
  end
107
110
  end
108
111
 
109
112
  context 'and no length option was passed in' do
110
113
  it 'returns the width of the terminal if it is a Unix environment' do
111
- @progressbar.stub(:terminal_width).and_return(99)
112
- @progressbar.send(:reset_length)
113
- @progressbar.send(:length).should eql 99
114
+ progressbar.stub(:terminal_width).and_return(99)
115
+ progressbar.send(:reset_length)
116
+ progressbar.send(:length).should eql 99
114
117
  end
115
118
 
116
119
  it 'returns 80 if it is not a Unix environment' do
117
- @progressbar.stub(:unix?).and_return(false)
118
- @progressbar.send(:reset_length)
119
- @progressbar.send(:length).should eql 80
120
+ progressbar.stub(:unix?).and_return(false)
121
+ progressbar.send(:reset_length)
122
+ progressbar.send(:length).should eql 80
120
123
  end
121
124
  end
122
125
  end
@@ -124,23 +127,23 @@ describe ProgressBar::Base do
124
127
  end
125
128
 
126
129
  context 'and options are passed' do
127
- before { @progressbar = ProgressBar::Base.new(:title => 'We All Float', :total => 12, :output => STDOUT, :progress_mark => 'x', :length => 88, :starting_at => 5) }
130
+ let(:progressbar) { ProgressBar::Base.new(:title => 'We All Float', :total => 12, :output => STDOUT, :progress_mark => 'x', :length => 88, :starting_at => 5) }
128
131
 
129
132
  describe '#title' do
130
133
  it 'returns the overridden title' do
131
- @progressbar.send(:title).to_s.should eql 'We All Float'
134
+ progressbar.send(:title).to_s.should eql 'We All Float'
132
135
  end
133
136
  end
134
137
 
135
138
  describe '#output' do
136
139
  it 'returns the overridden output stream' do
137
- @progressbar.send(:output).should eql STDOUT
140
+ progressbar.send(:output).should eql STDOUT
138
141
  end
139
142
  end
140
143
 
141
144
  describe '#length' do
142
145
  it 'returns the overridden length' do
143
- @progressbar.send(:length).should eql 88
146
+ progressbar.send(:length).should eql 88
144
147
  end
145
148
  end
146
149
  end
@@ -148,170 +151,267 @@ describe ProgressBar::Base do
148
151
  context 'if the bar was started 4 minutes ago' do
149
152
  before do
150
153
  Timecop.travel(-240) do
151
- @progressbar.start
154
+ progressbar.start
152
155
  end
153
156
  end
154
157
 
155
158
  context 'and within 2 minutes it was halfway done' do
156
159
  before do
157
160
  Timecop.travel(-120) do
158
- 50.times { @progressbar.increment }
161
+ 50.times { progressbar.increment }
159
162
  end
160
163
  end
161
164
 
162
165
  describe '#finish' do
163
166
  before do
164
167
  Timecop.travel(-120) do
165
- @progressbar.finish
168
+ progressbar.finish
166
169
  end
167
170
  end
168
171
 
169
172
  it 'completes the bar' do
170
- @output.rewind
171
- @output.read.should match /Progress: \|#{'=' * 68}\|\n/
173
+ output.rewind
174
+ output.read.should match /Progress: \|#{'=' * 68}\|\n/
172
175
  end
173
176
 
174
177
  it 'shows the elapsed time instead of the estimated time since the bar is completed' do
175
- @progressbar.to_s('%e').should eql 'Time: 00:02:00'
178
+ progressbar.to_s('%e').should eql 'Time: 00:02:00'
176
179
  end
177
180
 
178
181
  it 'calculates the elapsed time to 00:02:00' do
179
- @progressbar.to_s('%a').should eql 'Time: 00:02:00'
182
+ progressbar.to_s('%a').should eql 'Time: 00:02:00'
180
183
  end
181
184
  end
182
185
  end
183
186
  end
184
187
 
188
+ context 'which includes ANSI SGR codes in the format string' do
189
+ it 'properly calculates the length of the bar by removing the long version of the ANSI codes from the calculated length' do
190
+ @color_code = "\e[0m\e[32m\e[7m\e[1m"
191
+ @reset_code = "\e[0m"
192
+ @progress_mark = "#{@color_code} #{@reset_code}"
193
+ progressbar = ProgressBar::Base.new(:format => "#{@color_code}Processing... %b%i#{@reset_code}#{@color_code} %p%%#{@reset_code}",
194
+ :progress_mark => @progress_mark,
195
+ :output => output,
196
+ :length => 24,
197
+ :starting_at => 3,
198
+ :total => 6,
199
+ :throttle_rate => 0.0)
200
+
201
+ progressbar.increment
202
+ progressbar.increment
203
+
204
+ output.rewind
205
+ output.read.should 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"
206
+ end
207
+
208
+ it 'properly calculates the length of the bar by removing the short version of the ANSI codes from the calculated length' do
209
+ @color_code = "\e[0;32;7;1m"
210
+ @reset_code = "\e[0m"
211
+ @progress_mark = "#{@color_code} #{@reset_code}"
212
+ progressbar = ProgressBar::Base.new(:format => "#{@color_code}Processing... %b%i#{@reset_code}#{@color_code} %p%%#{@reset_code}",
213
+ :progress_mark => @progress_mark,
214
+ :output => output,
215
+ :length => 24,
216
+ :starting_at => 3,
217
+ :total => 6,
218
+ :throttle_rate => 0.0)
219
+
220
+ progressbar.increment
221
+ progressbar.increment
222
+
223
+ output.rewind
224
+ output.read.should 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"
225
+ end
226
+ end
227
+
185
228
  context 'for a TTY enabled device' do
186
229
  it 'can log messages' do
187
- @progressbar = ProgressBar::Base.new(:output => @output, :length => 20, :starting_at => 3, :total => 6, :throttle_rate => 0.0)
188
- @progressbar.increment
189
- @progressbar.log 'We All Float'
190
- @progressbar.increment
230
+ progressbar = ProgressBar::Base.new(:output => output, :length => 20, :starting_at => 3, :total => 6, :throttle_rate => 0.0)
231
+ progressbar.increment
232
+ progressbar.log 'We All Float'
233
+ progressbar.increment
191
234
 
192
- @output.rewind
193
- @output.read.should include "Progress: |==== |\rProgress: |===== |\r \rWe All Float\nProgress: |===== |\rProgress: |====== |\r"
235
+ output.rewind
236
+ output.read.should include "Progress: |==== |\rProgress: |===== |\r \rWe All Float\nProgress: |===== |\rProgress: |====== |\r"
194
237
  end
195
238
  end
196
239
 
197
240
  context 'for a non-TTY enabled device' do
198
241
  it 'can log messages' do
199
- @progressbar = ProgressBar::Base.new(:output => @non_tty_output, :length => 20, :starting_at => 4, :total => 6, :throttle_rate => 0.0)
200
- @progressbar.increment
201
- @progressbar.log 'We All Float'
202
- @progressbar.increment
203
- @progressbar.finish
242
+ progressbar = ProgressBar::Base.new(:output => non_tty_output, :length => 20, :starting_at => 4, :total => 6, :throttle_rate => 0.0)
243
+ progressbar.increment
244
+ progressbar.log 'We All Float'
245
+ progressbar.increment
246
+ progressbar.finish
247
+
248
+ non_tty_output.rewind
249
+ non_tty_output.read.should include "We All Float\nProgress: |========|\n"
250
+ end
251
+
252
+ it 'can output the bar properly so that it does not spam the screen' do
253
+ progressbar = ProgressBar::Base.new(:output => non_tty_output, :length => 20, :starting_at => 0, :total => 6, :throttle_rate => 0.0)
254
+
255
+ 6.times { progressbar.increment }
256
+
257
+ non_tty_output.rewind
258
+ non_tty_output.read.should eql "\n\nProgress: |========|\n"
259
+ end
260
+
261
+ it 'can output the bar properly if finished in the middle of its progress' do
262
+ progressbar = ProgressBar::Base.new(:output => non_tty_output, :length => 20, :starting_at => 0, :total => 6, :throttle_rate => 0.0)
263
+
264
+ 3.times { progressbar.increment }
265
+
266
+ progressbar.finish
267
+
268
+ non_tty_output.rewind
269
+ non_tty_output.read.should eql "\n\nProgress: |========|\n"
270
+ end
271
+
272
+ it 'can output the bar properly if stopped in the middle of its progress' do
273
+ progressbar = ProgressBar::Base.new(:output => non_tty_output, :length => 20, :starting_at => 0, :total => 6, :throttle_rate => 0.0)
274
+
275
+ 3.times { progressbar.increment }
204
276
 
205
- @non_tty_output.rewind
206
- @non_tty_output.read.should include "We All Float\nProgress: |========|\n"
277
+ progressbar.stop
278
+
279
+ non_tty_output.rewind
280
+ non_tty_output.read.should eql "\n\nProgress: |====\n"
207
281
  end
208
282
  end
209
283
  end
210
284
 
211
285
  context 'when a bar is about to be completed' do
212
- before do
213
- @progressbar = ProgressBar::Base.new(:starting_at => 99, :total => 100, :output => @output, :length => 80)
214
- end
286
+ let(:progressbar) { ProgressBar::Base.new(:starting_at => 5, :total => 6, :output => output, :length => 20) }
215
287
 
216
288
  context 'and it is incremented' do
217
- before { @progressbar.increment }
289
+ before { progressbar.increment }
218
290
 
219
291
  it 'registers as being "finished"' do
220
- @progressbar.should be_finished
292
+ progressbar.should be_finished
221
293
  end
222
294
 
223
295
  it 'prints a new line' do
224
- @output.rewind
225
- @output.read.end_with?("\n").should be_true
296
+ output.rewind
297
+ output.read.end_with?("\n").should be_true
298
+ end
299
+
300
+ it 'does not continue to print bars if finish is subsequently called' do
301
+ progressbar.finish
302
+
303
+ output.rewind
304
+ output.read.should end_with " \rProgress: |====== |\rProgress: |========|\n"
226
305
  end
227
306
  end
228
307
  end
229
308
 
230
309
  context 'when a bar has an unknown amount to completion' do
231
- before do
232
- @progressbar = ProgressBar::Base.new(:total => nil, :output => @output, :length => 80, :unknown_progress_animation_steps => ['=--', '-=-', '--='])
233
- end
310
+ let(:progressbar) { ProgressBar::Base.new(:total => nil, :output => output, :length => 80, :unknown_progress_animation_steps => ['=--', '-=-', '--=']) }
234
311
 
235
312
  it 'is represented correctly' do
236
- @progressbar.to_s('%i').should eql '=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=-'
313
+ progressbar.to_s('%i').should eql '=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=-'
237
314
  end
238
315
 
239
316
  it 'is represented after being incremented once' do
240
- @progressbar.increment
241
- @progressbar.to_s('%i').should eql '-=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--='
317
+ progressbar.increment
318
+ progressbar.to_s('%i').should eql '-=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--='
242
319
  end
243
320
 
244
321
  it 'is represented after being incremented twice' do
245
- @progressbar.increment
246
- @progressbar.increment
247
- @progressbar.to_s('%i').should eql '--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--'
322
+ progressbar.increment
323
+ progressbar.increment
324
+ progressbar.to_s('%i').should eql '--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--'
248
325
  end
249
326
 
250
327
  it 'displays the proper ETA' do
251
- @progressbar.to_s('%i%e').should eql '=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=-- ETA: ??:??:??'
328
+ progressbar.to_s('%i%e').should eql '=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=-- ETA: ??:??:??'
252
329
  end
253
330
  end
254
331
 
255
332
  context 'when a bar is started' do
256
- before do
257
- @progressbar = ProgressBar::Base.new(:starting_at => 0, :total => 100, :output => @output, :length => 80, :throttle_rate => 0.0)
258
- end
333
+ let(:progressbar) { ProgressBar::Base.new(:starting_at => 0, :total => 100, :output => output, :length => 80, :throttle_rate => 0.0) }
259
334
 
260
335
  context 'and it is incremented any number of times' do
261
- before { 10.times { @progressbar.increment } }
336
+ before { 10.times { progressbar.increment } }
262
337
 
263
338
  describe '#progress_mark=' do
264
339
  it 'changes the mark used to represent progress and updates the output' do
265
- @progressbar.progress_mark = 'x'
340
+ progressbar.progress_mark = 'x'
341
+
342
+ output.rewind
343
+ output.read.should match /\rProgress: \|xxxxxx#{' ' * 62}\|\r\z/
344
+ end
345
+ end
346
+
347
+ describe '#remainder_mark=' do
348
+ it 'changes the mark used to represent the remaining part of the bar and updates the output' do
349
+ progressbar.remainder_mark = 'x'
266
350
 
267
- @output.rewind
268
- @output.read.should match /\rProgress: \|xxxxxx#{' ' * 62}\|\r\z/
351
+ output.rewind
352
+ output.read.should match /\rProgress: \|======#{'x' * 62}\|\r\z/
269
353
  end
270
354
  end
271
355
 
272
356
  describe '#title=' do
273
357
  it 'changes the title used to represent the items being progressed and updates the output' do
274
- @progressbar.title = 'Items'
358
+ progressbar.title = 'Items'
275
359
 
276
- @output.rewind
277
- @output.read.should match /\rItems: \|=======#{' ' * 64}\|\r\z/
360
+ output.rewind
361
+ output.read.should match /\rItems: \|=======#{' ' * 64}\|\r\z/
278
362
  end
279
363
  end
280
364
 
281
365
  describe '#reset' do
282
- before { @progressbar.reset }
366
+ before { progressbar.reset }
283
367
 
284
368
  it 'resets the bar back to the starting value' do
285
- @output.rewind
286
- @output.read.should match /\rProgress: \|#{' ' * 68}\|\r\z/
369
+ output.rewind
370
+ output.read.should match /\rProgress: \|#{' ' * 68}\|\r\z/
287
371
  end
288
372
  end
289
373
 
290
374
  describe '#stop' do
291
- before { @progressbar.stop }
375
+ before { progressbar.stop }
292
376
 
293
377
  it 'forcibly halts the bar wherever it is and cancels it' do
294
- @output.rewind
295
- @output.read.should match /\rProgress: \|======#{' ' * 62}\|\n\z/
378
+ output.rewind
379
+ output.read.should match /\rProgress: \|======#{' ' * 62}\|\n\z/
380
+ end
381
+
382
+ it 'does not output the bar multiple times if the bar is already stopped' do
383
+ output.rewind
384
+ progressbar.stop
385
+ output.rewind
386
+
387
+ output.read.should_not start_with "Progress: |======#{' ' * 62}|"
388
+ end
389
+ end
390
+
391
+ describe '#resume' do
392
+ it 'does not output the bar multiple times' do
393
+ output.rewind
394
+ progressbar.resume
395
+ output.rewind
396
+
397
+ output.read.should_not start_with "Progress: |======#{' ' * 62}|"
296
398
  end
297
399
  end
298
400
  end
299
401
  end
300
402
 
301
403
  context 'when a bar is started from 10/100' do
302
- before do
303
- @progressbar = ProgressBar::Base.new(:starting_at => 10, :total => 100, :output => @output, :length => 112)
304
- end
404
+ let(:progressbar) { ProgressBar::Base.new(:starting_at => 10, :total => 100, :output => output, :length => 112) }
305
405
 
306
406
  context 'and it is incremented any number of times' do
307
- before { 10.times { @progressbar.increment } }
407
+ before { 10.times { progressbar.increment } }
308
408
 
309
409
  describe '#reset' do
310
- before { @progressbar.reset }
410
+ before { progressbar.reset }
311
411
 
312
412
  it 'resets the bar back to the starting value' do
313
- @output.rewind
314
- @output.read.should match /\rProgress: \|==========#{' ' * 90}\|\r\z/
413
+ output.rewind
414
+ output.read.should match /\rProgress: \|==========#{' ' * 90}\|\r\z/
315
415
  end
316
416
  end
317
417
  end
@@ -319,246 +419,248 @@ describe ProgressBar::Base do
319
419
 
320
420
  describe '#clear' do
321
421
  it 'clears the current terminal line and/or bar text' do
322
- @progressbar.clear
422
+ progressbar.clear
323
423
 
324
- @output.rewind
325
- @output.read.should match /^#{@progressbar.send(:clear_string)}/
424
+ output.rewind
425
+ output.read.should match /^#{progressbar.send(:clear_string)}/
326
426
  end
327
427
  end
328
428
 
329
429
  describe '#start' do
330
430
  it 'clears the current terminal line' do
331
- @progressbar.start
431
+ progressbar.start
332
432
 
333
- @output.rewind
334
- @output.read.should match /^#{@progressbar.send(:clear_string)}/
433
+ output.rewind
434
+ output.read.should match /^#{progressbar.send(:clear_string)}/
335
435
  end
336
436
 
337
437
  it 'prints the bar for the first time' do
338
- @progressbar.start
438
+ progressbar.start
339
439
 
340
- @output.rewind
341
- @output.read.should match /Progress: \| \|\r\z/
440
+ output.rewind
441
+ output.read.should match /Progress: \| \|\r\z/
342
442
  end
343
443
 
344
444
  it 'prints correctly if passed a position to start at' do
345
- @progressbar.start(:at => 20)
445
+ progressbar.start(:at => 20)
346
446
 
347
- @output.rewind
348
- @output.read.should match /Progress: \|============= \|\r\z/
447
+ output.rewind
448
+ output.read.should match /Progress: \|============= \|\r\z/
349
449
  end
350
450
  end
351
451
 
352
452
  context 'when the bar has not been completed' do
353
- before { @progressbar = ProgressBar::Base.new(:length => 112, :starting_at => 0, :total => 50, :output => @output, :throttle_rate => 0.0) }
453
+ let(:progressbar) { ProgressBar::Base.new(:length => 112, :starting_at => 0, :total => 50, :output => output, :throttle_rate => 0.0) }
354
454
 
355
455
  describe '#increment' do
356
- before { @progressbar.increment }
456
+ before { progressbar.increment }
357
457
 
358
458
  it 'displays the bar with the correct formatting' do
359
- @output.rewind
360
- @output.read.should match /Progress: \|== \|\r\z/
459
+ output.rewind
460
+ output.read.should match /Progress: \|== \|\r\z/
361
461
  end
362
462
  end
363
463
  end
364
464
 
365
465
  context 'when a new bar is created with a specific format' do
366
466
  context '#format' do
367
- before { @progressbar = ProgressBar::Base.new(:format => '%B %p%%') }
467
+ let(:progressbar) { ProgressBar::Base.new(:format => '%B %p%%') }
368
468
 
369
469
  context 'if called with no arguments' do
370
- before { @progressbar.format }
470
+ before { progressbar.format }
371
471
 
372
472
  it 'resets the format back to the default' do
373
- @progressbar.to_s.should match /^Progress: \|\s+\|\z/
473
+ progressbar.to_s.should match /^Progress: \|\s+\|\z/
374
474
  end
375
475
  end
376
476
 
377
477
  context 'if called with a specific format string' do
378
- before { @progressbar.format '%t' }
478
+ before { progressbar.format '%t' }
379
479
 
380
480
  it 'sets it as the new format for the bar' do
381
- @progressbar.to_s.should match /^Progress\z/
481
+ progressbar.to_s.should match /^Progress\z/
382
482
  end
383
483
  end
384
484
  end
385
485
 
386
486
  context '#to_s' do
387
487
  it 'displays the title when passed the "%t" format flag' do
388
- @progressbar.to_s('%t').should match /^Progress\z/
488
+ progressbar.to_s('%t').should match /^Progress\z/
389
489
  end
390
490
 
391
491
  it 'displays the title when passed the "%T" format flag' do
392
- @progressbar.to_s('%T').should match /^Progress\z/
492
+ progressbar.to_s('%T').should match /^Progress\z/
393
493
  end
394
494
 
395
495
  it 'displays the bar when passed the "%B" format flag (including empty space)' do
396
- @progressbar = ProgressBar::Base.new(:length => 100, :starting_at => 20)
397
- @progressbar.to_s('%B').should match /^#{'=' * 20}#{' ' * 80}\z/
496
+ progressbar = ProgressBar::Base.new(:length => 100, :starting_at => 20)
497
+ progressbar.to_s('%B').should match /^#{'=' * 20}#{' ' * 80}\z/
398
498
  end
399
499
 
400
500
  it 'displays the bar when passed the combined "%b%i" format flags' do
401
- @progressbar = ProgressBar::Base.new(:length => 100, :starting_at => 20)
402
- @progressbar.to_s('%b%i').should match /^#{'=' * 20}#{' ' * 80}\z/
501
+ progressbar = ProgressBar::Base.new(:length => 100, :starting_at => 20)
502
+ progressbar.to_s('%b%i').should match /^#{'=' * 20}#{' ' * 80}\z/
403
503
  end
404
504
 
405
505
  it 'displays the bar when passed the "%b" format flag (excluding empty space)' do
406
- @progressbar = ProgressBar::Base.new(:length => 100, :starting_at => 20)
407
- @progressbar.to_s('%b').should match /^#{'=' * 20}\z/
506
+ progressbar = ProgressBar::Base.new(:length => 100, :starting_at => 20)
507
+ progressbar.to_s('%b').should match /^#{'=' * 20}\z/
408
508
  end
409
509
 
410
510
  it 'displays the incomplete space when passed the "%i" format flag' do
411
- @progressbar = ProgressBar::Base.new(:length => 100, :starting_at => 20)
412
- @progressbar.to_s('%i').should match /^#{' ' * 80}\z/
511
+ progressbar = ProgressBar::Base.new(:length => 100, :starting_at => 20)
512
+ progressbar.to_s('%i').should match /^#{' ' * 80}\z/
413
513
  end
414
514
 
415
515
  it 'displays the bar when passed the "%w" format flag' do
416
- @progressbar = ProgressBar::Base.new(:output => @output, :length => 100, :starting_at => 0)
516
+ progressbar = ProgressBar::Base.new(:output => output, :length => 100, :starting_at => 0)
417
517
 
418
- @progressbar.to_s('%w').should match /^\z/
419
- 4.times { @progressbar.increment }
420
- @progressbar.to_s('%w').should match /^====\z/
421
- @progressbar.increment
422
- @progressbar.to_s('%w').should match /^= 5 =\z/
423
- 5.times { @progressbar.increment }
424
- @progressbar.to_s('%w').should match /^=== 10 ===\z/
425
- @progressbar.decrement
426
- @progressbar.to_s('%w').should match /^=== 9 ===\z/
427
- 91.times { @progressbar.increment }
428
- @progressbar.to_s('%w').should match /^#{'=' * 47} 100 #{'=' * 48}\z/
518
+ progressbar.to_s('%w').should match /^\z/
519
+ 4.times { progressbar.increment }
520
+ progressbar.to_s('%w').should match /^====\z/
521
+ progressbar.increment
522
+ progressbar.to_s('%w').should match /^= 5 =\z/
523
+ 5.times { progressbar.increment }
524
+ progressbar.to_s('%w').should match /^=== 10 ===\z/
525
+ progressbar.decrement
526
+ progressbar.to_s('%w').should match /^=== 9 ===\z/
527
+ 91.times { progressbar.increment }
528
+ progressbar.to_s('%w').should match /^#{'=' * 47} 100 #{'=' * 48}\z/
429
529
  end
430
530
 
431
531
  it 'calculates the remaining negative space properly with an integrated percentage bar of 0 percent' do
432
- @progressbar = ProgressBar::Base.new(:output => @output, :length => 100, :total => 200, :starting_at => 0)
532
+ progressbar = ProgressBar::Base.new(:output => output, :length => 100, :total => 200, :starting_at => 0)
433
533
 
434
- @progressbar.to_s('%w%i').should match /^\s{100}\z/
435
- 9.times { @progressbar.increment }
436
- @progressbar.to_s('%w%i').should match /^====\s{96}\z/
437
- @progressbar.increment
438
- @progressbar.to_s('%w%i').should match /^= 5 =\s{95}\z/
534
+ progressbar.to_s('%w%i').should match /^\s{100}\z/
535
+ 9.times { progressbar.increment }
536
+ progressbar.to_s('%w%i').should match /^====\s{96}\z/
537
+ progressbar.increment
538
+ progressbar.to_s('%w%i').should match /^= 5 =\s{95}\z/
439
539
  end
440
540
 
441
541
  it 'displays the current capacity when passed the "%c" format flag' do
442
- @progressbar = ProgressBar::Base.new(:output => @output, :starting_at => 0)
542
+ progressbar = ProgressBar::Base.new(:output => output, :starting_at => 0)
443
543
 
444
- @progressbar.to_s('%c').should match /^0\z/
445
- @progressbar.increment
446
- @progressbar.to_s('%c').should match /^1\z/
447
- @progressbar.decrement
448
- @progressbar.to_s('%c').should match /^0\z/
544
+ progressbar.to_s('%c').should match /^0\z/
545
+ progressbar.increment
546
+ progressbar.to_s('%c').should match /^1\z/
547
+ progressbar.decrement
548
+ progressbar.to_s('%c').should match /^0\z/
449
549
  end
450
550
 
451
551
  it 'displays the total capacity when passed the "%C" format flag' do
452
- @progressbar = ProgressBar::Base.new(:total => 100)
552
+ progressbar = ProgressBar::Base.new(:total => 100)
453
553
 
454
- @progressbar.to_s('%C').should match /^100\z/
554
+ progressbar.to_s('%C').should match /^100\z/
455
555
  end
456
556
 
457
557
  it 'displays the percentage complete when passed the "%p" format flag' do
458
- @progressbar = ProgressBar::Base.new(:starting_at => 33, :total => 200)
558
+ progressbar = ProgressBar::Base.new(:starting_at => 33, :total => 200)
459
559
 
460
- @progressbar.to_s('%p').should match /^16\z/
560
+ progressbar.to_s('%p').should match /^16\z/
461
561
  end
462
562
 
463
563
  it 'displays the percentage complete when passed the "%P" format flag' do
464
- @progressbar = ProgressBar::Base.new(:starting_at => 33, :total => 200)
564
+ progressbar = ProgressBar::Base.new(:starting_at => 33, :total => 200)
465
565
 
466
- @progressbar.to_s('%P').should match /^16.50\z/
566
+ progressbar.to_s('%P').should match /^16.50\z/
467
567
  end
468
568
 
469
569
  it 'displays only up to 2 decimal places when using the "%P" flag' do
470
- @progressbar = ProgressBar::Base.new(:starting_at => 66, :total => 99)
570
+ progressbar = ProgressBar::Base.new(:starting_at => 66, :total => 99)
471
571
 
472
- @progressbar.to_s('%P').should match /^66.66\z/
572
+ progressbar.to_s('%P').should match /^66.66\z/
473
573
  end
474
574
 
475
575
  it 'displays a literal percent sign when using the "%%" flag' do
476
- @progressbar = ProgressBar::Base.new(:starting_at => 66, :total => 99)
576
+ progressbar = ProgressBar::Base.new(:starting_at => 66, :total => 99)
477
577
 
478
- @progressbar.to_s('%%').should match /^%\z/
578
+ progressbar.to_s('%%').should match /^%\z/
479
579
  end
480
580
 
481
581
  it 'displays a literal percent sign when using the "%%" flag' do
482
- @progressbar = ProgressBar::Base.new(:starting_at => 66, :total => 99)
582
+ progressbar = ProgressBar::Base.new(:starting_at => 66, :total => 99)
483
583
 
484
- @progressbar.to_s('%%').should match /^%\z/
584
+ progressbar.to_s('%%').should match /^%\z/
485
585
  end
486
586
 
487
587
  # Autostarting for now. This will be applicable later.
488
588
  # context "when called before #start" do
489
589
  # it "displays unknown time elapsed when using the %a flag" do
490
- # @progressbar.to_s('%a').should match /^Time: --:--:--\z/
590
+ # progressbar.to_s('%a').should match /^Time: --:--:--\z/
491
591
  # end
492
592
  # end
493
593
 
494
594
  context 'when called after #start' do
495
595
  before do
496
596
  Timecop.travel(-3723) do
497
- @progressbar.start
597
+ progressbar.start
498
598
  end
499
599
  end
500
600
 
501
601
  context 'and the bar is reset' do
502
- before { @progressbar.reset }
602
+ before { progressbar.reset }
503
603
 
504
604
  it 'displays "??:??:??" until finished when passed the %e flag' do
505
- @progressbar.to_s('%a').should match /^Time: --:--:--\z/
605
+ progressbar.to_s('%a').should match /^Time: --:--:--\z/
506
606
  end
507
607
  end
508
608
 
509
609
  it 'displays the time elapsed when using the "%a" flag' do
510
- @progressbar.to_s('%a').should match /^Time: 01:02:03\z/
610
+ progressbar.to_s('%a').should match /^Time: 01:02:03\z/
511
611
  end
512
612
  end
513
613
 
514
614
  context 'when called before #start' do
515
615
  it 'displays unknown time until finished when passed the "%e" flag' do
516
- @progressbar = ProgressBar::Base.new
517
- @progressbar.to_s('%e').should match /^ ETA: \?\?:\?\?:\?\?\z/
616
+ progressbar = ProgressBar::Base.new
617
+ progressbar.to_s('%e').should match /^ ETA: \?\?:\?\?:\?\?\z/
518
618
  end
519
619
  end
520
620
 
521
621
  context 'when called after #start' do
522
- before do
622
+ let(:progressbar) do
523
623
  Timecop.travel(-3723) do
524
- @progressbar = ProgressBar::Base.new(:starting_at => 0, :output => @output, :smoothing => 0.0)
525
- @progressbar.start
526
- @progressbar.progress = 50
624
+ progressbar = ProgressBar::Base.new(:starting_at => 0, :output => output, :smoothing => 0.0)
625
+ progressbar.start
626
+ progressbar.progress = 50
627
+ progressbar
527
628
  end
528
629
  end
529
630
 
530
631
  context 'and the bar is reset' do
531
- before { @progressbar.reset }
632
+ before { progressbar.reset }
532
633
 
533
634
  it 'displays "??:??:??" until finished when passed the "%e" flag' do
534
- @progressbar.to_s('%e').should match /^ ETA: \?\?:\?\?:\?\?\z/
635
+ progressbar.to_s('%e').should match /^ ETA: \?\?:\?\?:\?\?\z/
535
636
  end
536
637
  end
537
638
 
538
639
  it 'displays the estimated time remaining when using the "%e" flag' do
539
- @progressbar.to_s('%e').should match /^ ETA: 01:02:02\z/
640
+ progressbar.to_s('%e').should match /^ ETA: 01:02:02\z/
540
641
  end
541
642
  end
542
643
 
543
644
  context 'when it could take 100 hours or longer to finish' do
544
- before do
645
+ let(:progressbar) do
545
646
  Timecop.travel(-120000) do
546
- @progressbar = ProgressBar::Base.new(:starting_at => 0, :total => 100, :output => @output, :smoothing => 0.0)
547
- @progressbar.start
548
- @progressbar.progress = 25
647
+ progressbar = ProgressBar::Base.new(:starting_at => 0, :total => 100, :output => output, :smoothing => 0.0)
648
+ progressbar.start
649
+ progressbar.progress = 25
650
+ progressbar
549
651
  end
550
652
  end
551
653
 
552
654
  it 'displays "> 4 Days" until finished when passed the "%E" flag' do
553
- @progressbar.to_s('%E').should match /^ ETA: > 4 Days\z/
655
+ progressbar.to_s('%E').should match /^ ETA: > 4 Days\z/
554
656
  end
555
657
 
556
658
  it 'displays "??:??:??" until finished when passed the "%e" flag' do
557
- @progressbar.to_s('%e').should match /^ ETA: \?\?:\?\?:\?\?\z/
659
+ progressbar.to_s('%e').should match /^ ETA: \?\?:\?\?:\?\?\z/
558
660
  end
559
661
 
560
662
  it 'displays the exact estimated time until finished when passed the "%f" flag' do
561
- @progressbar.to_s('%f').should match /^ ETA: 100:00:00\z/
663
+ progressbar.to_s('%f').should match /^ ETA: 100:00:00\z/
562
664
  end
563
665
  end
564
666
  end