tty-progressbar 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: