tty-progressbar 0.14.0 → 0.15.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +3 -2
- data/CHANGELOG.md +21 -1
- data/README.md +24 -2
- data/appveyor.yml +2 -0
- data/examples/multi/width.rb +13 -0
- data/examples/unicode.rb +7 -0
- data/lib/tty/progressbar.rb +46 -20
- data/lib/tty/progressbar/configuration.rb +16 -2
- data/lib/tty/progressbar/formatter/bar.rb +16 -5
- data/lib/tty/progressbar/multi.rb +10 -4
- data/lib/tty/progressbar/version.rb +1 -1
- data/spec/spec_helper.rb +1 -0
- data/spec/unit/custom_token_spec.rb +1 -1
- data/spec/unit/multi/reset_spec.rb +28 -0
- data/spec/unit/multi/width_spec.rb +118 -0
- data/spec/unit/new_spec.rb +10 -0
- data/spec/unit/render_spec.rb +25 -0
- data/spec/unit/resize_spec.rb +1 -1
- data/spec/unit/width_spec.rb +65 -0
- data/tty-progressbar.gemspec +3 -2
- metadata +24 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c2470861861ae00abd4f276cede9731c712d2508
|
4
|
+
data.tar.gz: 38d29289ddfd613781defa037dc1181654ef7a3a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1e2e6a01da4dcb082e8e55e1ecfc18841dd42a1cf1a2d622aa6d081d13f112a9f28fa4ef32cec33ffa68f50578a979eb3e4398f28145ac7204114a18a4145eaa
|
7
|
+
data.tar.gz: 5226faf2809e8939088d0d9ab4b91f391c687bc7e92149df9b13d0fbd6a7ea0a7a337863d9c1c54a59a6cbe92088605b0e915f6c7640d4b88d9e32b71fb6111a
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,25 @@
|
|
1
1
|
# Change log
|
2
2
|
|
3
|
-
## [v0.
|
3
|
+
## [v0.15.0] - 2018-06-24
|
4
|
+
|
5
|
+
### Added
|
6
|
+
* Add #format= for overriding formatting string
|
7
|
+
* Add #display_columns for determining display width of multibyte characters
|
8
|
+
* Add :inset option to bar configuration options
|
9
|
+
* Add ability to configure width for multi bar with top level bar
|
10
|
+
* Add unicode-display_width dependency
|
11
|
+
|
12
|
+
### Changed
|
13
|
+
* Change #update to only set configuration if actually present
|
14
|
+
* Change bar formatter to handle multibyte characters
|
15
|
+
|
16
|
+
### Fixed
|
17
|
+
* Fix to stop reseting multibar state when registered bar reset by Eric Hodel(@drbrain)
|
18
|
+
* Fix rendered bar to pad formatted output when it gets shorter by Eric Hodel(@drbrain)
|
19
|
+
* Fix multi bar to advance in steps matching each bar advance progress
|
20
|
+
* Fix multi bar rendering for widths exceeding screen columns count
|
21
|
+
|
22
|
+
## [v0.14.0] - 2018-01-17
|
4
23
|
|
5
24
|
### Changed
|
6
25
|
* Change to only output to a console and stop output to a file, pipe etc...
|
@@ -160,6 +179,7 @@
|
|
160
179
|
|
161
180
|
* Initial implementation and release
|
162
181
|
|
182
|
+
[v0.15.0]: https://github.com/peter-murach/tty-progressbar/compare/v0.14.0...v0.15.0
|
163
183
|
[v0.14.0]: https://github.com/peter-murach/tty-progressbar/compare/v0.13.0...v0.14.0
|
164
184
|
[v0.13.0]: https://github.com/peter-murach/tty-progressbar/compare/v0.12.2...v0.13.0
|
165
185
|
[v0.12.2]: https://github.com/peter-murach/tty-progressbar/compare/v0.12.1...v0.12.2
|
data/README.md
CHANGED
@@ -26,6 +26,7 @@
|
|
26
26
|
* Includes many predefined tokens to calculate ETA, Bytes ... [tokens](#41-tokens)
|
27
27
|
* Allows to define your [custom tokens](#42-custom-formatters)
|
28
28
|
* Supports parallel multi progress bars [multi](#6-ttyprogressbarmulti-api)
|
29
|
+
* Handles Unicode characters in progress bar [unicode](#44-unicode)
|
29
30
|
* Works on all ECMA-48 compatible terminals
|
30
31
|
|
31
32
|
## Installation
|
@@ -70,6 +71,7 @@ Or install it yourself as:
|
|
70
71
|
* [4.1 Tokens](#41-tokens)
|
71
72
|
* [4.2 Custom Formatters](#42-custom-formatters)
|
72
73
|
* [4.3 Custom Tokens](#43-custom-tokens)
|
74
|
+
* [4.4 Unicode](#44-unicode)
|
73
75
|
* [5. Logging](#5-logging)
|
74
76
|
* [6. TTY::ProgressBar::Multi API](#6-ttyprogressbarmulti-api)
|
75
77
|
* [6.1 new](#61-new)
|
@@ -302,10 +304,10 @@ trap(:WINCH) { bar.resize }
|
|
302
304
|
|
303
305
|
The progress bar fires events when it is progressing, stopped or finished. You can register to listen for events using the `on` message.
|
304
306
|
|
305
|
-
Every time an `advance` is called the `:progress` event gets fired which you can listen for:
|
307
|
+
Every time an `advance` is called the `:progress` event gets fired which you can listen for inside a block which includes the actual amount of progress as a first yielded argument:
|
306
308
|
|
307
309
|
```ruby
|
308
|
-
bar.on(:progress) { ... }
|
310
|
+
bar.on(:progress) { |amount| ... }
|
309
311
|
```
|
310
312
|
|
311
313
|
When the progress bar finishes and completes then the `:done` event is fired. You can listen for this event:
|
@@ -474,6 +476,26 @@ which outputs:
|
|
474
476
|
(4) Bye Piotr!
|
475
477
|
```
|
476
478
|
|
479
|
+
### 4.4 Unicode
|
480
|
+
|
481
|
+
The format string as well as `:complete`, `:head` and `:incompelte` configuration options can contain Unicode characters that aren't monospaced.
|
482
|
+
|
483
|
+
For example, you can specify complete bar progression character to be Unicode non-monospaced:
|
484
|
+
|
485
|
+
```ruby
|
486
|
+
bar = TTY::ProgressBar.new("Unicode [:bar]", total: 30, complete: 'あ')
|
487
|
+
#
|
488
|
+
# => Unicode [あああああああああああああああ]
|
489
|
+
```
|
490
|
+
|
491
|
+
Similarly, the formatted string can include Unicode characters:
|
492
|
+
|
493
|
+
```ruby
|
494
|
+
bar = TTY::ProgressBar.new("あめかんむり[:bar]", total: 20)
|
495
|
+
#
|
496
|
+
# => あめかんむり[== ]
|
497
|
+
```
|
498
|
+
|
477
499
|
## 5. Logging
|
478
500
|
|
479
501
|
If you want to print messages out to terminal along with the progress bar use the `log` method. The messages will appear above the progress bar and will continue scrolling up as more are logged out.
|
data/appveyor.yml
CHANGED
@@ -0,0 +1,13 @@
|
|
1
|
+
require_relative '../../lib/tty-progressbar'
|
2
|
+
|
3
|
+
bars = TTY::ProgressBar::Multi.new("main [:bar] :percent")
|
4
|
+
|
5
|
+
bar1 = bars.register "foo [:bar] :percent", total: 150
|
6
|
+
bar2 = bars.register "bar [:bar] :percent", total: 250
|
7
|
+
bar3 = bars.register "baz [:bar] :percent", total: 100
|
8
|
+
|
9
|
+
th1 = Thread.new { 15.times { sleep(0.1); bar1.advance(10) } }
|
10
|
+
th2 = Thread.new { 50.times { sleep(0.1); bar2.advance(5)} }
|
11
|
+
th3 = Thread.new { 50.times { sleep(0.1); bar3.advance(5) } }
|
12
|
+
|
13
|
+
[th1, th2, th3].each(&:join)
|
data/examples/unicode.rb
ADDED
data/lib/tty/progressbar.rb
CHANGED
@@ -5,6 +5,7 @@ require 'forwardable'
|
|
5
5
|
require 'monitor'
|
6
6
|
require 'tty-cursor'
|
7
7
|
require 'tty-screen'
|
8
|
+
require 'unicode/display_width'
|
8
9
|
|
9
10
|
require_relative 'progressbar/configuration'
|
10
11
|
require_relative 'progressbar/formatter'
|
@@ -23,7 +24,7 @@ module TTY
|
|
23
24
|
|
24
25
|
CURSOR_LOCK = Monitor.new
|
25
26
|
|
26
|
-
|
27
|
+
attr_accessor :format
|
27
28
|
|
28
29
|
attr_reader :current
|
29
30
|
|
@@ -33,12 +34,33 @@ module TTY
|
|
33
34
|
|
34
35
|
def_delegators :@configuration, :total, :width, :no_width,
|
35
36
|
:complete, :incomplete, :head, :hide_cursor, :clear,
|
36
|
-
:output, :frequency, :interval, :width=
|
37
|
+
:output, :frequency, :interval, :inset, :width=
|
37
38
|
|
38
39
|
def_delegators :@meter, :rate, :mean_rate
|
39
40
|
|
40
41
|
def_delegator :@formatter, :use
|
41
42
|
|
43
|
+
# Determine terminal width
|
44
|
+
#
|
45
|
+
# @return [Integer]
|
46
|
+
#
|
47
|
+
# @api public
|
48
|
+
def self.max_columns
|
49
|
+
TTY::Screen.width
|
50
|
+
end
|
51
|
+
|
52
|
+
# Determine the monospace display width of a string
|
53
|
+
#
|
54
|
+
# @param [String] value
|
55
|
+
# the value to determine width of
|
56
|
+
#
|
57
|
+
# @return [Integer]
|
58
|
+
#
|
59
|
+
# @api public
|
60
|
+
def self.display_columns(value)
|
61
|
+
Unicode::DisplayWidth.of(value)
|
62
|
+
end
|
63
|
+
|
42
64
|
# Create progress bar
|
43
65
|
#
|
44
66
|
# @param [String] format
|
@@ -80,6 +102,10 @@ module TTY
|
|
80
102
|
|
81
103
|
@formatter.load
|
82
104
|
reset
|
105
|
+
|
106
|
+
@first_render = true
|
107
|
+
@multibar = nil
|
108
|
+
@row = nil
|
83
109
|
end
|
84
110
|
|
85
111
|
# Reset progress to default configuration
|
@@ -96,9 +122,6 @@ module TTY
|
|
96
122
|
@start_at = Time.now
|
97
123
|
@started = false
|
98
124
|
@tokens = {}
|
99
|
-
@multibar = nil
|
100
|
-
@row = nil
|
101
|
-
@first_render = true
|
102
125
|
|
103
126
|
@meter.clear
|
104
127
|
end
|
@@ -135,7 +158,7 @@ module TTY
|
|
135
158
|
return if done?
|
136
159
|
|
137
160
|
synchronize do
|
138
|
-
emit(:progress)
|
161
|
+
emit(:progress, progress)
|
139
162
|
if progress.respond_to?(:to_hash)
|
140
163
|
tokens, progress = progress, 1
|
141
164
|
end
|
@@ -201,7 +224,9 @@ module TTY
|
|
201
224
|
def update(options = {})
|
202
225
|
synchronize do
|
203
226
|
options.each do |name, val|
|
204
|
-
@configuration.
|
227
|
+
if @configuration.respond_to?("#{name}=")
|
228
|
+
@configuration.public_send("#{name}=", val)
|
229
|
+
end
|
205
230
|
end
|
206
231
|
end
|
207
232
|
end
|
@@ -250,14 +275,22 @@ module TTY
|
|
250
275
|
write(TTY::Cursor.hide)
|
251
276
|
end
|
252
277
|
|
278
|
+
if @multibar
|
279
|
+
characters_in = @multibar.line_inset(self)
|
280
|
+
update(inset: self.class.display_columns(characters_in))
|
281
|
+
end
|
282
|
+
|
253
283
|
formatted = @formatter.decorate(self, @format)
|
254
284
|
@tokens.each do |token, val|
|
255
285
|
formatted = formatted.gsub(":#{token}", val)
|
256
286
|
end
|
257
|
-
|
287
|
+
|
288
|
+
padded = padout(formatted)
|
289
|
+
|
290
|
+
write(padded, true)
|
258
291
|
|
259
292
|
@last_render_time = Time.now
|
260
|
-
@last_render_width = formatted
|
293
|
+
@last_render_width = self.class.display_columns(formatted)
|
261
294
|
end
|
262
295
|
|
263
296
|
# Move cursor to a row of the current bar if the bar is rendered
|
@@ -420,15 +453,6 @@ module TTY
|
|
420
453
|
render
|
421
454
|
end
|
422
455
|
|
423
|
-
# Determine terminal width
|
424
|
-
#
|
425
|
-
# @return [Integer]
|
426
|
-
#
|
427
|
-
# @api public
|
428
|
-
def max_columns
|
429
|
-
TTY::Screen.width
|
430
|
-
end
|
431
|
-
|
432
456
|
# Show bar format
|
433
457
|
#
|
434
458
|
# @return [String]
|
@@ -461,8 +485,10 @@ module TTY
|
|
461
485
|
#
|
462
486
|
# @api private
|
463
487
|
def padout(message)
|
464
|
-
|
465
|
-
|
488
|
+
message_length = self.class.display_columns(message)
|
489
|
+
|
490
|
+
if @last_render_width > message_length
|
491
|
+
remaining_width = @last_render_width - message_length
|
466
492
|
message += ' ' * remaining_width
|
467
493
|
end
|
468
494
|
message
|
@@ -5,6 +5,7 @@ module TTY
|
|
5
5
|
attr_reader :total
|
6
6
|
|
7
7
|
attr_accessor :width
|
8
|
+
#attr_reader :width
|
8
9
|
|
9
10
|
attr_accessor :no_width
|
10
11
|
|
@@ -24,9 +25,11 @@ module TTY
|
|
24
25
|
|
25
26
|
attr_accessor :interval
|
26
27
|
|
28
|
+
attr_accessor :inset
|
29
|
+
|
27
30
|
def initialize(options)
|
28
31
|
self.total = options[:total] if options[:total]
|
29
|
-
@width
|
32
|
+
@width = options.fetch(:width) { total }
|
30
33
|
@no_width = options.fetch(:no_width) { false }
|
31
34
|
@incomplete = options.fetch(:incomplete) { ' ' }
|
32
35
|
@complete = options.fetch(:complete) { '=' }
|
@@ -36,12 +39,23 @@ module TTY
|
|
36
39
|
@output = options.fetch(:output) { $stderr }
|
37
40
|
@frequency = options.fetch(:frequency) { 0 } # 0Hz
|
38
41
|
@interval = options.fetch(:interval) { 1 } # 1 sec
|
42
|
+
@inset = options.fetch(:inset) { 0 }
|
39
43
|
end
|
40
44
|
|
45
|
+
# def width=(value)
|
46
|
+
# return if value.nil?
|
47
|
+
|
48
|
+
# if value < ProgressBar.max_columns
|
49
|
+
# @width = value
|
50
|
+
# else
|
51
|
+
# @width = ProgressBar.max_columns
|
52
|
+
# end
|
53
|
+
# end
|
54
|
+
|
41
55
|
def total=(value)
|
42
56
|
fail ArgumentError unless value
|
43
57
|
@total = value
|
44
|
-
|
58
|
+
self.width = value if width.nil?
|
45
59
|
end
|
46
60
|
end # Configuration
|
47
61
|
end # ProgressBar
|
@@ -30,12 +30,23 @@ module TTY
|
|
30
30
|
#
|
31
31
|
# @api public
|
32
32
|
def format(value)
|
33
|
-
|
33
|
+
without_bar = value.gsub(/:bar/, '')
|
34
|
+
available_space = [0, ProgressBar.max_columns -
|
35
|
+
ProgressBar.display_columns(without_bar) -
|
36
|
+
@progress.inset].max
|
34
37
|
width = [@progress.width, available_space].min
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
38
|
+
complete_bar_length = (width * @progress.ratio).round
|
39
|
+
complete_char_length = ProgressBar.display_columns(@progress.complete)
|
40
|
+
incomplete_char_length = ProgressBar.display_columns(@progress.incomplete)
|
41
|
+
|
42
|
+
# decimal number of items only when unicode chars are used
|
43
|
+
# otherwise it has no effect on regular ascii chars
|
44
|
+
complete_items = (complete_bar_length / complete_char_length.to_f).round
|
45
|
+
incomplete_items = (width - complete_items * complete_char_length) / incomplete_char_length
|
46
|
+
|
47
|
+
complete = Array.new(complete_items, @progress.complete)
|
48
|
+
incomplete = Array.new(incomplete_items, @progress.incomplete)
|
49
|
+
complete[-1] = @progress.head if complete_bar_length > 0
|
39
50
|
|
40
51
|
bar = ''
|
41
52
|
bar += complete.join
|
@@ -18,6 +18,8 @@ module TTY
|
|
18
18
|
|
19
19
|
def_delegators :@bars, :each, :empty?, :length, :[]
|
20
20
|
|
21
|
+
def_delegators :@top_bar, :width, :width=
|
22
|
+
|
21
23
|
DEFAULT_INSET = {
|
22
24
|
top: Gem.win_platform? ? '+ ' : "\u250c ",
|
23
25
|
middle: Gem.win_platform? ? '|-- ' : "\u251c\u2500\u2500 ",
|
@@ -51,6 +53,9 @@ module TTY
|
|
51
53
|
@top_bar = nil
|
52
54
|
@top_bar = register(format, observable: false) if format
|
53
55
|
|
56
|
+
@width = @options[:width]
|
57
|
+
@top_bar.update(width: @width) if @width
|
58
|
+
|
54
59
|
@callbacks = {
|
55
60
|
progress: [],
|
56
61
|
stopped: [],
|
@@ -73,7 +78,8 @@ module TTY
|
|
73
78
|
@bars << bar
|
74
79
|
observe(bar) if observable
|
75
80
|
if @top_bar
|
76
|
-
@top_bar.update(total: total
|
81
|
+
@top_bar.update(total: total)
|
82
|
+
@top_bar.update(width: total) unless @width
|
77
83
|
end
|
78
84
|
end
|
79
85
|
|
@@ -105,9 +111,9 @@ module TTY
|
|
105
111
|
#
|
106
112
|
# @api private
|
107
113
|
def progress_handler
|
108
|
-
|
109
|
-
@top_bar.advance if @top_bar
|
110
|
-
emit(:progress)
|
114
|
+
-> (progress) do
|
115
|
+
@top_bar.advance(progress) if @top_bar
|
116
|
+
emit(:progress, progress)
|
111
117
|
end
|
112
118
|
end
|
113
119
|
|
data/spec/spec_helper.rb
CHANGED
@@ -0,0 +1,28 @@
|
|
1
|
+
RSpec.describe TTY::ProgressBar::Multi, '#reset' do
|
2
|
+
let(:output) { StringIO.new('', 'w+') }
|
3
|
+
|
4
|
+
it "leaves multibar state alone" do
|
5
|
+
main = TTY::ProgressBar::Multi.new("", output: output, total: 10)
|
6
|
+
progress = main.register("[:bar]")
|
7
|
+
progress.advance(10)
|
8
|
+
expect(progress.complete?).to be(true)
|
9
|
+
progress.reset
|
10
|
+
expect(progress.complete?).to be(false)
|
11
|
+
progress.advance(10)
|
12
|
+
output.rewind
|
13
|
+
|
14
|
+
top = TTY::ProgressBar::Multi::DEFAULT_INSET[:top]
|
15
|
+
bottom = TTY::ProgressBar::Multi::DEFAULT_INSET[:bottom]
|
16
|
+
|
17
|
+
progress_updates =
|
18
|
+
output.read.scan(/#{Regexp.escape top}|#{Regexp.escape bottom}/)
|
19
|
+
expect(progress_updates.shift).to match(top)
|
20
|
+
expect(progress_updates.shift).to match(top)
|
21
|
+
expect(progress_updates.shift).to match(bottom)
|
22
|
+
expect(progress_updates.shift).to match(bottom)
|
23
|
+
expect(progress_updates.shift).to match(bottom)
|
24
|
+
expect(progress_updates.shift).to match(bottom)
|
25
|
+
|
26
|
+
expect(progress_updates).to be_empty
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
RSpec.describe TTY::ProgressBar::Multi, 'width' do
|
2
|
+
let(:output) { StringIO.new('', 'w+') }
|
3
|
+
let(:save) { TTY::Cursor.save }
|
4
|
+
let(:restore) { TTY::Cursor.restore }
|
5
|
+
let(:top) { TTY::ProgressBar::Multi::DEFAULT_INSET[:top] }
|
6
|
+
let(:middle) { TTY::ProgressBar::Multi::DEFAULT_INSET[:middle] }
|
7
|
+
let(:bottom) { TTY::ProgressBar::Multi::DEFAULT_INSET[:bottom] }
|
8
|
+
|
9
|
+
it "sets top level bar width to maximum columns when exceeds terminal width" do
|
10
|
+
allow(TTY::Screen).to receive(:width).and_return(15)
|
11
|
+
|
12
|
+
bars = TTY::ProgressBar::Multi.new("[:bar] main", output: output)
|
13
|
+
|
14
|
+
bar1 = bars.register("[:bar] one", total: 20)
|
15
|
+
bar2 = bars.register("[:bar] two", total: 20)
|
16
|
+
|
17
|
+
bar1.advance(10)
|
18
|
+
bar2.advance(10)
|
19
|
+
|
20
|
+
output.rewind
|
21
|
+
expect(output.read).to eq([
|
22
|
+
"\e[1G#{top}[== ] main\n",
|
23
|
+
"\e[1G#{bottom}[=== ] one\n",
|
24
|
+
save,
|
25
|
+
"\e[2A", # up 2 lines
|
26
|
+
"\e[1G#{top}[=== ] main",
|
27
|
+
restore,
|
28
|
+
"\e[1G#{bottom}[=== ] two\n"
|
29
|
+
].join)
|
30
|
+
|
31
|
+
bar1.advance(10)
|
32
|
+
|
33
|
+
output.rewind
|
34
|
+
expect(output.read).to eq([
|
35
|
+
"\e[1G#{top}[== ] main\n",
|
36
|
+
"\e[1G#{bottom}[=== ] one\n",
|
37
|
+
save,
|
38
|
+
"\e[2A", # up 2 lines
|
39
|
+
"\e[1G#{top}[=== ] main",
|
40
|
+
restore,
|
41
|
+
"\e[1G#{bottom}[=== ] two\n",
|
42
|
+
save,
|
43
|
+
"\e[3A", # up 3 lines
|
44
|
+
"\e[1G#{top}[===== ] main",
|
45
|
+
restore,
|
46
|
+
save,
|
47
|
+
"\e[2A", # up 2 lines
|
48
|
+
"\e[1G#{middle}[=====] one",
|
49
|
+
restore,
|
50
|
+
save,
|
51
|
+
"\e[2A", # up 2 lines
|
52
|
+
"#{middle}\n", # bar finished
|
53
|
+
restore
|
54
|
+
].join)
|
55
|
+
|
56
|
+
bar2.advance(10)
|
57
|
+
|
58
|
+
output.rewind
|
59
|
+
expect(output.read).to eq([
|
60
|
+
"\e[1G#{top}[== ] main\n",
|
61
|
+
"\e[1G#{bottom}[=== ] one\n",
|
62
|
+
save,
|
63
|
+
"\e[2A", # up 2 lines
|
64
|
+
"\e[1G#{top}[=== ] main",
|
65
|
+
restore,
|
66
|
+
"\e[1G#{bottom}[=== ] two\n",
|
67
|
+
save,
|
68
|
+
"\e[3A", # up 3 lines
|
69
|
+
"\e[1G#{top}[===== ] main",
|
70
|
+
restore,
|
71
|
+
save,
|
72
|
+
"\e[2A", # up 2 lines
|
73
|
+
"\e[1G#{middle}[=====] one",
|
74
|
+
restore,
|
75
|
+
save,
|
76
|
+
"\e[2A", # up 2 lines
|
77
|
+
"#{middle}\n", # bar finished
|
78
|
+
restore,
|
79
|
+
save,
|
80
|
+
"\e[3A", # up 3 lines
|
81
|
+
"\e[1G#{top}[======] main",
|
82
|
+
restore,
|
83
|
+
save,
|
84
|
+
"\e[3A", # up 1 line
|
85
|
+
"#{top}\n",
|
86
|
+
restore,
|
87
|
+
save,
|
88
|
+
"\e[1A", # up 1 line
|
89
|
+
"\e[1G#{bottom}[=====] two",
|
90
|
+
restore,
|
91
|
+
save,
|
92
|
+
"\e[1A", # up 1 line
|
93
|
+
"#{bottom}\n",
|
94
|
+
restore
|
95
|
+
].join)
|
96
|
+
end
|
97
|
+
|
98
|
+
it "sets top level bar width to a custom value" do
|
99
|
+
bars = TTY::ProgressBar::Multi.new("[:bar] main", output: output, width: 20)
|
100
|
+
|
101
|
+
bar1 = bars.register("[:bar] one", total: 20)
|
102
|
+
bar2 = bars.register("[:bar] two", total: 20)
|
103
|
+
|
104
|
+
bar1.advance(10)
|
105
|
+
bar2.advance(10)
|
106
|
+
|
107
|
+
output.rewind
|
108
|
+
expect(output.read).to eq([
|
109
|
+
"\e[1G#{top}[===== ] main\n",
|
110
|
+
"\e[1G#{bottom}[========== ] one\n",
|
111
|
+
save,
|
112
|
+
"\e[2A", # up 2 lines
|
113
|
+
"\e[1G#{top}[========== ] main",
|
114
|
+
restore,
|
115
|
+
"\e[1G#{bottom}[========== ] two\n"
|
116
|
+
].join)
|
117
|
+
end
|
118
|
+
end
|
data/spec/unit/new_spec.rb
CHANGED
@@ -7,6 +7,16 @@ RSpec.describe TTY::ProgressBar, '::new' do
|
|
7
7
|
}.to raise_error(ArgumentError, /Expected bar formatting string, got `{:output=>#{output}}` instead\./)
|
8
8
|
end
|
9
9
|
|
10
|
+
it "allows to change formatting string" do
|
11
|
+
bar = TTY::ProgressBar.new("[:bar]", output: output, total: 4)
|
12
|
+
bar.advance(2)
|
13
|
+
bar.format = "(:bar)"
|
14
|
+
bar.advance(2)
|
15
|
+
output.rewind
|
16
|
+
|
17
|
+
expect(output.read).to eq("\e[1G[== ]\e[1G(====)\n")
|
18
|
+
end
|
19
|
+
|
10
20
|
it "displays output where width == total" do
|
11
21
|
progress = TTY::ProgressBar.new("[:bar]", output: output, total: 10)
|
12
22
|
progress.advance
|
@@ -0,0 +1,25 @@
|
|
1
|
+
RSpec.describe TTY::ProgressBar, "#render" do
|
2
|
+
let(:output) { StringIO.new("", "w+") }
|
3
|
+
|
4
|
+
it "pads out longer previous lines" do
|
5
|
+
progress = TTY::ProgressBar.new ":current_byte" do |config|
|
6
|
+
config.no_width = true
|
7
|
+
config.output = output
|
8
|
+
config.total = 1_048_577
|
9
|
+
end
|
10
|
+
|
11
|
+
progress.advance(1)
|
12
|
+
progress.advance(1_048_574)
|
13
|
+
progress.advance(1)
|
14
|
+
progress.advance(1)
|
15
|
+
|
16
|
+
output.rewind
|
17
|
+
|
18
|
+
expect(output.read).to eq([
|
19
|
+
"\e[1G1B",
|
20
|
+
"\e[1G1024.00KB", # must not pad, line is longer
|
21
|
+
"\e[1G1.00MB ", # must pad out "0KB"
|
22
|
+
"\e[1G1.00MB", # must not pad, line is equal
|
23
|
+
].join)
|
24
|
+
end
|
25
|
+
end
|
data/spec/unit/resize_spec.rb
CHANGED
data/spec/unit/width_spec.rb
CHANGED
@@ -8,8 +8,10 @@ RSpec.describe TTY::ProgressBar, '#width' do
|
|
8
8
|
config.width = 1024
|
9
9
|
end
|
10
10
|
allow(TTY::Screen).to receive(:width).and_return(20)
|
11
|
+
|
11
12
|
5.times { progress.advance }
|
12
13
|
output.rewind
|
14
|
+
|
13
15
|
expect(output.read).to eq([
|
14
16
|
"\e[1G[==== ]",
|
15
17
|
"\e[1G[======= ]",
|
@@ -18,4 +20,67 @@ RSpec.describe TTY::ProgressBar, '#width' do
|
|
18
20
|
"\e[1G[==================]\n"
|
19
21
|
].join)
|
20
22
|
end
|
23
|
+
|
24
|
+
it "handles unicode characters width in formatting string" do
|
25
|
+
bar = TTY::ProgressBar.new("あめかんむり[:bar]", output: output, total: 20)
|
26
|
+
allow(TTY::Screen).to receive(:width).and_return(20)
|
27
|
+
|
28
|
+
4.times { bar.advance(5) }
|
29
|
+
output.rewind
|
30
|
+
|
31
|
+
expect(output.read).to eq([
|
32
|
+
"\e[1Gあめかんむり[== ]",
|
33
|
+
"\e[1Gあめかんむり[=== ]",
|
34
|
+
"\e[1Gあめかんむり[===== ]",
|
35
|
+
"\e[1Gあめかんむり[======]\n"
|
36
|
+
].join)
|
37
|
+
end
|
38
|
+
|
39
|
+
it "handles unicodes characters within bar" do
|
40
|
+
bar = TTY::ProgressBar.new("[:bar]", output: output, total: 20,
|
41
|
+
complete: 'あ', incomplete: 'め')
|
42
|
+
allow(TTY::Screen).to receive(:width).and_return(20)
|
43
|
+
|
44
|
+
4.times { bar.advance(5) }
|
45
|
+
output.rewind
|
46
|
+
|
47
|
+
expect(output.read).to eq([
|
48
|
+
"\e[1G[あああめめめめめめ]",
|
49
|
+
"\e[1G[あああああめめめめ]",
|
50
|
+
"\e[1G[あああああああめめ]",
|
51
|
+
"\e[1G[あああああああああ]\n"
|
52
|
+
].join)
|
53
|
+
end
|
54
|
+
|
55
|
+
it "handles unicodes characters within bar" do
|
56
|
+
bar = TTY::ProgressBar.new("[:bar]", output: output, total: 20,
|
57
|
+
complete: 'あ', incomplete: ' ')
|
58
|
+
allow(TTY::Screen).to receive(:width).and_return(20)
|
59
|
+
|
60
|
+
4.times { bar.advance(5) }
|
61
|
+
output.rewind
|
62
|
+
|
63
|
+
expect(output.read).to eq([
|
64
|
+
"\e[1G[あああ ]",
|
65
|
+
"\e[1G[あああああ ]",
|
66
|
+
"\e[1G[あああああああ ]",
|
67
|
+
"\e[1G[あああああああああ]\n"
|
68
|
+
].join)
|
69
|
+
end
|
70
|
+
|
71
|
+
it "handles unicodes characters within bar" do
|
72
|
+
bar = TTY::ProgressBar.new("[:bar]", output: output, total: 20,
|
73
|
+
complete: 'x', incomplete: 'め')
|
74
|
+
allow(TTY::Screen).to receive(:width).and_return(20)
|
75
|
+
|
76
|
+
4.times { bar.advance(5) }
|
77
|
+
output.rewind
|
78
|
+
|
79
|
+
expect(output.read).to eq([
|
80
|
+
"\e[1G[xxxxxめめめめめめ]",
|
81
|
+
"\e[1G[xxxxxxxxxめめめめ]",
|
82
|
+
"\e[1G[xxxxxxxxxxxxxxめめ]",
|
83
|
+
"\e[1G[xxxxxxxxxxxxxxxxxx]\n"
|
84
|
+
].join)
|
85
|
+
end
|
21
86
|
end
|
data/tty-progressbar.gemspec
CHANGED
@@ -20,8 +20,9 @@ Gem::Specification.new do |spec|
|
|
20
20
|
|
21
21
|
spec.required_ruby_version = '>= 2.0.0'
|
22
22
|
|
23
|
-
spec.add_dependency
|
24
|
-
spec.add_dependency
|
23
|
+
spec.add_dependency 'tty-cursor', '~> 0.5.0'
|
24
|
+
spec.add_dependency 'tty-screen', '~> 0.6.4'
|
25
|
+
spec.add_dependency 'unicode-display_width', '~> 1.3'
|
25
26
|
|
26
27
|
spec.add_development_dependency 'bundler', '>= 1.5.0', '< 2.0'
|
27
28
|
spec.add_development_dependency 'rspec', '~> 3.1'
|
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
|
+
version: 0.15.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: 2018-
|
11
|
+
date: 2018-06-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: tty-cursor
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: 0.6.4
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: unicode-display_width
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.3'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.3'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: bundler
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -124,11 +138,13 @@ files:
|
|
124
138
|
- examples/lazy.rb
|
125
139
|
- examples/multi/main_bar.rb
|
126
140
|
- examples/multi/simple.rb
|
141
|
+
- examples/multi/width.rb
|
127
142
|
- examples/simple.rb
|
128
143
|
- examples/slow_process.rb
|
129
144
|
- examples/speed.rb
|
130
145
|
- examples/threaded.rb
|
131
146
|
- examples/tokens.rb
|
147
|
+
- examples/unicode.rb
|
132
148
|
- lib/tty-progressbar.rb
|
133
149
|
- lib/tty/progressbar.rb
|
134
150
|
- lib/tty/progressbar/configuration.rb
|
@@ -185,10 +201,13 @@ files:
|
|
185
201
|
- spec/unit/multi/finish_spec.rb
|
186
202
|
- spec/unit/multi/line_inset_spec.rb
|
187
203
|
- spec/unit/multi/register_spec.rb
|
204
|
+
- spec/unit/multi/reset_spec.rb
|
188
205
|
- spec/unit/multi/stop_spec.rb
|
206
|
+
- spec/unit/multi/width_spec.rb
|
189
207
|
- spec/unit/new_spec.rb
|
190
208
|
- spec/unit/pipeline_spec.rb
|
191
209
|
- spec/unit/ratio_spec.rb
|
210
|
+
- spec/unit/render_spec.rb
|
192
211
|
- spec/unit/reset_spec.rb
|
193
212
|
- spec/unit/resize_spec.rb
|
194
213
|
- spec/unit/set_current_spec.rb
|
@@ -260,10 +279,13 @@ test_files:
|
|
260
279
|
- spec/unit/multi/finish_spec.rb
|
261
280
|
- spec/unit/multi/line_inset_spec.rb
|
262
281
|
- spec/unit/multi/register_spec.rb
|
282
|
+
- spec/unit/multi/reset_spec.rb
|
263
283
|
- spec/unit/multi/stop_spec.rb
|
284
|
+
- spec/unit/multi/width_spec.rb
|
264
285
|
- spec/unit/new_spec.rb
|
265
286
|
- spec/unit/pipeline_spec.rb
|
266
287
|
- spec/unit/ratio_spec.rb
|
288
|
+
- spec/unit/render_spec.rb
|
267
289
|
- spec/unit/reset_spec.rb
|
268
290
|
- spec/unit/resize_spec.rb
|
269
291
|
- spec/unit/set_current_spec.rb
|