tty-progressbar 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ff767a06ae19986026a9fc6bf8542246a66aa114
4
- data.tar.gz: ee1b4fdfcf5e032a0f57b45edfc6076b7e44478f
3
+ metadata.gz: 352677d511081780de389f441c94367e9c43439d
4
+ data.tar.gz: a76e419403efc5d4e86987272ce365df173edb57
5
5
  SHA512:
6
- metadata.gz: 8e30d01509fe132b2af4ae89138723a6e8f3fd55a9cd212b83d7a4bcac299d1ca46bb28051d039c75eaf57f30217bd518e4e2727629a5c954896811c4f199a97
7
- data.tar.gz: 023f9de9dc08949e1754ffc1caab86d5ad2d06c9f538577049a658e243a5680ae9fbd04a31a07c64e56d9d7cff8cad1d687a07d18ee2576d75342725901e4963
6
+ metadata.gz: 682bcc03f3f85f5825331b0caf3c41df49d089d19db7168ae1f1f34e624ca7f14b6c89a16b6aa6348f8f951851b1ff758ff9d36e1e9424dda2ecb70772f82a38
7
+ data.tar.gz: b520bc8143e6736f7214ac6bac1b9b187769c635fecec636a6ac3c8288cb20c5fc6a78d935b251f8521942aa0c68e40d5898eb6325f7b81783c96c275c0ab7ce
data/CHANGELOG.md CHANGED
@@ -1,3 +1,12 @@
1
+ 0.5.0 (January 1, 2015)
2
+
3
+ * Add ability to reset progress
4
+ * Add start method for manually setting the timer
5
+ * Fix bug with finish not rendering the bar full
6
+ * Add meter to measure speed rate
7
+ * Add to_seconds converter
8
+ * Add :rate, :mean_rate, :byte_rate & :mean_byte formatters
9
+
1
10
  0.4.0 (December 25, 2014)
2
11
 
3
12
  * Add :total_byte, :current_byte formatters by @vincentjames501
data/README.md CHANGED
@@ -42,16 +42,20 @@ Or install it yourself as:
42
42
  * [1.1 advance](#11-advance)
43
43
  * [1.2 current=](#12-current)
44
44
  * [1.3 ratio=](#13-ratio)
45
- * [1.4 finish](#14-finish)
46
- * [1.5 complete?](#15-complete)
47
- * [1.6 resize](#16-resize)
45
+ * [1.4 start](#14-start)
46
+ * [1.5 finish](#15-finish)
47
+ * [1.6 complete?](#16-complete)
48
+ * [1.7 reset](#17-reset)
49
+ * [1.8 resize](#18-resize)
48
50
  * [2. Configuration](#2-configuration)
49
51
  * [2.1 Frequency](#21-frequency)
52
+ * [2.2 Interval](#22-interval)
50
53
  * [3. Formatting](#3-formatting)
51
54
  * [3.1 Tokens](#31-tokens)
52
55
  * [3.2 Custom Formatters](#31-custom-formatters)
53
56
  * [4. Logging](#4-logging)
54
57
  * [5. Examples](#5-examples)
58
+ * [5.1 Color](#51-color)
55
59
 
56
60
  ## 1. Usage
57
61
 
@@ -105,7 +109,15 @@ In order to update overall completion of a progress bar as an exact percentage u
105
109
  bar.ratio = 0.5
106
110
  ```
107
111
 
108
- ### 1.4 finish
112
+ ### 1.4 start
113
+
114
+ By default the timer for internal time esitamation is started automatically when the `advance` method is called. However, if you require control on when the progression timer is started use `start` call:
115
+
116
+ ```ruby
117
+ bar.start # => sets timer and draws initial progress bar
118
+ ```
119
+
120
+ ### 1.5 finish
109
121
 
110
122
  In order to immediately stop and finish the progress call `finish`. This will finish drawing the progress and return to new line.
111
123
 
@@ -113,7 +125,7 @@ In order to immediately stop and finish the progress call `finish`. This will fi
113
125
  bar.finish
114
126
  ```
115
127
 
116
- ### 1.5 complete?
128
+ ### 1.6 complete?
117
129
 
118
130
  During progresion you can check if bar is finished or not by calling `complete?`.
119
131
 
@@ -121,7 +133,15 @@ During progresion you can check if bar is finished or not by calling `complete?`
121
133
  bar.complete? # => false
122
134
  ```
123
135
 
124
- ### 1.6 resize
136
+ ### 1.7 reset
137
+
138
+ In order to reset currently running or finished progress bar to its original configuration and initial position use `reset` like so:
139
+
140
+ ```ruby
141
+ bar.reset
142
+ ```
143
+
144
+ ### 1.8 resize
125
145
 
126
146
  If you wish for a progress bar to change it's current width, you can use `resize` by passing in a new desired length:
127
147
 
@@ -139,6 +159,7 @@ There are number of configuration options that can be provided:
139
159
  * `incomplete` incomplete character by default single space
140
160
  * `output` the output stream defaulting to `stderr`
141
161
  * `frequency` used to throttle the output, by default `0` (see [Frequency](#21-frequency))
162
+ * `interval` used to measure the speed, by default `1 sec` (see [Interval](#22-interval))
142
163
  * `hide_cursor` to hide display cursor defaulting to `false`
143
164
  * `clear` to clear the finished bar defaulting to `false`
144
165
 
@@ -162,6 +183,18 @@ The `frequency` option accepts `integer` representing number of `Hz` units, for
162
183
  TTY::ProgressBar.new("[:bar]", total: 30, frequency: 10) # 10 Hz
163
184
  ```
164
185
 
186
+ ### 2.2 Interval
187
+
188
+ For every call of `advance` method the **ProgressBar** takes a sample for speed measurement. By default the samples are grouped per second but you can change that by passing the `interval` option.
189
+
190
+ The `interval` option is an `integer` that represents the number of seconds, for example, interval of `60` would mean that speed is measured per 1 minute.
191
+
192
+ ```ruby
193
+ TTY::ProgressBar.new(":rate/minute", total: 100, interval: 60) # 1 minute
194
+
195
+ TTY::ProgressBar.new(":rate/hour", total: 100, interval: 3600) # 1 hour
196
+ ```
197
+
165
198
  ## 3. Formatting
166
199
 
167
200
  Every **TTY::ProgressBar** instance requires a format string, which apart from regular characters accepts special tokens to display dynamic information. For instance, a format to measure download progress could be:
@@ -182,6 +215,10 @@ These are the tokens that are currently supported:
182
215
  * `:percent` the completion percentage
183
216
  * `:elapsed` the elapsed time in seconds
184
217
  * `:eta` the esitmated time to completion in seconds
218
+ * `:rate` the current rate of progression per second
219
+ * `:byte_rate` the current rate of pregression in bytes per second
220
+ * `:mean_rate` the averaged rate of progression per second
221
+ * `:mean_byte` the averaged rate of progression in bytes per second
185
222
 
186
223
  ### 3.2 Custom Formatters
187
224
 
@@ -277,6 +314,23 @@ To see how a progress bar is reported in terminal you can do:
277
314
  end
278
315
  ```
279
316
 
317
+ ### 5.2 Speed
318
+
319
+ Commonly a progress bar is utilized to measure download speed per second. This can be done like so:
320
+
321
+ ```ruby
322
+ TTY::ProgressBar.new("[:bar] :byte_rate/s") do |config|
323
+ config.total = 300000
324
+ config.interval = 1 # => 1 sec
325
+ end
326
+ ```
327
+
328
+ This will result in output similar to:
329
+
330
+ ```ruby
331
+ downloading [======================= ] 4.12MB/s
332
+ ```
333
+
280
334
  ## Contributing
281
335
 
282
336
  1. Fork it ( https://github.com/peter-murach/tty-progressbar/fork )
@@ -287,4 +341,4 @@ end
287
341
 
288
342
  ## Copyright
289
343
 
290
- Copyright (c) 2014 Piotr Murach. See LICENSE for further details.
344
+ Copyright (c) 2015 Piotr Murach. See LICENSE for further details.
data/examples/speed.rb ADDED
@@ -0,0 +1,13 @@
1
+ # coding: utf-8
2
+
3
+ require 'tty-progressbar'
4
+
5
+ bar = TTY::ProgressBar.new "downloading [:bar] :rate/s :mean_rate/s" do |conf|
6
+ conf.total = 100
7
+ conf.interval = 1
8
+ end
9
+
10
+ 30.times do
11
+ sleep(0.1)
12
+ bar.advance(Random.rand(10))
13
+ end
@@ -22,6 +22,8 @@ module TTY
22
22
 
23
23
  attr_accessor :frequency
24
24
 
25
+ attr_accessor :interval
26
+
25
27
  def initialize(options)
26
28
  self.total = options[:total] if options[:total]
27
29
  @width = options.fetch(:width) { total }
@@ -31,6 +31,20 @@ module TTY
31
31
  end
32
32
  end
33
33
 
34
+ # Convert seconds to set precision
35
+ #
36
+ # @param [Numeric] seconds
37
+ # the seconds to convert
38
+ #
39
+ # @return [String]
40
+ # the formatted result
41
+ #
42
+ # @api public
43
+ def to_seconds(seconds, precision = nil)
44
+ precision ||= (seconds < 1 && !seconds.zero?) ? 5 : 2
45
+ sprintf "%5.#{precision}f", seconds
46
+ end
47
+
34
48
  KILOBYTE = 1024
35
49
  MEGABYTE = KILOBYTE * 1024
36
50
  GIGABYTE = MEGABYTE * 1024
@@ -0,0 +1,39 @@
1
+ # coding: utf-8
2
+
3
+ module TTY
4
+ class ProgressBar
5
+ # Used by {Pipeline} to format :current token
6
+ #
7
+ # @api private
8
+ class ByteRateFormatter
9
+ MATCHER = /:byte_rate/i
10
+
11
+ def initialize(progress)
12
+ @progress = progress
13
+ @converter = Converter.new
14
+ end
15
+
16
+ # Determines whether this formatter is applied or not.
17
+ #
18
+ # @param [Object] value
19
+ #
20
+ # @return [Boolean]
21
+ #
22
+ # @api private
23
+ def matches?(value)
24
+ !!(value.to_s =~ MATCHER)
25
+ end
26
+
27
+ # Format :byte_rate token
28
+ #
29
+ # @param [String] value
30
+ # the value being formatted
31
+ #
32
+ # @api public
33
+ def format(value)
34
+ formatted = @converter.to_bytes(@progress.rate)
35
+ value.gsub(MATCHER, formatted)
36
+ end
37
+ end # ByteRateFormatter
38
+ end # ProgressBar
39
+ end # TTY
@@ -6,7 +6,7 @@ module TTY
6
6
  #
7
7
  # @api private
8
8
  class CurrentFormatter
9
- MATCHER = /:current(?!_)/
9
+ MATCHER = /:current\b/i.freeze
10
10
 
11
11
  def initialize(progress)
12
12
  @progress = progress
@@ -3,7 +3,7 @@
3
3
  module TTY
4
4
  class ProgressBar
5
5
  class ByteFormatter
6
- MATCHER = /:current_byte|:byte/.freeze
6
+ MATCHER = /(:current_byte|:byte)\b/i.freeze
7
7
  # Used by {Pipeline} to format :byte token
8
8
  #
9
9
  # @api private
@@ -0,0 +1,39 @@
1
+ # coding: utf-8
2
+
3
+ module TTY
4
+ class ProgressBar
5
+ # Used by {Pipeline} to format :current token
6
+ #
7
+ # @api private
8
+ class MeanByteFormatter
9
+ MATCHER = /:mean_byte/i.freeze
10
+
11
+ def initialize(progress)
12
+ @progress = progress
13
+ @converter = Converter.new
14
+ end
15
+
16
+ # Determines whether this formatter is applied or not.
17
+ #
18
+ # @param [Object] value
19
+ #
20
+ # @return [Boolean]
21
+ #
22
+ # @api private
23
+ def matches?(value)
24
+ !!(value.to_s =~ MATCHER)
25
+ end
26
+
27
+ # Format :rate token
28
+ #
29
+ # @param [String] value
30
+ # the value being formatted
31
+ #
32
+ # @api public
33
+ def format(value)
34
+ formatted = @converter.to_bytes(@progress.mean_rate)
35
+ value.gsub(MATCHER, formatted)
36
+ end
37
+ end # MeanByteFormatter
38
+ end # ProgressBar
39
+ end # TTY
@@ -0,0 +1,39 @@
1
+ # coding: utf-8
2
+
3
+ module TTY
4
+ class ProgressBar
5
+ # Used by {Pipeline} to format :current token
6
+ #
7
+ # @api private
8
+ class MeanRateFormatter
9
+ MATCHER = /:mean_rate/i.freeze
10
+
11
+ def initialize(progress)
12
+ @progress = progress
13
+ @converter = Converter.new
14
+ end
15
+
16
+ # Determines whether this formatter is applied or not.
17
+ #
18
+ # @param [Object] value
19
+ #
20
+ # @return [Boolean]
21
+ #
22
+ # @api private
23
+ def matches?(value)
24
+ !!(value.to_s =~ MATCHER)
25
+ end
26
+
27
+ # Format :rate token
28
+ #
29
+ # @param [String] value
30
+ # the value being formatted
31
+ #
32
+ # @api public
33
+ def format(value)
34
+ formatted = @converter.to_seconds(@progress.mean_rate)
35
+ value.gsub(MATCHER, formatted)
36
+ end
37
+ end # MeanRateFormatter
38
+ end # ProgressBar
39
+ end # TTY
@@ -6,7 +6,7 @@ module TTY
6
6
  #
7
7
  # @api private
8
8
  class PercentFormatter
9
- MATCHER = /:percent/.freeze
9
+ MATCHER = /:percent\b/.freeze
10
10
 
11
11
  def initialize(progress, *args, &block)
12
12
  @progress = progress
@@ -0,0 +1,39 @@
1
+ # coding: utf-8
2
+
3
+ module TTY
4
+ class ProgressBar
5
+ # Used by {Pipeline} to format :current token
6
+ #
7
+ # @api private
8
+ class RateFormatter
9
+ MATCHER = /:rate/i.freeze
10
+
11
+ def initialize(progress)
12
+ @progress = progress
13
+ @converter = Converter.new
14
+ end
15
+
16
+ # Determines whether this formatter is applied or not.
17
+ #
18
+ # @param [Object] value
19
+ #
20
+ # @return [Boolean]
21
+ #
22
+ # @api private
23
+ def matches?(value)
24
+ !!(value.to_s =~ MATCHER)
25
+ end
26
+
27
+ # Format :rate token
28
+ #
29
+ # @param [String] value
30
+ # the value being formatted
31
+ #
32
+ # @api public
33
+ def format(value)
34
+ formatted = @converter.to_seconds(@progress.rate)
35
+ value.gsub(MATCHER, formatted)
36
+ end
37
+ end # RateFormatter
38
+ end # ProgressBar
39
+ end # TTY
@@ -3,7 +3,7 @@
3
3
  module TTY
4
4
  class ProgressBar
5
5
  class TotalFormatter
6
- MATCHER = /:total(?!_)/.freeze
6
+ MATCHER = /:total\b/i.freeze
7
7
 
8
8
  def initialize(progress, *args, &block)
9
9
  @progress = progress
@@ -6,7 +6,7 @@ module TTY
6
6
  #
7
7
  # @api private
8
8
  class TotalByteFormatter
9
- MATCHER = /:total_byte/.freeze
9
+ MATCHER = /:total_byte/i.freeze
10
10
 
11
11
  def initialize(progress, *args, &block)
12
12
  @progress = progress
@@ -23,6 +23,10 @@ module TTY
23
23
  @pipeline.use TTY::ProgressBar::EstimatedFormatter
24
24
  @pipeline.use TTY::ProgressBar::PercentFormatter
25
25
  @pipeline.use TTY::ProgressBar::ByteFormatter
26
+ @pipeline.use TTY::ProgressBar::ByteRateFormatter
27
+ @pipeline.use TTY::ProgressBar::RateFormatter
28
+ @pipeline.use TTY::ProgressBar::MeanRateFormatter
29
+ @pipeline.use TTY::ProgressBar::MeanByteFormatter
26
30
  @pipeline.use TTY::ProgressBar::BarFormatter
27
31
  end
28
32
  end # Formatter
@@ -0,0 +1,81 @@
1
+ # coding: utf-8
2
+
3
+ module TTY
4
+ class ProgressBar
5
+ # Used by {ProgressBar} to measure progress rate per interval
6
+ # by default 1s
7
+ #
8
+ # @api privatek
9
+ class Meter
10
+ # Create Meter
11
+ #
12
+ # @param [Integer] interval
13
+ # the interval for measurement samples
14
+ #
15
+ # @api private
16
+ def initialize(interval)
17
+ @samples = Hash.new { |h, el| h[el] = [] }
18
+ @interval = interval || 1 # 1 sec
19
+ @marker = 0
20
+
21
+ @start_time = Time.now.to_f
22
+ @last_sample_at = @start_time
23
+ end
24
+
25
+ def start
26
+ @start_time = Time.now.to_f
27
+ @last_sample_at = @start_time
28
+ end
29
+
30
+ # Update meter with value
31
+ #
32
+ # @api public
33
+ def sample(at, value)
34
+ if @interval < at.to_f - @last_sample_at
35
+ @marker += 1
36
+ end
37
+ @samples[@marker] << value
38
+
39
+ @last_sample_at = at.to_f
40
+ end
41
+
42
+ # The rate of sampling
43
+ #
44
+ # @api public
45
+ def rate
46
+ samples = @samples[@marker]
47
+ result = samples.inject(:+).to_f / samples.size
48
+ result.nan? ? 0 : result
49
+ end
50
+
51
+ # Group all rates per interval
52
+ #
53
+ # @api public
54
+ def rates
55
+ @samples.reduce([]) do |acc, (key, _)|
56
+ acc << @samples[key].reduce(:+)
57
+ end
58
+ end
59
+
60
+ # The mean rate
61
+ #
62
+ # @api public
63
+ def mean_rate
64
+ if rates.size == 1
65
+ rate
66
+ else
67
+ rates.reduce(:+).to_f / rates.size
68
+ end
69
+ end
70
+ alias_method :avg_rate, :mean_rate
71
+
72
+ # Reset the meter by clearing out it's metrics
73
+ #
74
+ # @api public
75
+ def clear
76
+ @marker = 0
77
+ @samples.clear
78
+ end
79
+ end # Meter
80
+ end # ProgressBar
81
+ end # TTY
@@ -2,6 +2,6 @@
2
2
 
3
3
  module TTY
4
4
  class ProgressBar
5
- VERSION = "0.4.0"
5
+ VERSION = '0.5.0'
6
6
  end # ProgressBar
7
7
  end # TTY
@@ -1,24 +1,5 @@
1
1
  # coding: utf-8
2
2
 
3
- require 'io/console'
4
- require 'forwardable'
5
- require 'tty-screen'
6
-
7
- require 'tty/progressbar/configuration'
8
- require 'tty/progressbar/converter'
9
- require 'tty/progressbar/version'
10
- require 'tty/progressbar/pipeline'
11
- require 'tty/progressbar/formatter'
12
-
13
- require 'tty/progressbar/formatter/bar'
14
- require 'tty/progressbar/formatter/current'
15
- require 'tty/progressbar/formatter/current_byte'
16
- require 'tty/progressbar/formatter/elapsed'
17
- require 'tty/progressbar/formatter/estimated'
18
- require 'tty/progressbar/formatter/percent'
19
- require 'tty/progressbar/formatter/total'
20
- require 'tty/progressbar/formatter/total_byte'
21
-
22
3
  module TTY
23
4
  # Used for creating terminal progress bar
24
5
  #
@@ -45,6 +26,8 @@ module TTY
45
26
  :complete, :incomplete, :hide_cursor, :clear,
46
27
  :output, :frequency
47
28
 
29
+ def_delegators :@meter, :rate, :mean_rate
30
+
48
31
  def_delegator :@formatter, :use
49
32
 
50
33
  # Create progress bar
@@ -83,12 +66,25 @@ module TTY
83
66
  @last_render_width = 0
84
67
  @done = false
85
68
  @start_at = Time.now
69
+ @started = false
86
70
  @formatter = TTY::ProgressBar::Formatter.new
71
+ @meter = Meter.new(options.fetch(:interval, 1))
87
72
 
88
73
  @formatter.load
89
74
  register_callbacks
90
75
  end
91
76
 
77
+ # Start progression by drawing bar and setting time
78
+ #
79
+ # @api public
80
+ def start
81
+ @started = true
82
+ @started_at = Time.now
83
+ @meter.start
84
+
85
+ advance(0)
86
+ end
87
+
92
88
  # Advance the progress bar
93
89
  #
94
90
  # @param [Object|Number] progress
@@ -97,9 +93,10 @@ module TTY
97
93
  def advance(progress = 1)
98
94
  return if @done
99
95
 
100
- @start_at = Time.now if @current.zero?
96
+ @start_at = Time.now if @current.zero? && !@started
101
97
  @readings += 1
102
98
  @current += progress
99
+ @meter.sample(Time.now, progress)
103
100
 
104
101
  if !no_width && @current >= total
105
102
  finish && return
@@ -196,9 +193,10 @@ module TTY
196
193
  write(ECMA_CSI + DEC_TCEM + DEC_SET, false)
197
194
  end
198
195
  return if @done
199
- @current = width if no_width
196
+ @current = total unless no_width
200
197
  render
201
198
  clear ? clear_line : write("\n", false)
199
+ @meter.clear
202
200
  @done = true
203
201
  end
204
202
 
@@ -209,6 +207,18 @@ module TTY
209
207
  output.print(ECMA_CSI + '0m' + ECMA_CSI + '1000D' + ECMA_CSI + ECMA_CLR)
210
208
  end
211
209
 
210
+ # Reset progress to default configuration
211
+ #
212
+ # @api public
213
+ def reset
214
+ @current = 0
215
+ @readings = 0
216
+ @done = false
217
+ @meter.clear
218
+
219
+ advance(0) # rerender with new configuration
220
+ end
221
+
212
222
  # Check if progress is finised
213
223
  #
214
224
  # @return [Boolean]
@@ -257,6 +267,8 @@ module TTY
257
267
  message
258
268
  end
259
269
 
270
+ EXIT_SIGS = [:QUIT, :TERM, :INT]
271
+
260
272
  # Handle resize and kill signals
261
273
  #
262
274
  # @api private
@@ -267,7 +279,9 @@ module TTY
267
279
  end
268
280
  Signal.trap('WINCH', &callback)
269
281
 
270
- Signal.trap('INT') { finish }
282
+ EXIT_SIGS.each do |sig|
283
+ Signal.trap(sig) { finish && fail(Interrupt) }
284
+ end
271
285
  end
272
286
  end # ProgressBar
273
287
  end # TTY
@@ -1,3 +1,27 @@
1
1
  # coding: utf-8
2
2
 
3
+ require 'io/console'
4
+ require 'forwardable'
5
+ require 'tty-screen'
6
+
7
+ require 'tty/progressbar/configuration'
8
+ require 'tty/progressbar/converter'
9
+ require 'tty/progressbar/version'
10
+ require 'tty/progressbar/pipeline'
11
+ require 'tty/progressbar/formatter'
12
+ require 'tty/progressbar/meter'
13
+
14
+ require 'tty/progressbar/formatter/bar'
15
+ require 'tty/progressbar/formatter/current'
16
+ require 'tty/progressbar/formatter/current_byte'
17
+ require 'tty/progressbar/formatter/elapsed'
18
+ require 'tty/progressbar/formatter/estimated'
19
+ require 'tty/progressbar/formatter/percent'
20
+ require 'tty/progressbar/formatter/rate'
21
+ require 'tty/progressbar/formatter/byte_rate'
22
+ require 'tty/progressbar/formatter/mean_rate'
23
+ require 'tty/progressbar/formatter/mean_byte'
24
+ require 'tty/progressbar/formatter/total'
25
+ require 'tty/progressbar/formatter/total_byte'
26
+
3
27
  require 'tty/progressbar'
@@ -0,0 +1,19 @@
1
+ # coding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe TTY::ProgressBar::Converter, '.to_seconds' do
6
+ subject(:converter) { described_class.new }
7
+
8
+ it "ensure 5 digit precision for < 1" do
9
+ expect(converter.to_seconds(0.000005)).to eq("0.00001")
10
+ end
11
+
12
+ it "rounds 0 to 0.00" do
13
+ expect(converter.to_seconds(0)).to eq(" 0.00")
14
+ end
15
+
16
+ it "ensures 2 digit precision for > 1" do
17
+ expect(converter.to_seconds(11.2)).to eq("11.20")
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ # coding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe TTY::ProgressBar, '.finish' do
6
+ let(:output) { StringIO.new('', 'w+') }
7
+
8
+ it 'finishes progress' do
9
+ progress = TTY::ProgressBar.new("[:bar]", output: output, total: 10)
10
+ progress.advance
11
+ progress.finish
12
+ expect(progress.complete?).to be(true)
13
+ output.rewind
14
+ expect(output.read).to eq([
15
+ "\e[1G[= ]",
16
+ "\e[1G[==========]\n"
17
+ ].join)
18
+ end
19
+ end
@@ -0,0 +1,29 @@
1
+ # coding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe TTY::ProgressBar, 'byte_rate' do
6
+ let(:output) { StringIO.new('', 'w+') }
7
+
8
+ before { Timecop.safe_mode = false }
9
+
10
+ it "shows current rate in bytes per sec" do
11
+ time_now = Time.local(2014, 10, 5, 12, 0, 0)
12
+ Timecop.freeze(time_now)
13
+ progress = TTY::ProgressBar.new(":byte_rate", output: output, total: 10000, interval: 1)
14
+ 5.times do |i|
15
+ time_now = Time.local(2014, 10, 5, 12, 0, i * 2)
16
+ Timecop.freeze(time_now)
17
+ progress.advance(i * 1000)
18
+ end
19
+ output.rewind
20
+ expect(output.read).to eq([
21
+ "\e[1G0.0B",
22
+ "\e[1G1000.0B",
23
+ "\e[1G1.95KB",
24
+ "\e[1G2.93KB",
25
+ "\e[1G3.91KB\n"
26
+ ].join)
27
+ Timecop.return
28
+ end
29
+ end
@@ -28,4 +28,36 @@ RSpec.describe TTY::ProgressBar, 'elapsed' do
28
28
  ].join)
29
29
  Timecop.return
30
30
  end
31
+
32
+ it "resets elapsed time" do
33
+ time_now = Time.local(2014, 10, 5, 12, 0, 0)
34
+ Timecop.freeze(time_now)
35
+ progress = TTY::ProgressBar.new(":elapsed", output: output, total: 5)
36
+
37
+ 5.times do |sec|
38
+ time_now = Time.local(2014, 10, 5, 12, 0, sec)
39
+ Timecop.freeze(time_now)
40
+ progress.advance
41
+ end
42
+ expect(progress.complete?).to be(true)
43
+ progress.reset
44
+ 2.times do |sec|
45
+ time_now = Time.local(2014, 10, 5, 13, 0, sec)
46
+ Timecop.freeze(time_now)
47
+ progress.advance
48
+ end
49
+
50
+ output.rewind
51
+ expect(output.read).to eq([
52
+ "\e[1G 0s",
53
+ "\e[1G 1s",
54
+ "\e[1G 2s",
55
+ "\e[1G 3s",
56
+ "\e[1G 4s\n",
57
+ "\e[1G 0s",
58
+ "\e[1G 0s",
59
+ "\e[1G 1s"
60
+ ].join)
61
+ Timecop.return
62
+ end
31
63
  end
@@ -0,0 +1,29 @@
1
+ # coding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe TTY::ProgressBar, 'mean_byte' do
6
+ let(:output) { StringIO.new('', 'w+') }
7
+
8
+ before { Timecop.safe_mode = false }
9
+
10
+ it "shows mean rate in bytes per sec" do
11
+ time_now = Time.local(2014, 10, 5, 12, 0, 0)
12
+ Timecop.freeze(time_now)
13
+ progress = TTY::ProgressBar.new(":mean_byte", output: output, total: 10000, interval: 1)
14
+ 5.times do |i|
15
+ time_now = Time.local(2014, 10, 5, 12, 0, i * 2)
16
+ Timecop.freeze(time_now)
17
+ progress.advance(i * 1000)
18
+ end
19
+ output.rewind
20
+ expect(output.read).to eq([
21
+ "\e[1G0.0B",
22
+ "\e[1G500.0B",
23
+ "\e[1G1000.0B",
24
+ "\e[1G1.46KB",
25
+ "\e[1G1.95KB\n"
26
+ ].join)
27
+ Timecop.return
28
+ end
29
+ end
@@ -0,0 +1,29 @@
1
+ # coding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe TTY::ProgressBar, 'mean_rate' do
6
+ let(:output) { StringIO.new('', 'w+') }
7
+
8
+ before { Timecop.safe_mode = false }
9
+
10
+ it "shows current rate per sec" do
11
+ time_now = Time.local(2014, 10, 5, 12, 0, 0)
12
+ Timecop.freeze(time_now)
13
+ progress = TTY::ProgressBar.new(":mean_rate", output: output, total: 100, interval: 1)
14
+ 5.times do |i|
15
+ time_now = Time.local(2014, 10, 5, 12, 0, i * 2)
16
+ Timecop.freeze(time_now)
17
+ progress.advance(i * 10)
18
+ end
19
+ output.rewind
20
+ expect(output.read).to eq([
21
+ "\e[1G 0.00",
22
+ "\e[1G 5.00",
23
+ "\e[1G10.00",
24
+ "\e[1G15.00",
25
+ "\e[1G20.00\n"
26
+ ].join)
27
+ Timecop.return
28
+ end
29
+ end
@@ -0,0 +1,29 @@
1
+ # coding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe TTY::ProgressBar, 'rate' do
6
+ let(:output) { StringIO.new('', 'w+') }
7
+
8
+ before { Timecop.safe_mode = false }
9
+
10
+ it "shows current rate per sec" do
11
+ time_now = Time.local(2014, 10, 5, 12, 0, 0)
12
+ Timecop.freeze(time_now)
13
+ progress = TTY::ProgressBar.new(":rate", output: output, total: 100, interval: 1)
14
+ 5.times do |i|
15
+ time_now = Time.local(2014, 10, 5, 12, 0, i * 2)
16
+ Timecop.freeze(time_now)
17
+ progress.advance(i * 10)
18
+ end
19
+ output.rewind
20
+ expect(output.read).to eq([
21
+ "\e[1G 0.00",
22
+ "\e[1G10.00",
23
+ "\e[1G20.00",
24
+ "\e[1G30.00",
25
+ "\e[1G40.00\n"
26
+ ].join)
27
+ Timecop.return
28
+ end
29
+ end
@@ -1,3 +1,5 @@
1
+ # coding: utf-8
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  RSpec.describe TTY::ProgressBar, 'frequency' do
@@ -0,0 +1,72 @@
1
+ # coding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe TTY::ProgressBar::Meter, '' do
6
+
7
+ before { Timecop.safe_mode = false }
8
+
9
+ after { Timecop.return }
10
+
11
+ it "measures rate per second" do
12
+ meter = TTY::ProgressBar::Meter.new(1)
13
+ meter.start
14
+ time_now = Time.local(2014, 10, 5, 12, 0, 0)
15
+ Timecop.freeze(time_now)
16
+
17
+ # First sample batch
18
+ time_now = Time.local(2014, 10, 5, 12, 0, 0, 100)
19
+ meter.sample time_now, 1000
20
+ expect(meter.rate).to eq(1000)
21
+ expect(meter.mean_rate).to eq(1000)
22
+
23
+ time_now = Time.local(2014, 10, 5, 12, 0, 0, 200)
24
+ meter.sample time_now, 2000
25
+ expect(meter.rate).to eq(1500)
26
+ expect(meter.mean_rate).to eq(1500)
27
+
28
+ time_now = Time.local(2014, 10, 5, 12, 0, 0, 300)
29
+ meter.sample time_now, 1000
30
+ expect(meter.rate).to be_within(0.5).of(1333)
31
+ expect(meter.mean_rate).to be_within(0.5).of(1333)
32
+
33
+ # Second sample batch after 1s
34
+ time_now = Time.local(2014, 10, 5, 12, 0, 1, 400)
35
+ meter.sample time_now, 500
36
+ expect(meter.rate).to eq(500)
37
+ expect(meter.mean_rate).to eq(2250)
38
+
39
+ time_now = Time.local(2014, 10, 5, 12, 0, 1, 500)
40
+ meter.sample time_now, 500
41
+ expect(meter.rate).to eq(500)
42
+ expect(meter.mean_rate).to eq(2500)
43
+
44
+ # Third sample batch after 3s
45
+ time_now = Time.local(2014, 10, 5, 12, 0, 2, 600)
46
+ meter.sample time_now, 3000
47
+ expect(meter.rate).to eq(3000)
48
+ expect(meter.mean_rate).to be_within(0.7).of(2666)
49
+
50
+ time_now = Time.local(2014, 10, 5, 12, 0, 2, 700)
51
+ meter.sample time_now, 3000
52
+ expect(meter.rate).to eq(3000)
53
+ expect(meter.mean_rate).to be_within(0.7).of(3666)
54
+ end
55
+
56
+ it "clears measurements" do
57
+ meter = TTY::ProgressBar::Meter.new(1)
58
+ meter.start
59
+ time_now = Time.local(2014, 10, 5, 12, 0, 0)
60
+ Timecop.freeze(time_now)
61
+
62
+ time_now = Time.local(2014, 10, 5, 12, 0, 0, 100)
63
+ meter.sample time_now, 1000
64
+ expect(meter.rates).to eq([1000])
65
+ expect(meter.rate).to eq(1000)
66
+
67
+ meter.clear
68
+ expect(meter.rates).to eq([])
69
+ expect(meter.rate).to eq(0)
70
+ end
71
+ end
72
+
@@ -0,0 +1,37 @@
1
+ # coding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe TTY::ProgressBar, '.reset' do
6
+ let(:output) { StringIO.new('', 'w+') }
7
+
8
+ it "resets current progress" do
9
+ progress = TTY::ProgressBar.new("[:bar]", output: output, total: 10)
10
+ progress.advance(5)
11
+ progress.reset
12
+ 2.times { progress.advance(3) }
13
+ output.rewind
14
+ expect(output.read).to eq([
15
+ "\e[1G[===== ]",
16
+ "\e[1G[ ]",
17
+ "\e[1G[=== ]",
18
+ "\e[1G[====== ]"
19
+ ].join)
20
+ end
21
+
22
+ it "resets finished progress" do
23
+ progress = TTY::ProgressBar.new("[:bar]", output: output, total: 10)
24
+ progress.advance(10)
25
+ expect(progress.complete?).to be(true)
26
+ progress.reset
27
+ expect(progress.complete?).to be(false)
28
+ 2.times { progress.advance(3) }
29
+ output.rewind
30
+ expect(output.read).to eq([
31
+ "\e[1G[==========]\n",
32
+ "\e[1G[ ]",
33
+ "\e[1G[=== ]",
34
+ "\e[1G[====== ]"
35
+ ].join)
36
+ end
37
+ end
@@ -0,0 +1,18 @@
1
+ # coding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe TTY::ProgressBar, '.start' do
6
+ let(:output) { StringIO.new('', 'w+') }
7
+
8
+ it "starts timer and draws initial progress" do
9
+ progress = TTY::ProgressBar.new("[:bar]", output: output, total: 10)
10
+ progress.start
11
+ progress.advance
12
+ output.rewind
13
+ expect(output.read).to eq([
14
+ "\e[1G[ ]",
15
+ "\e[1G[= ]"
16
+ ].join)
17
+ end
18
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tty-progressbar
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Piotr Murach
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-12-25 00:00:00.000000000 Z
11
+ date: 2015-01-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: tty-screen
@@ -56,19 +56,25 @@ files:
56
56
  - Rakefile
57
57
  - examples/color.rb
58
58
  - examples/simple.rb
59
+ - examples/speed.rb
59
60
  - lib/tty-progressbar.rb
60
61
  - lib/tty/progressbar.rb
61
62
  - lib/tty/progressbar/configuration.rb
62
63
  - lib/tty/progressbar/converter.rb
63
64
  - lib/tty/progressbar/formatter.rb
64
65
  - lib/tty/progressbar/formatter/bar.rb
66
+ - lib/tty/progressbar/formatter/byte_rate.rb
65
67
  - lib/tty/progressbar/formatter/current.rb
66
68
  - lib/tty/progressbar/formatter/current_byte.rb
67
69
  - lib/tty/progressbar/formatter/elapsed.rb
68
70
  - lib/tty/progressbar/formatter/estimated.rb
71
+ - lib/tty/progressbar/formatter/mean_byte.rb
72
+ - lib/tty/progressbar/formatter/mean_rate.rb
69
73
  - lib/tty/progressbar/formatter/percent.rb
74
+ - lib/tty/progressbar/formatter/rate.rb
70
75
  - lib/tty/progressbar/formatter/total.rb
71
76
  - lib/tty/progressbar/formatter/total_byte.rb
77
+ - lib/tty/progressbar/meter.rb
72
78
  - lib/tty/progressbar/pipeline.rb
73
79
  - lib/tty/progressbar/version.rb
74
80
  - spec/spec_helper.rb
@@ -76,24 +82,33 @@ files:
76
82
  - spec/unit/clear_spec.rb
77
83
  - spec/unit/complete_spec.rb
78
84
  - spec/unit/converter/to_bytes_spec.rb
85
+ - spec/unit/converter/to_seconds_spec.rb
79
86
  - spec/unit/converter/to_time_spec.rb
80
87
  - spec/unit/custom_formatter_spec.rb
88
+ - spec/unit/finish_spec.rb
81
89
  - spec/unit/formatter/bar_spec.rb
90
+ - spec/unit/formatter/byte_rate_spec.rb
82
91
  - spec/unit/formatter/current_byte_spec.rb
83
92
  - spec/unit/formatter/current_spec.rb
84
93
  - spec/unit/formatter/elapsed_spec.rb
85
94
  - spec/unit/formatter/estimated_spec.rb
95
+ - spec/unit/formatter/mean_byte_spec.rb
96
+ - spec/unit/formatter/mean_rate_spec.rb
86
97
  - spec/unit/formatter/percent_spec.rb
98
+ - spec/unit/formatter/rate_spec.rb
87
99
  - spec/unit/formatter/total_byte_spec.rb
88
100
  - spec/unit/formatter/total_spec.rb
89
101
  - spec/unit/frequency_spec.rb
90
102
  - spec/unit/hide_cursor_spec.rb
91
103
  - spec/unit/log_spec.rb
104
+ - spec/unit/meter_spec.rb
92
105
  - spec/unit/new_spec.rb
93
106
  - spec/unit/pipeline_spec.rb
94
107
  - spec/unit/ratio_spec.rb
108
+ - spec/unit/reset_spec.rb
95
109
  - spec/unit/resize_spec.rb
96
110
  - spec/unit/set_current_spec.rb
111
+ - spec/unit/start_spec.rb
97
112
  - spec/unit/width_spec.rb
98
113
  - tasks/console.rake
99
114
  - tasks/coverage.rake
@@ -129,23 +144,32 @@ test_files:
129
144
  - spec/unit/clear_spec.rb
130
145
  - spec/unit/complete_spec.rb
131
146
  - spec/unit/converter/to_bytes_spec.rb
147
+ - spec/unit/converter/to_seconds_spec.rb
132
148
  - spec/unit/converter/to_time_spec.rb
133
149
  - spec/unit/custom_formatter_spec.rb
150
+ - spec/unit/finish_spec.rb
134
151
  - spec/unit/formatter/bar_spec.rb
152
+ - spec/unit/formatter/byte_rate_spec.rb
135
153
  - spec/unit/formatter/current_byte_spec.rb
136
154
  - spec/unit/formatter/current_spec.rb
137
155
  - spec/unit/formatter/elapsed_spec.rb
138
156
  - spec/unit/formatter/estimated_spec.rb
157
+ - spec/unit/formatter/mean_byte_spec.rb
158
+ - spec/unit/formatter/mean_rate_spec.rb
139
159
  - spec/unit/formatter/percent_spec.rb
160
+ - spec/unit/formatter/rate_spec.rb
140
161
  - spec/unit/formatter/total_byte_spec.rb
141
162
  - spec/unit/formatter/total_spec.rb
142
163
  - spec/unit/frequency_spec.rb
143
164
  - spec/unit/hide_cursor_spec.rb
144
165
  - spec/unit/log_spec.rb
166
+ - spec/unit/meter_spec.rb
145
167
  - spec/unit/new_spec.rb
146
168
  - spec/unit/pipeline_spec.rb
147
169
  - spec/unit/ratio_spec.rb
170
+ - spec/unit/reset_spec.rb
148
171
  - spec/unit/resize_spec.rb
149
172
  - spec/unit/set_current_spec.rb
173
+ - spec/unit/start_spec.rb
150
174
  - spec/unit/width_spec.rb
151
175
  has_rdoc: