ruby-progressbar 1.4.2 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 35cb162ef6a48d988df23e47ffe815580cb6258a
4
+ data.tar.gz: bf2ed1a84e032ebde941494682375c05da9117f2
5
+ SHA512:
6
+ metadata.gz: 12c2dfc60bd0339e7b643fc68e67018a5f9281a3bd719a4df0197fd0ec639e31c84d2108ddad0516b9df5eaf6ee8f35a303c65159f59dfc931cbecd97928cf38
7
+ data.tar.gz: d87e233863403cabd91c47eb73d20ab8e03250048638ba2042d50480ceb89b49a384fdb7c570b948941427785354d0d65b033db579633ea92bdfb6e00fa69c8a
data/README.md CHANGED
@@ -1,5 +1,6 @@
1
1
  Ruby/ProgressBar: A Text Progress Bar Library for Ruby
2
2
  ================================
3
+ [![Build Status](https://secure.travis-ci.org/jfelchner/ruby-progressbar.png?branch=master)](http://travis-ci.org/jfelchner/ruby-progressbar) [![Code Climate](https://codeclimate.com/github/jfelchner/ruby-progressbar.png)](https://codeclimate.com/github/jfelchner/ruby-progressbar) [![Code Climate](https://codeclimate.com/github/jfelchner/ruby-progressbar/coverage.png)](https://codeclimate.com/github/jfelchner/ruby-progressbar)
3
4
 
4
5
  The **ultimate** text progress bar library for Ruby! It'll **SMASH YOU OVER THE HEAD** with a **PURE RUSH** of progress bar excitement!
5
6
 
@@ -18,7 +19,7 @@ Supported Rubies
18
19
 
19
20
  It's Better Than The Other 186,312 Progress Bar Libraries Because...
20
21
  --------------------------------
21
- * Full test suite [![Build Status](https://secure.travis-ci.org/jfelchner/ruby-progressbar.png?branch=master)](http://travis-ci.org/jfelchner/ruby-progressbar)
22
+ * Full test suite [![Code Climate](https://codeclimate.com/github/jfelchner/ruby-progressbar/coverage.png)](https://codeclimate.com/github/jfelchner/ruby-progressbar)
22
23
  * _**ZERO**_ dependencies
23
24
  * Used by tons of other open source projects (which means we find out about bugs quickly)
24
25
  * It's pretty [freakin' sweet](https://www.youtube.com/watch?v=On3IoVhf_GM)
@@ -63,7 +64,7 @@ It's simple to get started:
63
64
  ProgressBar.create
64
65
  ```
65
66
 
66
- Creates a basic progress bar beginning at `0`, a total capacity of `100` and tells it to start.
67
+ Creates a basic progress bar beginning at `0`, a maximum capacity of `100` and tells it to start.
67
68
 
68
69
  Progress: | |
69
70
 
@@ -90,7 +91,7 @@ If you would like to customize your prompt, you can pass options when you call `
90
91
  ProgressBar.create(:title => "Items", :starting_at => 20, :total => 200)
91
92
  ```
92
93
 
93
- Will output:
94
+ This will output:
94
95
 
95
96
  Items: |======= |
96
97
 
@@ -114,7 +115,7 @@ The following are the list of options you can use:
114
115
  * `#decrement`: Will retract the bar's progress by `1` unit.
115
116
  * `#progress +=`: Will allow you to increment by a relative amount.
116
117
  * `#progress -=`: Will allow you to decrement by a relative amount.
117
- * `#progress=`: Will allow you to jump the amount of progress directly to whatever value you would like. _Note: This will almost always mess up your estimated time if you're using it._
118
+ * `#progress=`: Will set the bar's progress to whatever value you would like. _Note: This will likely mess up your estimated time if you're using it._
118
119
  * `#total=`: Will change the total number of items being processed by the bar. This can be anything (even nil) but cannot be less than the amount of progress already accumulated by the bar.
119
120
 
120
121
  ### Stopping
@@ -123,7 +124,7 @@ The bar can be stopped in four ways:
123
124
 
124
125
  * `#finish`: Will stop the bar by completing it immediately. The current position will be advanced to the total.
125
126
  * `#stop`: Will stop the bar by immediately cancelling it. The current position will remain where it is.
126
- * `#pause`: Will stop the bar similar to `#stop` but will allow it to be restarted where it previously left off by calling `#resume`. _Note: Elapsed Time and Estimated Time will stop being affected while the bar is paused._
127
+ * `#pause`: Will stop the bar like `#stop` but will allow it to be restarted from where it previously left off by calling `#resume`. _Note: Elapsed Time and Estimated Time will stop being affected while the bar is paused._
127
128
  * `#reset`: Will stop the bar by resetting all information. The current position of the bar will be reset to where it began when it was created. _(eg if you passed `:starting_at => 5` when you created the bar, it would reset to `5` and not `0`)_
128
129
 
129
130
  ### Finishing
@@ -134,11 +135,11 @@ _Note: The bar will be finished automatically if the current value ever becomes
134
135
 
135
136
  ### Refreshing
136
137
 
137
- * If you need to have the bar be redisplayed to give your users more of a "real-time" feel, you can call `#refresh` which will not affect the current position but will update the elapsed and estimated timers.
138
+ * If you need to redisplay the progress bar to give your users a "real-time" feel, you can call `#refresh`. `#refresh` will not affect the current position but will update the elapsed and estimated timers.
138
139
 
139
140
  ### Unknown Progress
140
141
 
141
- Sometimes when processing work, you don't know at the beginning of the job exactly how many items you will be processing. Maybe this might be because you're downloading a chunked file or processing a set of jobs that hasn't fully loaded yet.
142
+ Sometimes when processing work, you don't know exactly how many items you will need to process. This might be because you're downloading a chunked file or because you're processing a set of jobs that hasn't been fully loaded yet.
142
143
 
143
144
  In times like these, you can set total to `nil` and continue to increment the bar as usual. The bar will display an 'unknown' animation which will change every time you increment. This will give the appearance (by default) that the bar is processing work even though there is no "progress".
144
145
 
@@ -174,12 +175,12 @@ And the bar will magically transform into its typical state:
174
175
 
175
176
  ### Logging
176
177
 
177
- Many times while using the progress bar, you may wish to log some output for the user. If you attempt to do this using a standard `puts` statement, you'll find that the text will overwrite that which makes up the bar. For example if you were to `puts "hello"` after progress has already begun, you may get something like this:
178
+ While using the progress bar, you may wish to log some output for the user. If you attempt to do this using a standard `puts` statement, you'll find that the text will overwrite the bar. For example if you were to `puts "hello"` after progress has already begun, you may get something like this:
178
179
 
179
180
  helloess: |======= |
180
181
  Progress: |======== |
181
182
 
182
- The reason is that ruby-progressbar has to keep redrawing itself every time you change the progress. It's a limitation of terminal output. Using `puts` messes that up because `puts` adds a newline which moves the cursor to the next line, then when ruby-progressbar updates, it does so on the following line.
183
+ This happens because the ruby-progressbar has to keep redrawing itself every time you change the progress. It's a limitation of terminal output. Using `puts` messes that up because `puts` adds a newline which moves the cursor to the next line, then when ruby-progressbar updates, it does so on the following line.
183
184
 
184
185
  To circumvent this, use `#log` instead.
185
186
 
@@ -192,7 +193,7 @@ progressbar.log 'hello'
192
193
  hello
193
194
  Progress: |============= |
194
195
 
195
- `#log` will automatically clear the bar, print your desired text and then redraw the bar on the following line. Notice that we did not get a bar **above** the logged output. If you consistently use `#log`, you should only every see one bar on the screen at any time.
196
+ `#log` will automatically clear the bar, print your desired text and then redraw the bar on the following line. Notice that we did not get a bar **above** the logged output. If you consistently use `#log`, you should only ever see one bar on the screen at any time.
196
197
 
197
198
  Formatting
198
199
  --------------------------------
@@ -213,6 +214,8 @@ The flags you can use in the format string are as follows:
213
214
  * `%B`: The full progress bar including 'incomplete' space (eg: `========== `)
214
215
  * `%b`: Progress bar only (eg: `==========`)
215
216
  * `%w`: Bar With Integrated Percentage (eg: `==== 75 ====`)
217
+ * `%r`: Rate of Progress as a whole number (eg: `13`)
218
+ * `%R`: Rate of Progress as a decimal number (eg: `13.67`)
216
219
  * `%i`: Display the incomplete space of the bar (this string will only contain whitespace eg: ` `)
217
220
  * `%%`: A literal percent sign `%`
218
221
 
@@ -268,13 +271,13 @@ Becomes **PAC-MAN**!
268
271
 
269
272
  ### Overriding the Length
270
273
 
271
- By default, the progressbar will try to be as smart as possible about how wide it can be. Under most Unix systems, it should be as wide as the terminal will allow while still fitting on one line. If you wish to override this behavior, you can pass in the `:length` option when creating the bar like so:
274
+ By default, the progress bar will try to be as smart as possible about how wide it can be. Under most Unix systems, it should be as wide as the terminal will allow while still fitting on one line. If you wish to override this behavior, you can pass in the `:length` option when creating the bar:
272
275
 
273
276
  ```ruby
274
277
  ProgressBar.create(:length => 40)
275
278
  ```
276
279
 
277
- Additionally, if you don't have access to the code calling the progressbar itself (say if you're using a gem like Fuubar), you can set the `RUBY_PROGRESS_BAR_LENGTH` environment variable and it will always override any other setting.
280
+ If you don't have access to the code calling the progress bar itself (say if you're using a gem like Fuubar), you can set the `RUBY_PROGRESS_BAR_LENGTH` environment variable and it will override any other setting.
278
281
 
279
282
  _Note: If the terminal width is less than 20 characters or ruby-progressbar is being used on a non-*nix system, the bar will default to an 80 character width._
280
283
 
@@ -287,6 +290,27 @@ The following items can be set at any time. Changes cause an immediate bar refr
287
290
  * `#title=`: Sets the string used to represent the items the bar is tracking (or I guess whatever else you want it to be).
288
291
  * `#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).
289
292
 
293
+ ### Rate Scaling
294
+
295
+ By default the rate shown on the progress bar is shown as the number of items
296
+ processed per second. Often times, you won't want to display the literal number
297
+ of items, but rather scale it in some way. For example, if you're displaying
298
+ the progress of a file being transferred, and you are representing the bar as
299
+ the number of bytes in the file, by default the `%r` formatter will show the
300
+ number of bytes per second.
301
+
302
+ If instead of the bytes per second you wanted to show the user the number of
303
+ kilobytes per second, you can do that like so:
304
+
305
+ ```ruby
306
+ ProgressBar.create(:format => '%a %B %p%% %r KB/sec',
307
+ :rate_scale => lambda { |rate| rate / 1024 })
308
+ ```
309
+
310
+ Now, when the bar is displayed it will look something like so:
311
+
312
+ Time: --:--:-- =============== 40% - 102 KB/sec
313
+
290
314
  ## In The Weeds
291
315
 
292
316
  This is some stuff that makes ruby-progressbar extra awesome, but for the most part it "Just Works" and you won't have to even know it's there, but if you're curious like us, here it is.
@@ -295,11 +319,11 @@ This is some stuff that makes ruby-progressbar extra awesome, but for the most p
295
319
 
296
320
  #### Smoothing Out Estimated Time Jitters
297
321
 
298
- Sometimes when you're tracking progress, you could have some items which take significantly longer than others. When this is the case, the ETA gauge can vary wildly from increment to increment.
322
+ Sometimes when you're tracking progress, you might have some items which take significantly longer than others to complete. When this is the case, the ETA gauge can vary wildly from increment to increment.
299
323
 
300
324
  __RUBY PROGRESS BAR TO THE RESCUE!__
301
325
 
302
- Thanks to [@L2G](https://github.com/L2G) and 'the maths' you can pass the `:smoothing` option when creating a new bar and it will use an exponentially smoothed average rather than a linear one. A value of `0.0` means no smoothing and is equivalent to the classic behavior. A value of `1.0` is the maximum amount of smoothing. Any values between those two are valid. `0.1` is the default.
326
+ Thanks to [@L2G](https://github.com/L2G) and 'the maths' you can pass the `:smoothing` option when creating a new bar. Your progress bar will then use an exponentially smoothed average rather than a linear one. A value of `0.0` means no smoothing and is equivalent to the classic behavior. A value of `1.0` is the maximum amount of smoothing. Any values between those two are valid. The default value is `0.1`.
303
327
 
304
328
  ```ruby
305
329
  ProgressBar.create(:smoothing => 0.6)
@@ -307,7 +331,7 @@ ProgressBar.create(:smoothing => 0.6)
307
331
 
308
332
  #### Time Mocking Support
309
333
 
310
- When mocking time, the concept of when `now` is becomes distorted. You can imagine that because ruby-progressbar tracks elapsed and estimated times, if it used the mocked version of `now` the results would be very undesirable. Fortunately, if you use one of our supported Ruby time mocking libraries, your elapsed and estimated times will appear correctly no matter when your 'now' is. Currently supported are:
334
+ When mocking time, the concept of when `now` is becomes distorted. You can imagine that because ruby-progressbar tracks elapsed and estimated times, if it used the mocked version of `now` the results would be very undesirable. But, if you use one of our supported Ruby time mocking libraries, your elapsed and estimated times will always appear correctly. Currently supported are:
311
335
 
312
336
  * [Timecop](https://github.com/jtrupiano/timecop)
313
337
  * [Delorean](https://github.com/bebanjo/delorean)
@@ -316,17 +340,19 @@ When mocking time, the concept of when `now` is becomes distorted. You can imag
316
340
 
317
341
  When reporting progress of large amounts of very fast operations, whose duration is comparable to the output time of a progress bar, it becomes desirable to throttle output to the console and only perform it once in a set period. ProgressBar supports throttling if given `:throttle_rate` option:
318
342
 
319
- ProgressBar.create(:throttle_rate => 0.1)
343
+ ```ruby
344
+ ProgressBar.create(:throttle_rate => 0.1)
345
+ ```
320
346
 
321
347
  The above progress bar will output at most 10 times a second.
322
348
 
323
- The default throttling rate if none is specified is 100 times per second (or 0.01)
349
+ The default throttling rate is 100 times per second (or 0.01)
324
350
 
325
351
  ### Custom Unknown Progress Animations
326
352
 
327
353
  Following up on [unknown progress](#unknown-progress), you may wish to update the unknown progress animation to suit your specific needs. This can be easily done by passing in the `:unknown_progress_animation_steps` option.
328
354
 
329
- This item should be an array of strings representing each step of the animation. The specific step used for a given progress is determined by the current progress of the bar. For example:
355
+ This item should be an array of strings that represent each step of the animation. The specific step used for a given progress is determined by the current progress of the bar. For example:
330
356
 
331
357
  ```ruby
332
358
  progressbar = ProgressBar.create(:unknown_progress_animation_steps => ['==>', '>==', '=>='])
@@ -340,21 +366,23 @@ Whatever element is chosen is repeated along the entire 'incomplete' portion of
340
366
 
341
367
  ### Non-TTY Output
342
368
 
343
- 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.
369
+ Normally, when the progress bar is updated, the entire previous bar is 'overwritten' with the updated information. However 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.
344
370
 
345
- 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:
371
+ To try to solve this problem, 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:
346
372
 
347
373
  Progress: |=============
348
374
 
349
- 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.
375
+ Notice that there are no dynamically updating segments like counters or ETA. Dynamic segments are incompatible with non-TTY devices. This is because dynamic segments need to be updated on each refresh of the bar, which is impossible in non-TTY mode.
350
376
 
351
377
  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.
352
378
 
353
- So how does it work? First we output the title and the first end cap:
379
+ So how does it work?
380
+
381
+ First we output the title and the first end cap:
354
382
 
355
383
  Progress: |
356
384
 
357
- 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.
385
+ Next, every time we increment the bar, we check whether the progress bar has grown. If it has, we _only output the additional portion_ of the bar to the output.
358
386
 
359
387
  For example, given the previous title output, if we increment the bar once, we would get:
360
388
 
@@ -362,7 +390,7 @@ For example, given the previous title output, if we increment the bar once, we w
362
390
 
363
391
  But in this case, only one `=` was output. Not the entire `Progress: |=`.
364
392
 
365
- Once the bar gets to be completely finished though:
393
+ However when the bar is completed:
366
394
 
367
395
  Progress: |====================================================================|
368
396
 
@@ -12,6 +12,7 @@ class ProgressBar
12
12
  super(options)
13
13
 
14
14
  @bar = Components::Bar.new(options)
15
+ @rate = Components::Rate.new(options)
15
16
  @estimated_time = Components::EstimatedTimer.new(options)
16
17
  @elapsed_time = Components::ElapsedTimer.new
17
18
  @throttle = Components::Throttle.new(options)
@@ -155,11 +156,13 @@ class ProgressBar
155
156
  def with_progressables(*args)
156
157
  @bar.send(*args)
157
158
  @estimated_time.send(*args)
159
+ @rate.send(*args)
158
160
  end
159
161
 
160
162
  def with_timers(*args)
161
163
  @estimated_time.send(*args)
162
164
  @elapsed_time.send(*args)
165
+ @rate.send(*args)
163
166
  end
164
167
 
165
168
  def update_progress(*args)
@@ -4,3 +4,4 @@ require 'ruby-progressbar/components/bar'
4
4
  require 'ruby-progressbar/components/estimated_timer'
5
5
  require 'ruby-progressbar/components/elapsed_timer'
6
6
  require 'ruby-progressbar/components/throttle'
7
+ require 'ruby-progressbar/components/rate'
@@ -84,6 +84,10 @@ class ProgressBar
84
84
  format('%5.2f', (progress.to_f * 100.0 / total * 100.0).floor / 100.0)
85
85
  end
86
86
 
87
+ def progress_made
88
+ started? ? self.progress - self.starting_position : 0
89
+ end
90
+
87
91
  private
88
92
  def validate_total(new_total)
89
93
  (progress.nil? || new_total.nil? || new_total >= progress) || raise(ProgressBar::InvalidProgressError, "You can't set the item's total value to be less than the current progress.")
@@ -93,12 +97,8 @@ class ProgressBar
93
97
  (total.nil? || new_progress <= total) || raise(ProgressBar::InvalidProgressError, "You can't set the item's current value to be greater than the total.")
94
98
  end
95
99
 
96
- def progress_made
97
- started? ? self.progress - self.starting_position : 0
98
- end
99
-
100
100
  def update_running_average
101
- self.running_average = RunningAverageCalculator.calculate(self.running_average, self.progress, self.smoothing)
101
+ self.running_average = RunningAverageCalculator.calculate(self.running_average, self.progress_made, self.smoothing)
102
102
  end
103
103
  end
104
104
  end
@@ -0,0 +1,69 @@
1
+ class ProgressBar
2
+ module Components
3
+ class Rate
4
+ include Timer
5
+ include Progressable
6
+
7
+ attr_accessor :rate_scale
8
+
9
+ def initialize(options = {})
10
+ self.rate_scale = options[:rate_scale]
11
+
12
+ super
13
+ end
14
+
15
+ def start(options = {})
16
+ as(Timer).start
17
+ as(Progressable).start(options)
18
+ end
19
+
20
+ def reset
21
+ as(Timer).reset
22
+ as(Progressable).reset
23
+ end
24
+
25
+ def to_s(format_string = "%i")
26
+ elapsed = elapsed_whole_seconds.to_f
27
+ return 0 unless elapsed > 0
28
+
29
+ base_rate = (progress_made / elapsed)
30
+
31
+ if rate_scale
32
+ scaled_rate = rate_scale.call(base_rate)
33
+ else
34
+ scaled_rate = base_rate
35
+ end
36
+
37
+ format_string % scaled_rate
38
+ end
39
+
40
+ private
41
+
42
+ def as(ancestor, &blk)
43
+ @__as ||= {}
44
+ unless r = @__as[ancestor]
45
+ r = (@__as[ancestor] = As.new(self, ancestor))
46
+ end
47
+ r.instance_eval(&blk) if block_given?
48
+ r
49
+ end
50
+
51
+ class As
52
+ private *instance_methods.select { |m| m !~ /(^__|^\W|^binding$)/ }
53
+
54
+ def initialize(subject, ancestor)
55
+ @subject = subject
56
+ @ancestor = ancestor
57
+ end
58
+
59
+ def start(*args, &blk)
60
+ @ancestor.instance_method(:start).bind(@subject).call(*args,&blk)
61
+ end
62
+
63
+ def method_missing(sym, *args, &blk)
64
+ @ancestor.instance_method(sym).bind(@subject).call(*args,&blk)
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -2,31 +2,32 @@ class ProgressBar
2
2
  module Format
3
3
  class Molecule
4
4
  MOLECULES = {
5
- :t => [:left_justified_title, :title],
6
- :T => [:right_justified_title, :title],
7
- :c => [:current_progress, :progress],
8
- :C => [:total_capacity, :total],
9
- :p => [:percentage_complete_as_integer, :percentage],
10
- :P => [:percentage_complete_as_float, :percentage_with_precision],
11
- :a => [:elapsed_time, :elapsed_time],
12
- :e => [:estimated_time_with_unknown, :estimated_time_with_unknown_oob],
13
- :E => [:estimated_time_with_greater_than, :estimated_time_with_friendly_oob],
14
- :f => [:force_estimated_time, :estimated_time_with_no_oob],
15
- :B => [:complete_bar, :complete_bar],
16
- :b => [:bar, :bar],
17
- :w => [:bar_with_percentage, :bar_with_percentage],
18
- :i => [:incomplete_space, :incomplete_space]
5
+ :t => :title,
6
+ :T => :title,
7
+ :c => :progress,
8
+ :C => :total,
9
+ :p => :percentage,
10
+ :P => :percentage_with_precision,
11
+ :a => :elapsed_time,
12
+ :e => :estimated_time_with_unknown_oob,
13
+ :E => :estimated_time_with_friendly_oob,
14
+ :f => :estimated_time_with_no_oob,
15
+ :B => :complete_bar,
16
+ :b => :bar,
17
+ :w => :bar_with_percentage,
18
+ :i => :incomplete_space,
19
+ :r => :rate_of_change,
20
+ :R => :rate_of_change_with_precision,
19
21
  }
20
22
 
21
23
  BAR_MOLECULES = %w{w B b i}
22
24
 
23
25
  attr_reader :key
24
26
  attr_reader :method_name
25
- attr_reader :method_arguments
26
27
 
27
28
  def initialize(letter)
28
- @key = letter
29
- @description, @method_name, @method_arguments = MOLECULES.fetch(@key.to_sym)
29
+ @key = letter
30
+ @method_name = MOLECULES.fetch(@key.to_sym)
30
31
  end
31
32
 
32
33
  def bar_molecule?
@@ -91,5 +91,13 @@ class ProgressBar
91
91
  def estimated_time
92
92
  finished? ? @elapsed_time : @estimated_time
93
93
  end
94
+
95
+ def rate_of_change
96
+ @rate.to_s
97
+ end
98
+
99
+ def rate_of_change_with_precision
100
+ @rate.to_s("%.2f")
101
+ end
94
102
  end
95
103
  end
@@ -1,3 +1,3 @@
1
1
  class ProgressBar
2
- VERSION = '1.4.2'
2
+ VERSION = '1.5.0'
3
3
  end
@@ -1,16 +1,17 @@
1
- require 'spec_helper'
1
+ require 'rspectacular'
2
+ require 'support/time'
2
3
  require 'stringio'
3
4
 
4
5
  describe ProgressBar::Base do
5
6
  let(:output) do
6
7
  StringIO.new('', 'w+').tap do |io|
7
- io.stub(:tty?).and_return true
8
+ allow(io).to receive(:tty?).and_return true
8
9
  end
9
10
  end
10
11
 
11
12
  let(:non_tty_output) do
12
13
  StringIO.new('', 'w+').tap do |io|
13
- io.stub(:tty?).and_return false
14
+ allow(io).to receive(:tty?).and_return false
14
15
  end
15
16
  end
16
17
 
@@ -31,7 +32,7 @@ describe ProgressBar::Base do
31
32
  progressbar.increment
32
33
 
33
34
  output.rewind
34
- output.read.should match /\raaaaaaaaaaaaaaaaaaaaaaaaa \r\s+\raaaaaaaaaaaaaaaaaaaaaaaaa\r\z/
35
+ expect(output.read).to match /\raaaaaaaaaaaaaaaaaaaaaaaaa \r\s+\raaaaaaaaaaaaaaaaaaaaaaaaa\r\z/
35
36
  end
36
37
 
37
38
  context 'and the bar length is calculated' do
@@ -41,7 +42,7 @@ describe ProgressBar::Base do
41
42
  allow(progressbar).to receive(:terminal_width).
42
43
  and_return 20
43
44
 
44
- progressbar.to_s('%t%w').should eql '*********************'
45
+ expect(progressbar.to_s('%t%w')).to eql '*********************'
45
46
  end
46
47
  end
47
48
 
@@ -52,7 +53,7 @@ describe ProgressBar::Base do
52
53
  allow(progressbar).to receive(:terminal_width).
53
54
  and_return 20
54
55
 
55
- progressbar.to_s('%t%i').should eql '*********************'
56
+ expect(progressbar.to_s('%t%i')).to eql '*********************'
56
57
  end
57
58
 
58
59
  it 'returns the proper string' do
@@ -61,7 +62,7 @@ describe ProgressBar::Base do
61
62
  allow(progressbar).to receive(:terminal_width).
62
63
  and_return 20
63
64
 
64
- progressbar.to_s('%t%i').should eql '*********************'
65
+ expect(progressbar.to_s('%t%i')).to eql '*********************'
65
66
  end
66
67
  end
67
68
 
@@ -72,7 +73,7 @@ describe ProgressBar::Base do
72
73
  allow(progressbar).to receive(:terminal_width).
73
74
  and_return 20
74
75
 
75
- progressbar.to_s('%t%B').should eql '******************* '
76
+ expect(progressbar.to_s('%t%B')).to eql '******************* '
76
77
  end
77
78
 
78
79
  it 'returns the proper string' do
@@ -81,7 +82,7 @@ describe ProgressBar::Base do
81
82
  allow(progressbar).to receive(:terminal_width).
82
83
  and_return 20
83
84
 
84
- progressbar.to_s('%t%w%i').should eql '******************* '
85
+ expect(progressbar.to_s('%t%w%i')).to eql '******************* '
85
86
  end
86
87
  end
87
88
  end
@@ -92,13 +93,13 @@ describe ProgressBar::Base do
92
93
 
93
94
  describe '#title' do
94
95
  it 'returns the default title' do
95
- progressbar.send(:title).to_s.should eql ProgressBar::Base::DEFAULT_TITLE
96
+ expect(progressbar.send(:title).to_s).to eql ProgressBar::Base::DEFAULT_TITLE
96
97
  end
97
98
  end
98
99
 
99
100
  describe '#output' do
100
101
  it 'returns the default output stream' do
101
- progressbar.send(:output).should eql ProgressBar::Base::DEFAULT_OUTPUT_STREAM
102
+ expect(progressbar.send(:output)).to eql ProgressBar::Base::DEFAULT_OUTPUT_STREAM
102
103
  end
103
104
  end
104
105
 
@@ -109,7 +110,7 @@ describe ProgressBar::Base do
109
110
 
110
111
  it 'returns the length of the environment variable as an integer' do
111
112
  progressbar = ProgressBar::Base.new
112
- progressbar.send(:length).should eql 44
113
+ expect(progressbar.send(:length)).to eql 44
113
114
  end
114
115
  end
115
116
 
@@ -119,21 +120,21 @@ describe ProgressBar::Base do
119
120
  context 'but the length option was passed in' do
120
121
  it 'returns the length specified in the option' do
121
122
  progressbar = ProgressBar::Base.new(:length => 88)
122
- progressbar.send(:length).should eql 88
123
+ expect(progressbar.send(:length)).to eql 88
123
124
  end
124
125
  end
125
126
 
126
127
  context 'and no length option was passed in' do
127
128
  it 'returns the width of the terminal if it is a Unix environment' do
128
- progressbar.stub(:terminal_width).and_return(99)
129
+ allow(progressbar).to receive(:terminal_width).and_return(99)
129
130
  progressbar.send(:reset_length)
130
- progressbar.send(:length).should eql 99
131
+ expect(progressbar.send(:length)).to eql 99
131
132
  end
132
133
 
133
134
  it 'returns 80 if it is not a Unix environment' do
134
- progressbar.stub(:unix?).and_return(false)
135
+ allow(progressbar).to receive(:unix?).and_return(false)
135
136
  progressbar.send(:reset_length)
136
- progressbar.send(:length).should eql 80
137
+ expect(progressbar.send(:length)).to eql 80
137
138
  end
138
139
  end
139
140
  end
@@ -145,19 +146,19 @@ describe ProgressBar::Base do
145
146
 
146
147
  describe '#title' do
147
148
  it 'returns the overridden title' do
148
- progressbar.send(:title).to_s.should eql 'We All Float'
149
+ expect(progressbar.send(:title).to_s).to eql 'We All Float'
149
150
  end
150
151
  end
151
152
 
152
153
  describe '#output' do
153
154
  it 'returns the overridden output stream' do
154
- progressbar.send(:output).should eql STDOUT
155
+ expect(progressbar.send(:output)).to eql STDOUT
155
156
  end
156
157
  end
157
158
 
158
159
  describe '#length' do
159
160
  it 'returns the overridden length' do
160
- progressbar.send(:length).should eql 88
161
+ expect(progressbar.send(:length)).to eql 88
161
162
  end
162
163
  end
163
164
  end
@@ -185,15 +186,15 @@ describe ProgressBar::Base do
185
186
 
186
187
  it 'completes the bar' do
187
188
  output.rewind
188
- output.read.should match /Progress: \|#{'=' * 68}\|\n/
189
+ expect(output.read).to match /Progress: \|#{'=' * 68}\|\n/
189
190
  end
190
191
 
191
192
  it 'shows the elapsed time instead of the estimated time since the bar is completed' do
192
- progressbar.to_s('%e').should eql 'Time: 00:02:00'
193
+ expect(progressbar.to_s('%e')).to eql 'Time: 00:02:00'
193
194
  end
194
195
 
195
196
  it 'calculates the elapsed time to 00:02:00' do
196
- progressbar.to_s('%a').should eql 'Time: 00:02:00'
197
+ expect(progressbar.to_s('%a')).to eql 'Time: 00:02:00'
197
198
  end
198
199
  end
199
200
  end
@@ -216,7 +217,7 @@ describe ProgressBar::Base do
216
217
  progressbar.increment
217
218
 
218
219
  output.rewind
219
- 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"
220
+ 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"
220
221
  end
221
222
 
222
223
  it 'properly calculates the length of the bar by removing the short version of the ANSI codes from the calculated length' do
@@ -235,7 +236,7 @@ describe ProgressBar::Base do
235
236
  progressbar.increment
236
237
 
237
238
  output.rewind
238
- 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"
239
+ 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"
239
240
  end
240
241
  end
241
242
 
@@ -247,7 +248,7 @@ describe ProgressBar::Base do
247
248
  progressbar.increment
248
249
 
249
250
  output.rewind
250
- output.read.should include "Progress: |==== |\rProgress: |===== |\r \rWe All Float\nProgress: |===== |\rProgress: |====== |\r"
251
+ expect(output.read).to include "Progress: |==== |\rProgress: |===== |\r \rWe All Float\nProgress: |===== |\rProgress: |====== |\r"
251
252
  end
252
253
  end
253
254
 
@@ -260,7 +261,7 @@ describe ProgressBar::Base do
260
261
  progressbar.finish
261
262
 
262
263
  non_tty_output.rewind
263
- non_tty_output.read.should include "We All Float\nProgress: |========|\n"
264
+ expect(non_tty_output.read).to include "We All Float\nProgress: |========|\n"
264
265
  end
265
266
 
266
267
  it 'can output the bar properly so that it does not spam the screen' do
@@ -269,7 +270,7 @@ describe ProgressBar::Base do
269
270
  6.times { progressbar.increment }
270
271
 
271
272
  non_tty_output.rewind
272
- non_tty_output.read.should eql "\n\nProgress: |========|\n"
273
+ expect(non_tty_output.read).to eql "\n\nProgress: |========|\n"
273
274
  end
274
275
 
275
276
  it 'can output the bar properly if finished in the middle of its progress' do
@@ -280,7 +281,7 @@ describe ProgressBar::Base do
280
281
  progressbar.finish
281
282
 
282
283
  non_tty_output.rewind
283
- non_tty_output.read.should eql "\n\nProgress: |========|\n"
284
+ expect(non_tty_output.read).to eql "\n\nProgress: |========|\n"
284
285
  end
285
286
 
286
287
  it 'can output the bar properly if stopped in the middle of its progress' do
@@ -291,7 +292,7 @@ describe ProgressBar::Base do
291
292
  progressbar.stop
292
293
 
293
294
  non_tty_output.rewind
294
- non_tty_output.read.should eql "\n\nProgress: |====\n"
295
+ expect(non_tty_output.read).to eql "\n\nProgress: |====\n"
295
296
  end
296
297
  end
297
298
  end
@@ -303,19 +304,19 @@ describe ProgressBar::Base do
303
304
  before { progressbar.increment }
304
305
 
305
306
  it 'registers as being "finished"' do
306
- progressbar.should be_finished
307
+ expect(progressbar).to be_finished
307
308
  end
308
309
 
309
310
  it 'prints a new line' do
310
311
  output.rewind
311
- output.read.end_with?("\n").should be_true
312
+ expect(output.read.end_with?("\n")).to eql true
312
313
  end
313
314
 
314
315
  it 'does not continue to print bars if finish is subsequently called' do
315
316
  progressbar.finish
316
317
 
317
318
  output.rewind
318
- output.read.should end_with " \rProgress: |====== |\rProgress: |========|\n"
319
+ expect(output.read).to end_with " \rProgress: |====== |\rProgress: |========|\n"
319
320
  end
320
321
  end
321
322
  end
@@ -324,25 +325,25 @@ describe ProgressBar::Base do
324
325
  let(:progressbar) { ProgressBar::Base.new(:total => nil, :output => output, :length => 80, :unknown_progress_animation_steps => ['=--', '-=-', '--=']) }
325
326
 
326
327
  it 'is represented correctly' do
327
- progressbar.to_s('%i').should eql '=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=-'
328
+ expect(progressbar.to_s('%i')).to eql '=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=-'
328
329
  end
329
330
 
330
331
  it 'is represented after being incremented once' do
331
332
  progressbar.increment
332
- progressbar.to_s('%i').should eql '-=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--='
333
+ expect(progressbar.to_s('%i')).to eql '-=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--='
333
334
  end
334
335
 
335
336
  it 'is represented after being incremented twice' do
336
337
  progressbar.increment
337
338
  progressbar.increment
338
- progressbar.to_s('%i').should eql '--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--'
339
+ expect(progressbar.to_s('%i')).to eql '--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--'
339
340
  end
340
341
 
341
342
  it 'displays the proper ETA' do
342
343
  progressbar.increment
343
344
 
344
- progressbar.to_s('%i%e').should eql '-=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=- ETA: ??:??:??'
345
- progressbar.to_s('%i%E').should eql '-=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=- ETA: ??:??:??'
345
+ expect(progressbar.to_s('%i%e')).to eql '-=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=- ETA: ??:??:??'
346
+ expect(progressbar.to_s('%i%E')).to eql '-=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=- ETA: ??:??:??'
346
347
  end
347
348
  end
348
349
 
@@ -357,7 +358,7 @@ describe ProgressBar::Base do
357
358
  progressbar.progress_mark = 'x'
358
359
 
359
360
  output.rewind
360
- output.read.should match /\rProgress: \|xxxxxx#{' ' * 62}\|\r\z/
361
+ expect(output.read).to match /\rProgress: \|xxxxxx#{' ' * 62}\|\r\z/
361
362
  end
362
363
  end
363
364
 
@@ -366,7 +367,7 @@ describe ProgressBar::Base do
366
367
  progressbar.remainder_mark = 'x'
367
368
 
368
369
  output.rewind
369
- output.read.should match /\rProgress: \|======#{'x' * 62}\|\r\z/
370
+ expect(output.read).to match /\rProgress: \|======#{'x' * 62}\|\r\z/
370
371
  end
371
372
  end
372
373
 
@@ -375,7 +376,7 @@ describe ProgressBar::Base do
375
376
  progressbar.title = 'Items'
376
377
 
377
378
  output.rewind
378
- output.read.should match /\rItems: \|=======#{' ' * 64}\|\r\z/
379
+ expect(output.read).to match /\rItems: \|=======#{' ' * 64}\|\r\z/
379
380
  end
380
381
  end
381
382
 
@@ -384,7 +385,7 @@ describe ProgressBar::Base do
384
385
 
385
386
  it 'resets the bar back to the starting value' do
386
387
  output.rewind
387
- output.read.should match /\rProgress: \|#{' ' * 68}\|\r\z/
388
+ expect(output.read).to match /\rProgress: \|#{' ' * 68}\|\r\z/
388
389
  end
389
390
  end
390
391
 
@@ -393,7 +394,7 @@ describe ProgressBar::Base do
393
394
 
394
395
  it 'forcibly halts the bar wherever it is and cancels it' do
395
396
  output.rewind
396
- output.read.should match /\rProgress: \|======#{' ' * 62}\|\n\z/
397
+ expect(output.read).to match /\rProgress: \|======#{' ' * 62}\|\n\z/
397
398
  end
398
399
 
399
400
  it 'does not output the bar multiple times if the bar is already stopped' do
@@ -401,7 +402,7 @@ describe ProgressBar::Base do
401
402
  progressbar.stop
402
403
  output.rewind
403
404
 
404
- output.read.should_not start_with "Progress: |======#{' ' * 62}|"
405
+ expect(output.read).to start_with "#{' ' * 80}"
405
406
  end
406
407
  end
407
408
 
@@ -411,7 +412,7 @@ describe ProgressBar::Base do
411
412
  progressbar.resume
412
413
  output.rewind
413
414
 
414
- output.read.should_not start_with "Progress: |======#{' ' * 62}|"
415
+ expect(output.read).to start_with "#{' ' * 80}"
415
416
  end
416
417
  end
417
418
  end
@@ -428,7 +429,7 @@ describe ProgressBar::Base do
428
429
 
429
430
  it 'resets the bar back to the starting value' do
430
431
  output.rewind
431
- output.read.should match /\rProgress: \|==========#{' ' * 90}\|\r\z/
432
+ expect(output.read).to match /\rProgress: \|==========#{' ' * 90}\|\r\z/
432
433
  end
433
434
  end
434
435
  end
@@ -439,7 +440,7 @@ describe ProgressBar::Base do
439
440
  progressbar.clear
440
441
 
441
442
  output.rewind
442
- output.read.should match /^#{progressbar.send(:clear_string)}/
443
+ expect(output.read).to match /^#{progressbar.send(:clear_string)}/
443
444
  end
444
445
  end
445
446
 
@@ -448,21 +449,21 @@ describe ProgressBar::Base do
448
449
  progressbar.start
449
450
 
450
451
  output.rewind
451
- output.read.should match /^#{progressbar.send(:clear_string)}/
452
+ expect(output.read).to match /^#{progressbar.send(:clear_string)}/
452
453
  end
453
454
 
454
455
  it 'prints the bar for the first time' do
455
456
  progressbar.start
456
457
 
457
458
  output.rewind
458
- output.read.should match /Progress: \| \|\r\z/
459
+ expect(output.read).to match /Progress: \| \|\r\z/
459
460
  end
460
461
 
461
462
  it 'prints correctly if passed a position to start at' do
462
463
  progressbar.start(:at => 20)
463
464
 
464
465
  output.rewind
465
- output.read.should match /Progress: \|============= \|\r\z/
466
+ expect(output.read).to match /Progress: \|============= \|\r\z/
466
467
  end
467
468
  end
468
469
 
@@ -474,7 +475,7 @@ describe ProgressBar::Base do
474
475
 
475
476
  it 'displays the bar with the correct formatting' do
476
477
  output.rewind
477
- output.read.should match /Progress: \|== \|\r\z/
478
+ expect(output.read).to match /Progress: \|== \|\r\z/
478
479
  end
479
480
  end
480
481
  end
@@ -487,7 +488,7 @@ describe ProgressBar::Base do
487
488
  before { progressbar.format }
488
489
 
489
490
  it 'resets the format back to the default' do
490
- progressbar.to_s.should match /^Progress: \|\s+\|\z/
491
+ expect(progressbar.to_s).to match /^Progress: \|\s+\|\z/
491
492
  end
492
493
  end
493
494
 
@@ -495,116 +496,260 @@ describe ProgressBar::Base do
495
496
  before { progressbar.format '%t' }
496
497
 
497
498
  it 'sets it as the new format for the bar' do
498
- progressbar.to_s.should match /^Progress\z/
499
+ expect(progressbar.to_s).to match /^Progress\z/
499
500
  end
500
501
  end
501
502
  end
502
503
 
503
504
  context '#to_s' do
505
+ context 'when no time has elapsed' do
506
+ it 'displays zero for the rate' do
507
+ Timecop.freeze do
508
+ progressbar = ProgressBar::Base.new(:length => 100, :starting_at => 0)
509
+
510
+ expect(progressbar.to_s('%r')).to match /^0\z/
511
+ end
512
+ end
513
+ end
514
+
515
+ context 'when any time has elasped' do
516
+ context 'and the standard rate is applied' do
517
+ it 'displays zero for %r if no progress has been made' do
518
+ progressbar = ProgressBar::Base.new(:length => 100, :starting_at => 20)
519
+
520
+ Timecop.travel(2) do
521
+ expect(progressbar.to_s('%r')).to match /^0\z/
522
+ end
523
+ end
524
+
525
+ it 'displays zero for %R if no progress has been made' do
526
+ progressbar = ProgressBar::Base.new(:length => 100, :starting_at => 20)
527
+
528
+ Timecop.travel(2) do
529
+ expect(progressbar.to_s('%R')).to match /^0.00\z/
530
+ end
531
+ end
532
+
533
+ it 'takes into account the starting position when calculating %r' do
534
+ Timecop.freeze do
535
+ progressbar = ProgressBar::Base.new(:length => 100, :starting_at => 20)
536
+ progressbar.start
537
+ progressbar.progress += 20
538
+
539
+ Timecop.travel(2) do
540
+ expect(progressbar.to_s('%r')).to match /^10\z/
541
+ end
542
+ end
543
+ end
544
+
545
+ it 'takes into account the starting position when calculating %R' do
546
+ Timecop.freeze do
547
+ progressbar = ProgressBar::Base.new(:length => 100, :starting_at => 20)
548
+ progressbar.start
549
+ progressbar.progress += 13
550
+
551
+ Timecop.travel(2) do
552
+ expect(progressbar.to_s('%R')).to match /^6.50\z/
553
+ end
554
+ end
555
+ end
556
+
557
+ it 'displays the rate when passed the "%r" format flag' do
558
+ Timecop.freeze do
559
+ progressbar = ProgressBar::Base.new(:length => 100, :starting_at => 0)
560
+ progressbar.start
561
+ progressbar.progress += 20
562
+
563
+ Timecop.travel(2) do
564
+ expect(progressbar.to_s('%r')).to match /^10\z/
565
+ end
566
+ end
567
+ end
568
+
569
+ it 'displays the rate when passed the "%R" format flag' do
570
+ Timecop.freeze do
571
+ progressbar = ProgressBar::Base.new(:length => 100, :starting_at => 0)
572
+ progressbar.start
573
+ progressbar.progress += 10
574
+
575
+ Timecop.travel(6) do
576
+ expect(progressbar.to_s('%R')).to match /^1.67\z/
577
+ end
578
+ end
579
+ end
580
+ end
581
+
582
+ context 'and the a custom rate is applied' do
583
+ it 'displays zero for %r if no progress has been made' do
584
+ progressbar = ProgressBar::Base.new(:length => 100, :starting_at => 20, :rate_scale => lambda { |rate| rate / 2 })
585
+
586
+ Timecop.travel(2) do
587
+ expect(progressbar.to_s('%r')).to match /^0\z/
588
+ end
589
+ end
590
+
591
+ it 'displays zero for %R if no progress has been made' do
592
+ progressbar = ProgressBar::Base.new(:length => 100, :starting_at => 20, :rate_scale => lambda { |rate| rate / 2 })
593
+
594
+ Timecop.travel(2) do
595
+ expect(progressbar.to_s('%R')).to match /^0.00\z/
596
+ end
597
+ end
598
+
599
+ it 'takes into account the starting position when calculating %r' do
600
+ Timecop.freeze do
601
+ progressbar = ProgressBar::Base.new(:length => 100, :starting_at => 20, :rate_scale => lambda { |rate| rate / 2 })
602
+ progressbar.start
603
+ progressbar.progress += 20
604
+
605
+ Timecop.travel(2) do
606
+ expect(progressbar.to_s('%r')).to match /^5\z/
607
+ end
608
+ end
609
+ end
610
+
611
+ it 'takes into account the starting position when calculating %R' do
612
+ Timecop.freeze do
613
+ progressbar = ProgressBar::Base.new(:length => 100, :starting_at => 20, :rate_scale => lambda { |rate| rate / 2 })
614
+ progressbar.start
615
+ progressbar.progress += 13
616
+
617
+ Timecop.travel(2) do
618
+ expect(progressbar.to_s('%R')).to match /^3.25\z/
619
+ end
620
+ end
621
+ end
622
+
623
+ it 'displays the rate when passed the "%r" format flag' do
624
+ Timecop.freeze do
625
+ progressbar = ProgressBar::Base.new(:length => 100, :starting_at => 0, :rate_scale => lambda { |rate| rate / 2 })
626
+ progressbar.start
627
+ progressbar.progress += 20
628
+
629
+ Timecop.travel(2) do
630
+ expect(progressbar.to_s('%r')).to match /^5\z/
631
+ end
632
+ end
633
+ end
634
+
635
+ it 'displays the rate when passed the "%R" format flag' do
636
+ Timecop.freeze do
637
+ progressbar = ProgressBar::Base.new(:length => 100, :starting_at => 0, :rate_scale => lambda { |rate| rate / 2 })
638
+ progressbar.start
639
+ progressbar.progress += 10
640
+
641
+ Timecop.travel(6) do
642
+ expect(progressbar.to_s('%R')).to match /^0.83\z/
643
+ end
644
+ end
645
+ end
646
+ end
647
+ end
648
+
504
649
  it 'displays the title when passed the "%t" format flag' do
505
- progressbar.to_s('%t').should match /^Progress\z/
650
+ expect(progressbar.to_s('%t')).to match /^Progress\z/
506
651
  end
507
652
 
508
653
  it 'displays the title when passed the "%T" format flag' do
509
- progressbar.to_s('%T').should match /^Progress\z/
654
+ expect(progressbar.to_s('%T')).to match /^Progress\z/
510
655
  end
511
656
 
512
657
  it 'displays the bar when passed the "%B" format flag (including empty space)' do
513
658
  progressbar = ProgressBar::Base.new(:length => 100, :starting_at => 20)
514
- progressbar.to_s('%B').should match /^#{'=' * 20}#{' ' * 80}\z/
659
+ expect(progressbar.to_s('%B')).to match /^#{'=' * 20}#{' ' * 80}\z/
515
660
  end
516
661
 
517
662
  it 'displays the bar when passed the combined "%b%i" format flags' do
518
663
  progressbar = ProgressBar::Base.new(:length => 100, :starting_at => 20)
519
- progressbar.to_s('%b%i').should match /^#{'=' * 20}#{' ' * 80}\z/
664
+ expect(progressbar.to_s('%b%i')).to match /^#{'=' * 20}#{' ' * 80}\z/
520
665
  end
521
666
 
522
667
  it 'displays the bar when passed the "%b" format flag (excluding empty space)' do
523
668
  progressbar = ProgressBar::Base.new(:length => 100, :starting_at => 20)
524
- progressbar.to_s('%b').should match /^#{'=' * 20}\z/
669
+ expect(progressbar.to_s('%b')).to match /^#{'=' * 20}\z/
525
670
  end
526
671
 
527
672
  it 'displays the incomplete space when passed the "%i" format flag' do
528
673
  progressbar = ProgressBar::Base.new(:length => 100, :starting_at => 20)
529
- progressbar.to_s('%i').should match /^#{' ' * 80}\z/
674
+ expect(progressbar.to_s('%i')).to match /^#{' ' * 80}\z/
530
675
  end
531
676
 
532
677
  it 'displays the bar when passed the "%w" format flag' do
533
678
  progressbar = ProgressBar::Base.new(:output => output, :length => 100, :starting_at => 0)
534
679
 
535
- progressbar.to_s('%w').should match /^\z/
680
+ expect(progressbar.to_s('%w')).to match /^\z/
536
681
  4.times { progressbar.increment }
537
- progressbar.to_s('%w').should match /^====\z/
682
+ expect(progressbar.to_s('%w')).to match /^====\z/
538
683
  progressbar.increment
539
- progressbar.to_s('%w').should match /^= 5 =\z/
684
+ expect(progressbar.to_s('%w')).to match /^= 5 =\z/
540
685
  5.times { progressbar.increment }
541
- progressbar.to_s('%w').should match /^=== 10 ===\z/
686
+ expect(progressbar.to_s('%w')).to match /^=== 10 ===\z/
542
687
  progressbar.decrement
543
- progressbar.to_s('%w').should match /^=== 9 ===\z/
688
+ expect(progressbar.to_s('%w')).to match /^=== 9 ===\z/
544
689
  91.times { progressbar.increment }
545
- progressbar.to_s('%w').should match /^#{'=' * 47} 100 #{'=' * 48}\z/
690
+ expect(progressbar.to_s('%w')).to match /^#{'=' * 47} 100 #{'=' * 48}\z/
546
691
  end
547
692
 
548
693
  it 'calculates the remaining negative space properly with an integrated percentage bar of 0 percent' do
549
694
  progressbar = ProgressBar::Base.new(:output => output, :length => 100, :total => 200, :starting_at => 0)
550
695
 
551
- progressbar.to_s('%w%i').should match /^\s{100}\z/
696
+ expect(progressbar.to_s('%w%i')).to match /^\s{100}\z/
552
697
  9.times { progressbar.increment }
553
- progressbar.to_s('%w%i').should match /^====\s{96}\z/
698
+ expect(progressbar.to_s('%w%i')).to match /^====\s{96}\z/
554
699
  progressbar.increment
555
- progressbar.to_s('%w%i').should match /^= 5 =\s{95}\z/
700
+ expect(progressbar.to_s('%w%i')).to match /^= 5 =\s{95}\z/
556
701
  end
557
702
 
558
703
  it 'displays the current capacity when passed the "%c" format flag' do
559
704
  progressbar = ProgressBar::Base.new(:output => output, :starting_at => 0)
560
705
 
561
- progressbar.to_s('%c').should match /^0\z/
706
+ expect(progressbar.to_s('%c')).to match /^0\z/
562
707
  progressbar.increment
563
- progressbar.to_s('%c').should match /^1\z/
708
+ expect(progressbar.to_s('%c')).to match /^1\z/
564
709
  progressbar.decrement
565
- progressbar.to_s('%c').should match /^0\z/
710
+ expect(progressbar.to_s('%c')).to match /^0\z/
566
711
  end
567
712
 
568
713
  it 'displays the total capacity when passed the "%C" format flag' do
569
714
  progressbar = ProgressBar::Base.new(:total => 100)
570
715
 
571
- progressbar.to_s('%C').should match /^100\z/
716
+ expect(progressbar.to_s('%C')).to match /^100\z/
572
717
  end
573
718
 
574
719
  it 'displays the percentage complete when passed the "%p" format flag' do
575
720
  progressbar = ProgressBar::Base.new(:starting_at => 33, :total => 200)
576
721
 
577
- progressbar.to_s('%p').should match /^16\z/
722
+ expect(progressbar.to_s('%p')).to match /^16\z/
578
723
  end
579
724
 
580
725
  it 'displays the percentage complete when passed the "%P" format flag' do
581
726
  progressbar = ProgressBar::Base.new(:starting_at => 33, :total => 200)
582
727
 
583
- progressbar.to_s('%P').should match /^16.50\z/
728
+ expect(progressbar.to_s('%P')).to match /^16.50\z/
584
729
  end
585
730
 
586
731
  it 'displays only up to 2 decimal places when using the "%P" flag' do
587
732
  progressbar = ProgressBar::Base.new(:starting_at => 66, :total => 99)
588
733
 
589
- progressbar.to_s('%P').should match /^66.66\z/
734
+ expect(progressbar.to_s('%P')).to match /^66.66\z/
590
735
  end
591
736
 
592
737
  it 'displays a literal percent sign when using the "%%" flag' do
593
738
  progressbar = ProgressBar::Base.new(:starting_at => 66, :total => 99)
594
739
 
595
- progressbar.to_s('%%').should match /^%\z/
740
+ expect(progressbar.to_s('%%')).to match /^%\z/
596
741
  end
597
742
 
598
743
  it 'displays a literal percent sign when using the "%%" flag' do
599
744
  progressbar = ProgressBar::Base.new(:starting_at => 66, :total => 99)
600
745
 
601
- progressbar.to_s('%%').should match /^%\z/
746
+ expect(progressbar.to_s('%%')).to match /^%\z/
602
747
  end
603
748
 
604
749
  # Autostarting for now. This will be applicable later.
605
750
  # context "when called before #start" do
606
751
  # it "displays unknown time elapsed when using the %a flag" do
607
- # progressbar.to_s('%a').should match /^Time: --:--:--\z/
752
+ # expect(progressbar.to_s('%a')).to match /^Time: --:--:--\z/
608
753
  # end
609
754
  # end
610
755
 
@@ -619,19 +764,19 @@ describe ProgressBar::Base do
619
764
  before { progressbar.reset }
620
765
 
621
766
  it 'displays "??:??:??" until finished when passed the %e flag' do
622
- progressbar.to_s('%a').should match /^Time: --:--:--\z/
767
+ expect(progressbar.to_s('%a')).to match /^Time: --:--:--\z/
623
768
  end
624
769
  end
625
770
 
626
771
  it 'displays the time elapsed when using the "%a" flag' do
627
- progressbar.to_s('%a').should match /^Time: 01:02:03\z/
772
+ expect(progressbar.to_s('%a')).to match /^Time: 01:02:03\z/
628
773
  end
629
774
  end
630
775
 
631
776
  context 'when called before #start' do
632
777
  it 'displays unknown time until finished when passed the "%e" flag' do
633
778
  progressbar = ProgressBar::Base.new
634
- progressbar.to_s('%e').should match /^ ETA: \?\?:\?\?:\?\?\z/
779
+ expect(progressbar.to_s('%e')).to match /^ ETA: \?\?:\?\?:\?\?\z/
635
780
  end
636
781
  end
637
782
 
@@ -649,12 +794,12 @@ describe ProgressBar::Base do
649
794
  before { progressbar.reset }
650
795
 
651
796
  it 'displays "??:??:??" until finished when passed the "%e" flag' do
652
- progressbar.to_s('%e').should match /^ ETA: \?\?:\?\?:\?\?\z/
797
+ expect(progressbar.to_s('%e')).to match /^ ETA: \?\?:\?\?:\?\?\z/
653
798
  end
654
799
  end
655
800
 
656
801
  it 'displays the estimated time remaining when using the "%e" flag' do
657
- progressbar.to_s('%e').should match /^ ETA: 01:02:03\z/
802
+ expect(progressbar.to_s('%e')).to match /^ ETA: 01:02:03\z/
658
803
  end
659
804
  end
660
805
 
@@ -669,15 +814,15 @@ describe ProgressBar::Base do
669
814
  end
670
815
 
671
816
  it 'displays "> 4 Days" until finished when passed the "%E" flag' do
672
- progressbar.to_s('%E').should match /^ ETA: > 4 Days\z/
817
+ expect(progressbar.to_s('%E')).to match /^ ETA: > 4 Days\z/
673
818
  end
674
819
 
675
820
  it 'displays "??:??:??" until finished when passed the "%e" flag' do
676
- progressbar.to_s('%e').should match /^ ETA: \?\?:\?\?:\?\?\z/
821
+ expect(progressbar.to_s('%e')).to match /^ ETA: \?\?:\?\?:\?\?\z/
677
822
  end
678
823
 
679
824
  it 'displays the exact estimated time until finished when passed the "%f" flag' do
680
- progressbar.to_s('%f').should match /^ ETA: 100:00:00\z/
825
+ expect(progressbar.to_s('%f')).to match /^ ETA: 100:00:00\z/
681
826
  end
682
827
  end
683
828
  end