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.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +20 -0
  3. data/README.md +302 -57
  4. data/examples/failure.rb +14 -0
  5. data/examples/iterator.rb +7 -0
  6. data/examples/multi/main_bar.rb +17 -0
  7. data/examples/multi/simple.rb +15 -0
  8. data/examples/threaded.rb +16 -0
  9. data/lib/tty-progressbar.rb +3 -2
  10. data/lib/tty/progressbar.rb +221 -58
  11. data/lib/tty/progressbar/configuration.rb +4 -0
  12. data/lib/tty/progressbar/converter.rb +2 -1
  13. data/lib/tty/progressbar/formatter.rb +2 -1
  14. data/lib/tty/progressbar/formatter/bar.rb +3 -1
  15. data/lib/tty/progressbar/formatter/byte_rate.rb +2 -1
  16. data/lib/tty/progressbar/formatter/current.rb +2 -1
  17. data/lib/tty/progressbar/formatter/current_byte.rb +2 -1
  18. data/lib/tty/progressbar/formatter/elapsed.rb +2 -1
  19. data/lib/tty/progressbar/formatter/estimated.rb +2 -1
  20. data/lib/tty/progressbar/formatter/mean_byte.rb +2 -1
  21. data/lib/tty/progressbar/formatter/mean_rate.rb +2 -1
  22. data/lib/tty/progressbar/formatter/percent.rb +2 -1
  23. data/lib/tty/progressbar/formatter/rate.rb +2 -1
  24. data/lib/tty/progressbar/formatter/total.rb +2 -1
  25. data/lib/tty/progressbar/formatter/total_byte.rb +2 -1
  26. data/lib/tty/progressbar/meter.rb +2 -1
  27. data/lib/tty/progressbar/multi.rb +221 -0
  28. data/lib/tty/progressbar/version.rb +1 -1
  29. data/spec/unit/events_spec.rb +35 -0
  30. data/spec/unit/formatter/elapsed_spec.rb +0 -1
  31. data/spec/unit/head_spec.rb +34 -0
  32. data/spec/unit/inspect_spec.rb +1 -1
  33. data/spec/unit/iterate_spec.rb +48 -0
  34. data/spec/unit/multi/advance_spec.rb +139 -0
  35. data/spec/unit/multi/events_spec.rb +64 -0
  36. data/spec/unit/multi/finish_spec.rb +19 -0
  37. data/spec/unit/multi/line_inset_spec.rb +67 -0
  38. data/spec/unit/multi/register_spec.rb +36 -0
  39. data/spec/unit/multi/stop_spec.rb +17 -0
  40. data/spec/unit/new_spec.rb +6 -0
  41. data/spec/unit/reset_spec.rb +0 -2
  42. data/spec/unit/stop_spec.rb +21 -0
  43. data/spec/unit/update_spec.rb +24 -0
  44. data/tty-progressbar.gemspec +1 -0
  45. metadata +44 -2
@@ -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
@@ -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
@@ -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