tty-progressbar 0.11.0 → 0.12.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +20 -0
- data/README.md +302 -57
- data/examples/failure.rb +14 -0
- data/examples/iterator.rb +7 -0
- data/examples/multi/main_bar.rb +17 -0
- data/examples/multi/simple.rb +15 -0
- data/examples/threaded.rb +16 -0
- data/lib/tty-progressbar.rb +3 -2
- data/lib/tty/progressbar.rb +221 -58
- data/lib/tty/progressbar/configuration.rb +4 -0
- data/lib/tty/progressbar/converter.rb +2 -1
- data/lib/tty/progressbar/formatter.rb +2 -1
- data/lib/tty/progressbar/formatter/bar.rb +3 -1
- data/lib/tty/progressbar/formatter/byte_rate.rb +2 -1
- data/lib/tty/progressbar/formatter/current.rb +2 -1
- data/lib/tty/progressbar/formatter/current_byte.rb +2 -1
- data/lib/tty/progressbar/formatter/elapsed.rb +2 -1
- data/lib/tty/progressbar/formatter/estimated.rb +2 -1
- data/lib/tty/progressbar/formatter/mean_byte.rb +2 -1
- data/lib/tty/progressbar/formatter/mean_rate.rb +2 -1
- data/lib/tty/progressbar/formatter/percent.rb +2 -1
- data/lib/tty/progressbar/formatter/rate.rb +2 -1
- data/lib/tty/progressbar/formatter/total.rb +2 -1
- data/lib/tty/progressbar/formatter/total_byte.rb +2 -1
- data/lib/tty/progressbar/meter.rb +2 -1
- data/lib/tty/progressbar/multi.rb +221 -0
- data/lib/tty/progressbar/version.rb +1 -1
- data/spec/unit/events_spec.rb +35 -0
- data/spec/unit/formatter/elapsed_spec.rb +0 -1
- data/spec/unit/head_spec.rb +34 -0
- data/spec/unit/inspect_spec.rb +1 -1
- data/spec/unit/iterate_spec.rb +48 -0
- data/spec/unit/multi/advance_spec.rb +139 -0
- data/spec/unit/multi/events_spec.rb +64 -0
- data/spec/unit/multi/finish_spec.rb +19 -0
- data/spec/unit/multi/line_inset_spec.rb +67 -0
- data/spec/unit/multi/register_spec.rb +36 -0
- data/spec/unit/multi/stop_spec.rb +17 -0
- data/spec/unit/new_spec.rb +6 -0
- data/spec/unit/reset_spec.rb +0 -2
- data/spec/unit/stop_spec.rb +21 -0
- data/spec/unit/update_spec.rb +24 -0
- data/tty-progressbar.gemspec +1 -0
- metadata +44 -2
data/spec/unit/inspect_spec.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
RSpec.describe TTY::ProgressBar, '#inspect' do
|
4
4
|
it "inspects bar properties" do
|
5
5
|
bar = described_class.new("downloading [:bar] :total", total: 30)
|
6
|
-
expect(bar.inspect).to eq(%q{#<TTY::ProgressBar @format="downloading [:bar] :total", @current="0", @total="30", @width="30", @complete="=", @incomplete=" ", @interval="">})
|
6
|
+
expect(bar.inspect).to eq(%q{#<TTY::ProgressBar @format="downloading [:bar] :total", @current="0", @total="30", @width="30", @complete="=", @head="=", @incomplete=" ", @interval="1">})
|
7
7
|
end
|
8
8
|
|
9
9
|
it "prints string format" do
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
RSpec.describe TTY::ProgressBar, '#iterate' do
|
4
|
+
let(:output) { StringIO.new('', 'w+') }
|
5
|
+
|
6
|
+
it "iterates over a collection and yields" do
|
7
|
+
bar = TTY::ProgressBar.new("[:bar]", output: output)
|
8
|
+
values = []
|
9
|
+
bar.iterate(5.times) { |val| values << val}
|
10
|
+
|
11
|
+
expect(bar.complete?).to eq(true)
|
12
|
+
output.rewind
|
13
|
+
expect(output.read).to eq([
|
14
|
+
"\e[1G[= ]",
|
15
|
+
"\e[1G[== ]",
|
16
|
+
"\e[1G[=== ]",
|
17
|
+
"\e[1G[==== ]",
|
18
|
+
"\e[1G[=====]\n"
|
19
|
+
].join)
|
20
|
+
expect(values).to eq([0, 1, 2, 3, 4])
|
21
|
+
end
|
22
|
+
|
23
|
+
it "iterates over a collection with a step" do
|
24
|
+
bar = TTY::ProgressBar.new("[:bar]", output: output)
|
25
|
+
bar.iterate(20.times, 5) { }
|
26
|
+
|
27
|
+
expect(bar.complete?).to eq(true)
|
28
|
+
output.rewind
|
29
|
+
expect(output.read).to eq([
|
30
|
+
"\e[1G[===== ]",
|
31
|
+
"\e[1G[========== ]",
|
32
|
+
"\e[1G[=============== ]",
|
33
|
+
"\e[1G[====================]\n"
|
34
|
+
].join)
|
35
|
+
end
|
36
|
+
|
37
|
+
it "iterates over a collection and returns enumerable" do
|
38
|
+
bar = TTY::ProgressBar.new("[:bar]", output: output)
|
39
|
+
values = []
|
40
|
+
progress = bar.iterate(5.times)
|
41
|
+
|
42
|
+
expect(bar.complete?).to eq(false)
|
43
|
+
|
44
|
+
progress.each { |v| values << v }
|
45
|
+
|
46
|
+
expect(values).to eq([0,1,2,3,4])
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,139 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
RSpec.describe TTY::ProgressBar::Multi, 'advance' do
|
4
|
+
let(:output) { StringIO.new('', 'w+') }
|
5
|
+
let(:save) { TTY::Cursor.save }
|
6
|
+
let(:restore) { TTY::Cursor.restore }
|
7
|
+
let(:top) { TTY::ProgressBar::Multi::DEFAULT_INSET[:top] }
|
8
|
+
let(:middle) { TTY::ProgressBar::Multi::DEFAULT_INSET[:middle] }
|
9
|
+
let(:bottom) { TTY::ProgressBar::Multi::DEFAULT_INSET[:bottom] }
|
10
|
+
|
11
|
+
it "advances progress bars correctly under multibar" do
|
12
|
+
bars = TTY::ProgressBar::Multi.new(output: output)
|
13
|
+
|
14
|
+
bar1 = bars.register("[:bar] one", total: 5)
|
15
|
+
bar2 = bars.register("[:bar] two", total: 5)
|
16
|
+
|
17
|
+
bar2.advance
|
18
|
+
bar1.advance
|
19
|
+
|
20
|
+
output.rewind
|
21
|
+
expect(output.read).to eq([
|
22
|
+
"\e[1G[= ] two\n",
|
23
|
+
"\e[1G[= ] one\n"
|
24
|
+
].join)
|
25
|
+
|
26
|
+
bar2.advance
|
27
|
+
|
28
|
+
output.rewind
|
29
|
+
expect(output.read).to eq([
|
30
|
+
"\e[1G[= ] two\n",
|
31
|
+
"\e[1G[= ] one\n",
|
32
|
+
save,
|
33
|
+
"\e[2A", # up 2 lines
|
34
|
+
"\e[1G[== ] two",
|
35
|
+
restore
|
36
|
+
].join)
|
37
|
+
|
38
|
+
bar1.advance
|
39
|
+
|
40
|
+
output.rewind
|
41
|
+
expect(output.read).to eq([
|
42
|
+
"\e[1G[= ] two\n",
|
43
|
+
"\e[1G[= ] one\n",
|
44
|
+
save,
|
45
|
+
"\e[2A", # up 2 lines
|
46
|
+
"\e[1G[== ] two",
|
47
|
+
restore,
|
48
|
+
save,
|
49
|
+
"\e[1A", # up 1 line
|
50
|
+
"\e[1G[== ] one",
|
51
|
+
restore
|
52
|
+
].join)
|
53
|
+
end
|
54
|
+
|
55
|
+
it "advances progress bars correctly under top level multibar" do
|
56
|
+
bars = TTY::ProgressBar::Multi.new("[:bar] main", output: output)
|
57
|
+
|
58
|
+
bar1 = bars.register("[:bar] one", total: 5)
|
59
|
+
bar2 = bars.register("[:bar] two", total: 5)
|
60
|
+
|
61
|
+
bars.start
|
62
|
+
|
63
|
+
bar2.advance
|
64
|
+
bar1.advance
|
65
|
+
|
66
|
+
output.rewind
|
67
|
+
expect(output.read).to eq([
|
68
|
+
"\e[1G#{top}[ ] main\n",
|
69
|
+
"\e[1G#{bottom}[= ] two\n",
|
70
|
+
save,
|
71
|
+
"\e[2A", # up 2 lines
|
72
|
+
"\e[1G#{top}[= ] main",
|
73
|
+
restore,
|
74
|
+
"\e[1G#{bottom}[= ] one\n",
|
75
|
+
save,
|
76
|
+
"\e[3A", # up 3 lines
|
77
|
+
"\e[1G#{top}[== ] main",
|
78
|
+
restore
|
79
|
+
].join)
|
80
|
+
|
81
|
+
bar2.advance
|
82
|
+
|
83
|
+
output.rewind
|
84
|
+
expect(output.read).to eq([
|
85
|
+
"\e[1G#{top}[ ] main\n",
|
86
|
+
"\e[1G#{bottom}[= ] two\n",
|
87
|
+
save,
|
88
|
+
"\e[2A", # up 2 lines
|
89
|
+
"\e[1G#{top}[= ] main",
|
90
|
+
restore,
|
91
|
+
"\e[1G#{bottom}[= ] one\n",
|
92
|
+
save,
|
93
|
+
"\e[3A", # up 3 lines
|
94
|
+
"\e[1G#{top}[== ] main",
|
95
|
+
restore,
|
96
|
+
save,
|
97
|
+
"\e[2A", # up 2 lines,
|
98
|
+
"\e[1G#{middle}[== ] two",
|
99
|
+
restore,
|
100
|
+
save,
|
101
|
+
"\e[3A", # up 3 lines
|
102
|
+
"\e[1G#{top}[=== ] main",
|
103
|
+
restore
|
104
|
+
].join)
|
105
|
+
|
106
|
+
bar1.advance
|
107
|
+
|
108
|
+
output.rewind
|
109
|
+
expect(output.read).to eq([
|
110
|
+
"\e[1G#{top}[ ] main\n",
|
111
|
+
"\e[1G#{bottom}[= ] two\n",
|
112
|
+
save,
|
113
|
+
"\e[2A", # up 2 lines
|
114
|
+
"\e[1G#{top}[= ] main",
|
115
|
+
restore,
|
116
|
+
"\e[1G#{bottom}[= ] one\n",
|
117
|
+
save,
|
118
|
+
"\e[3A", # up 3 lines
|
119
|
+
"\e[1G#{top}[== ] main",
|
120
|
+
restore,
|
121
|
+
save,
|
122
|
+
"\e[2A", # up 2 lines,
|
123
|
+
"\e[1G#{middle}[== ] two",
|
124
|
+
restore,
|
125
|
+
save,
|
126
|
+
"\e[3A", # up 3 lines
|
127
|
+
"\e[1G#{top}[=== ] main",
|
128
|
+
restore,
|
129
|
+
save,
|
130
|
+
"\e[1A", # up 1 line
|
131
|
+
"\e[1G#{bottom}[== ] one",
|
132
|
+
restore,
|
133
|
+
save,
|
134
|
+
"\e[3A", # up 3 lines
|
135
|
+
"\e[1G#{top}[==== ] main",
|
136
|
+
restore
|
137
|
+
].join)
|
138
|
+
end
|
139
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
RSpec.describe TTY::ProgressBar::Multi, 'events' do
|
4
|
+
let(:output) { StringIO.new('', 'w+') }
|
5
|
+
|
6
|
+
it "emits :progress eent when any of the registerd bars advances" do
|
7
|
+
events = []
|
8
|
+
bars = TTY::ProgressBar::Multi.new("[:bar]", output: output, total: 5)
|
9
|
+
bars.on(:progress) { events << :progress }
|
10
|
+
|
11
|
+
bar = bars.register "one [:bar]"
|
12
|
+
bar.advance
|
13
|
+
|
14
|
+
expect(events).to eq([:progress])
|
15
|
+
end
|
16
|
+
|
17
|
+
it "emits :done event when all progress bars finished" do
|
18
|
+
events = []
|
19
|
+
bars = TTY::ProgressBar::Multi.new("[:bar]", output: output, total: 5)
|
20
|
+
bars.on(:done) { events << :done }
|
21
|
+
|
22
|
+
bar = bars.register "one [:bar]"
|
23
|
+
|
24
|
+
bar.finish
|
25
|
+
|
26
|
+
expect(events).to eq([:done])
|
27
|
+
end
|
28
|
+
|
29
|
+
it "emits :done event when top level bar finished" do
|
30
|
+
events = []
|
31
|
+
bars = TTY::ProgressBar::Multi.new("[:bar]", output: output, total: 5)
|
32
|
+
bars.on(:done) { events << :done }
|
33
|
+
|
34
|
+
bars.register "one [:bar]"
|
35
|
+
|
36
|
+
bars.finish
|
37
|
+
|
38
|
+
expect(events).to eq([:done])
|
39
|
+
end
|
40
|
+
|
41
|
+
it "emits :stopped event when all registerd bars are stopped" do
|
42
|
+
events = []
|
43
|
+
bars = TTY::ProgressBar::Multi.new("[:bar]", output: output, total: 5)
|
44
|
+
bars.on(:stopped) { events << :stopped }
|
45
|
+
|
46
|
+
bar = bars.register "one [:bar]"
|
47
|
+
|
48
|
+
bar.stop
|
49
|
+
|
50
|
+
expect(events).to eq([:stopped])
|
51
|
+
end
|
52
|
+
|
53
|
+
it "emits :stopped event when top level bar finished" do
|
54
|
+
events = []
|
55
|
+
bars = TTY::ProgressBar::Multi.new("[:bar]", output: output, total: 5)
|
56
|
+
bars.on(:stopped) { events << :stopped }
|
57
|
+
|
58
|
+
bars.register "one [:bar]"
|
59
|
+
|
60
|
+
bars.stop
|
61
|
+
|
62
|
+
expect(events).to eq([:stopped])
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
RSpec.describe TTY::ProgressBar::Multi, '#finish' do
|
4
|
+
let(:output) { StringIO.new('', 'w+') }
|
5
|
+
|
6
|
+
it "finishes all bars" do
|
7
|
+
bars = TTY::ProgressBar::Multi.new("main [:bar]", output: output)
|
8
|
+
|
9
|
+
bar1 = bars.register("[:bar]", total: 5)
|
10
|
+
bar2 = bars.register("[:bar]", total: 10)
|
11
|
+
|
12
|
+
expect(bars.complete?).to eq(false)
|
13
|
+
|
14
|
+
bar1.finish
|
15
|
+
bar2.finish
|
16
|
+
|
17
|
+
expect(bars.complete?).to eq(true)
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
RSpec.describe TTY::ProgressBar::Multi, '#line_inset' do
|
4
|
+
let(:output) { StringIO.new('', 'w+') }
|
5
|
+
|
6
|
+
it "doesn't create inset when no top level bar" do
|
7
|
+
bars = TTY::ProgressBar::Multi.new(output: output)
|
8
|
+
|
9
|
+
bar = bars.register 'example'
|
10
|
+
|
11
|
+
expect(bars.line_inset(bar)).to eq('')
|
12
|
+
end
|
13
|
+
|
14
|
+
it "defaults to the empty string for the top level bar" do
|
15
|
+
bars = TTY::ProgressBar::Multi.new("Top level spinner", output: output)
|
16
|
+
|
17
|
+
expect(bars.line_inset(bars.top_bar))
|
18
|
+
.to eq(TTY::ProgressBar::Multi::DEFAULT_INSET[:top])
|
19
|
+
end
|
20
|
+
|
21
|
+
it "returns middle character for a top level bar" do
|
22
|
+
bars = TTY::ProgressBar::Multi.new("Top level bar", output: output)
|
23
|
+
|
24
|
+
bar = bars.register 'middle', total: 10
|
25
|
+
bar2 = bars.register 'bottom', total: 10
|
26
|
+
|
27
|
+
bar.start
|
28
|
+
bar2.start
|
29
|
+
|
30
|
+
expect(bars.line_inset(bar))
|
31
|
+
.to eq(TTY::ProgressBar::Multi::DEFAULT_INSET[:middle])
|
32
|
+
end
|
33
|
+
|
34
|
+
it "decorates last bar" do
|
35
|
+
bars = TTY::ProgressBar::Multi.new("Top spinner", output: output)
|
36
|
+
|
37
|
+
bar1 = bars.register 'middle', total: 10
|
38
|
+
bar = bars.register 'bottom', total: 10
|
39
|
+
|
40
|
+
bar1.start
|
41
|
+
bar.start
|
42
|
+
|
43
|
+
expect(bars.line_inset(bar))
|
44
|
+
.to eq(TTY::ProgressBar::Multi::DEFAULT_INSET[:bottom])
|
45
|
+
end
|
46
|
+
|
47
|
+
it "allows customization" do
|
48
|
+
opts = {
|
49
|
+
output: output,
|
50
|
+
style: {
|
51
|
+
top: ". ",
|
52
|
+
middle: "--",
|
53
|
+
bottom: "---",
|
54
|
+
}
|
55
|
+
}
|
56
|
+
bars = TTY::ProgressBar::Multi.new("Top level spinner", opts)
|
57
|
+
middle_bar = bars.register "", total: 10
|
58
|
+
bottom_bar = bars.register "", total: 10
|
59
|
+
|
60
|
+
middle_bar.start
|
61
|
+
bottom_bar.start
|
62
|
+
|
63
|
+
expect(bars.line_inset(bars.top_bar)).to eq(". ")
|
64
|
+
expect(bars.line_inset(middle_bar)).to eq("--")
|
65
|
+
expect(bars.line_inset(bottom_bar)).to eq("---")
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
RSpec.describe TTY::ProgressBar::Multi, '#register' do
|
4
|
+
let(:output) { StringIO.new('', 'w+') }
|
5
|
+
|
6
|
+
it "registers a TTY::ProgressBar instance" do
|
7
|
+
bars = TTY::ProgressBar::Multi.new(output: output)
|
8
|
+
allow_any_instance_of(TTY::ProgressBar).to receive(:attach_to)
|
9
|
+
expect_any_instance_of(TTY::ProgressBar).to receive(:attach_to)
|
10
|
+
|
11
|
+
bar = bars.register("[:bar]")
|
12
|
+
|
13
|
+
expect(bar).to be_instance_of(TTY::ProgressBar)
|
14
|
+
expect(bars.length).to eq(1)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "uses global options to register instance" do
|
18
|
+
bars = TTY::ProgressBar::Multi.new(output: output, total: 100)
|
19
|
+
bar = double(:bar, attach_to: nil)
|
20
|
+
allow(TTY::ProgressBar).to receive(:new).and_return(bar)
|
21
|
+
|
22
|
+
bars.register("[:bar]")
|
23
|
+
|
24
|
+
expect(TTY::ProgressBar).to have_received(:new).with("[:bar]", {total: 100, output: output})
|
25
|
+
end
|
26
|
+
|
27
|
+
it "registers bars with top level" do
|
28
|
+
bars = TTY::ProgressBar::Multi.new("main [:bar]", output: output)
|
29
|
+
|
30
|
+
bars.register("[:bar]", total: 5)
|
31
|
+
bars.register("[:bar]", total: 10)
|
32
|
+
|
33
|
+
expect(bars.total).to eq(15)
|
34
|
+
expect(bars.current).to eq(0)
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
RSpec.describe TTY::ProgressBar::Multi, '#stop' do
|
4
|
+
let(:output) { StringIO.new('', 'w+') }
|
5
|
+
|
6
|
+
it "stops all bars when top level stops" do
|
7
|
+
bars = TTY::ProgressBar::Multi.new("main [:bar]", output: output)
|
8
|
+
|
9
|
+
bar1 = bars.register("[:bar]", total: 5)
|
10
|
+
bar2 = bars.register("[:bar]", total: 10)
|
11
|
+
|
12
|
+
bars.stop
|
13
|
+
|
14
|
+
expect(bar1.stopped?).to eq(true)
|
15
|
+
expect(bar2.stopped?).to eq(true)
|
16
|
+
end
|
17
|
+
end
|
data/spec/unit/new_spec.rb
CHANGED
@@ -3,6 +3,12 @@
|
|
3
3
|
RSpec.describe TTY::ProgressBar, '::new' do
|
4
4
|
let(:output) { StringIO.new('', 'w+') }
|
5
5
|
|
6
|
+
it "fails to initialize without formatting string" do
|
7
|
+
expect {
|
8
|
+
TTY::ProgressBar.new(output: output)
|
9
|
+
}.to raise_error(ArgumentError, /Expected bar formatting string, got `{:output=>#{output}}` instead\./)
|
10
|
+
end
|
11
|
+
|
6
12
|
it "displays output where width == total" do
|
7
13
|
progress = TTY::ProgressBar.new("[:bar]", output: output, total: 10)
|
8
14
|
progress.advance
|
data/spec/unit/reset_spec.rb
CHANGED
@@ -11,7 +11,6 @@ RSpec.describe TTY::ProgressBar, '#reset' do
|
|
11
11
|
output.rewind
|
12
12
|
expect(output.read).to eq([
|
13
13
|
"\e[1G[===== ]",
|
14
|
-
"\e[1G[ ]",
|
15
14
|
"\e[1G[=== ]",
|
16
15
|
"\e[1G[====== ]"
|
17
16
|
].join)
|
@@ -27,7 +26,6 @@ RSpec.describe TTY::ProgressBar, '#reset' do
|
|
27
26
|
output.rewind
|
28
27
|
expect(output.read).to eq([
|
29
28
|
"\e[1G[==========]\n",
|
30
|
-
"\e[1G[ ]",
|
31
29
|
"\e[1G[=== ]",
|
32
30
|
"\e[1G[====== ]"
|
33
31
|
].join)
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
RSpec.describe TTY::ProgressBar, '#stop' do
|
4
|
+
let(:output) { StringIO.new('', 'w+') }
|
5
|
+
|
6
|
+
it 'stops progress' do
|
7
|
+
progress = TTY::ProgressBar.new("[:bar]", output: output, total: 10)
|
8
|
+
5.times { |i|
|
9
|
+
progress.stop if i == 3
|
10
|
+
progress.advance
|
11
|
+
}
|
12
|
+
expect(progress.complete?).to be(false)
|
13
|
+
output.rewind
|
14
|
+
expect(output.read).to eq([
|
15
|
+
"\e[1G[= ]",
|
16
|
+
"\e[1G[== ]",
|
17
|
+
"\e[1G[=== ]",
|
18
|
+
"\e[1G[=== ]\n"
|
19
|
+
].join)
|
20
|
+
end
|
21
|
+
end
|