tty-spinner 0.8.0 → 0.9.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 +5 -5
- data/CHANGELOG.md +120 -0
- data/README.md +28 -10
- data/Rakefile +8 -0
- data/examples/auto_spin.rb +8 -0
- data/examples/basic.rb +8 -0
- data/examples/clear.rb +9 -0
- data/examples/color.rb +12 -0
- data/examples/error.rb +9 -0
- data/examples/formats.rb +11 -0
- data/examples/hide_cursor.rb +12 -0
- data/examples/multi/basic.rb +13 -0
- data/examples/multi/basic_top_level.rb +13 -0
- data/examples/multi/custom_style.rb +26 -0
- data/examples/multi/files.rb +14 -0
- data/examples/multi/jobs.rb +10 -0
- data/examples/multi/multi.rb +17 -0
- data/examples/multi/multi_top_level.rb +18 -0
- data/examples/multi/pause.rb +26 -0
- data/examples/multi/threaded.rb +30 -0
- data/examples/pause.rb +19 -0
- data/examples/run.rb +18 -0
- data/examples/success.rb +9 -0
- data/examples/threaded.rb +11 -0
- data/examples/update.rb +11 -0
- data/lib/tty-spinner.rb +0 -2
- data/lib/tty/spinner.rb +40 -30
- data/lib/tty/spinner/formats.rb +3 -3
- data/lib/tty/spinner/multi.rb +31 -12
- data/lib/tty/spinner/version.rb +2 -2
- data/spec/spec_helper.rb +51 -0
- data/spec/unit/auto_spin_spec.rb +27 -0
- data/spec/unit/clear_spec.rb +18 -0
- data/spec/unit/error_spec.rb +46 -0
- data/spec/unit/events_spec.rb +37 -0
- data/spec/unit/formats_spec.rb +9 -0
- data/spec/unit/frames_spec.rb +33 -0
- data/spec/unit/hide_cursor_spec.rb +53 -0
- data/spec/unit/job_spec.rb +14 -0
- data/spec/unit/join_spec.rb +12 -0
- data/spec/unit/multi/auto_spin_spec.rb +34 -0
- data/spec/unit/multi/error_spec.rb +109 -0
- data/spec/unit/multi/line_inset_spec.rb +59 -0
- data/spec/unit/multi/on_spec.rb +13 -0
- data/spec/unit/multi/register_spec.rb +47 -0
- data/spec/unit/multi/spin_spec.rb +103 -0
- data/spec/unit/multi/stop_spec.rb +97 -0
- data/spec/unit/multi/success_spec.rb +110 -0
- data/spec/unit/new_spec.rb +26 -0
- data/spec/unit/pause_spec.rb +25 -0
- data/spec/unit/reset_spec.rb +21 -0
- data/spec/unit/run_spec.rb +32 -0
- data/spec/unit/spin_spec.rb +90 -0
- data/spec/unit/stop_spec.rb +64 -0
- data/spec/unit/success_spec.rb +46 -0
- data/spec/unit/update_spec.rb +87 -0
- data/tasks/console.rake +11 -0
- data/tasks/coverage.rake +11 -0
- data/tasks/spec.rake +29 -0
- data/tty-spinner.gemspec +27 -0
- metadata +62 -9
@@ -0,0 +1,13 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
RSpec.describe TTY::Spinner::Multi, '#on' do
|
4
|
+
let(:output) { StringIO.new('', 'w+') }
|
5
|
+
|
6
|
+
it 'fails to register a callback with invalid event name' do
|
7
|
+
spinners = TTY::Spinner::Multi.new(output: output)
|
8
|
+
|
9
|
+
expect {
|
10
|
+
spinners.on(:unknown_event) { }
|
11
|
+
}.to raise_error(ArgumentError, /The event unknown_event does not exist/)
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
RSpec.describe TTY::Spinner::Multi, '#register' do
|
4
|
+
let(:output) { StringIO.new('', 'w+') }
|
5
|
+
|
6
|
+
it "registers a TTY::Spinner instance from a pattern" do
|
7
|
+
spinners = TTY::Spinner::Multi.new(output: output, interval: 100)
|
8
|
+
allow_any_instance_of(TTY::Spinner).to receive(:attach_to)
|
9
|
+
expect_any_instance_of(TTY::Spinner).to receive(:attach_to)
|
10
|
+
|
11
|
+
spinner = spinners.register ""
|
12
|
+
|
13
|
+
expect(spinner).to be_instance_of(TTY::Spinner)
|
14
|
+
expect(spinners.length).to eq(1)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "registers a TTY::Spinner instance from a spinner instance" do
|
18
|
+
spinners = TTY::Spinner::Multi.new(output: output, interval: 100)
|
19
|
+
spinner_to_register = ::TTY::Spinner.new
|
20
|
+
|
21
|
+
spinner = spinners.register spinner_to_register
|
22
|
+
|
23
|
+
expect(spinner).to eq(spinner_to_register)
|
24
|
+
expect(spinners.length).to eq(1)
|
25
|
+
end
|
26
|
+
|
27
|
+
it "raises an erro when given neither a string or spinner instance" do
|
28
|
+
spinners = TTY::Spinner::Multi.new(output: output, interval: 100)
|
29
|
+
|
30
|
+
expect { spinners.register [] }.
|
31
|
+
to raise_error(
|
32
|
+
ArgumentError,
|
33
|
+
"Expected a pattern or spinner, got: Array"
|
34
|
+
)
|
35
|
+
end
|
36
|
+
|
37
|
+
it "uses global options to register instance" do
|
38
|
+
spinners = TTY::Spinner::Multi.new(output: output, interval: 100)
|
39
|
+
spinner = double(:spinner, attach_to: nil)
|
40
|
+
allow(spinner).to receive(:on).and_return(spinner)
|
41
|
+
allow(TTY::Spinner).to receive(:new).and_return(spinner)
|
42
|
+
|
43
|
+
spinners.register "[:spinner]"
|
44
|
+
|
45
|
+
expect(TTY::Spinner).to have_received(:new).with("[:spinner]", {interval: 100, output: output})
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
RSpec.describe TTY::Spinner::Multi, '#spin' do
|
4
|
+
let(:output) { StringIO.new('', 'w+') }
|
5
|
+
let(:save) { TTY::Cursor.save }
|
6
|
+
let(:restore) { TTY::Cursor.restore }
|
7
|
+
let(:top) { TTY::Spinner::Multi::DEFAULT_INSET[:top] }
|
8
|
+
let(:middle) { TTY::Spinner::Multi::DEFAULT_INSET[:middle] }
|
9
|
+
let(:bottom) { TTY::Spinner::Multi::DEFAULT_INSET[:bottom] }
|
10
|
+
|
11
|
+
it "spins spinners correctly under multi spinner" do
|
12
|
+
spinners = TTY::Spinner::Multi.new(output: output)
|
13
|
+
|
14
|
+
spinner1 = spinners.register(":spinner one")
|
15
|
+
spinner2 = spinners.register(":spinner two")
|
16
|
+
|
17
|
+
spinner2.spin
|
18
|
+
spinner1.spin
|
19
|
+
|
20
|
+
output.rewind
|
21
|
+
expect(output.read).to eq([
|
22
|
+
"\e[1G| two\n",
|
23
|
+
"\e[1G| one\n"
|
24
|
+
].join)
|
25
|
+
|
26
|
+
spinner1.spin
|
27
|
+
|
28
|
+
output.rewind
|
29
|
+
expect(output.read).to eq([
|
30
|
+
"\e[1G| two\n",
|
31
|
+
"\e[1G| one\n",
|
32
|
+
save,
|
33
|
+
"\e[1A", # up 1 line
|
34
|
+
"\e[1G/ one",
|
35
|
+
restore
|
36
|
+
].join)
|
37
|
+
|
38
|
+
spinner2.spin
|
39
|
+
|
40
|
+
output.rewind
|
41
|
+
expect(output.read).to eq([
|
42
|
+
"\e[1G| two\n",
|
43
|
+
"\e[1G| one\n",
|
44
|
+
save,
|
45
|
+
"\e[1A", # up 1 line
|
46
|
+
"\e[1G/ one",
|
47
|
+
restore,
|
48
|
+
save,
|
49
|
+
"\e[2A", # up 2 lines
|
50
|
+
"\e[1G/ two",
|
51
|
+
restore
|
52
|
+
].join)
|
53
|
+
end
|
54
|
+
|
55
|
+
it "spins registerd spinners correctly under top level multi spinner" do
|
56
|
+
spinners = TTY::Spinner::Multi.new(":spinner top", output: output)
|
57
|
+
|
58
|
+
spinner1 = spinners.register(":spinner one")
|
59
|
+
spinner2 = spinners.register(":spinner two")
|
60
|
+
|
61
|
+
spinners.spin
|
62
|
+
|
63
|
+
spinner2.spin
|
64
|
+
spinner1.spin
|
65
|
+
|
66
|
+
output.rewind
|
67
|
+
expect(output.read).to eq([
|
68
|
+
"\e[1G#{top}| top\n",
|
69
|
+
"\e[1G#{middle}| two\n",
|
70
|
+
"\e[1G#{bottom}| one\n"
|
71
|
+
].join)
|
72
|
+
|
73
|
+
spinner1.spin
|
74
|
+
|
75
|
+
output.rewind
|
76
|
+
expect(output.read).to eq([
|
77
|
+
"\e[1G#{top}| top\n",
|
78
|
+
"\e[1G#{middle}| two\n",
|
79
|
+
"\e[1G#{bottom}| one\n",
|
80
|
+
save,
|
81
|
+
"\e[1A", # up 1 line
|
82
|
+
"\e[1G#{bottom}/ one",
|
83
|
+
restore
|
84
|
+
].join)
|
85
|
+
|
86
|
+
spinner2.spin
|
87
|
+
|
88
|
+
output.rewind
|
89
|
+
expect(output.read).to eq([
|
90
|
+
"\e[1G#{top}| top\n",
|
91
|
+
"\e[1G#{middle}| two\n",
|
92
|
+
"\e[1G#{bottom}| one\n",
|
93
|
+
save,
|
94
|
+
"\e[1A", # up 1 line
|
95
|
+
"\e[1G#{bottom}/ one",
|
96
|
+
restore,
|
97
|
+
save,
|
98
|
+
"\e[2A", # up 2 lines
|
99
|
+
"\e[1G#{middle}/ two",
|
100
|
+
restore
|
101
|
+
].join)
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
RSpec.describe TTY::Spinner::Multi, '#stop' do
|
4
|
+
let(:output) { StringIO.new('', 'w+') }
|
5
|
+
|
6
|
+
it 'stops unregisterd multi spinner and emits a :done message' do
|
7
|
+
spinners = TTY::Spinner::Multi.new(output: output)
|
8
|
+
callbacks = []
|
9
|
+
sp1 = spinners.register "[:spinner] one"
|
10
|
+
sp2 = spinners.register "[:spinner] two"
|
11
|
+
|
12
|
+
expect(sp1.done?).to eq(false)
|
13
|
+
expect(sp2.done?).to eq(false)
|
14
|
+
|
15
|
+
spinners.on(:error) { callbacks << :error }
|
16
|
+
.on(:done) { callbacks << :done }
|
17
|
+
.on(:success) { callbacks << :success }
|
18
|
+
|
19
|
+
spinners.stop
|
20
|
+
|
21
|
+
expect(sp1.done?).to eq(true)
|
22
|
+
expect(sp2.done?).to eq(true)
|
23
|
+
expect(callbacks).to eq([:done])
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'stops registerd multi spinner and emits a :done message' do
|
27
|
+
spinners = TTY::Spinner::Multi.new(":spinner", output: output)
|
28
|
+
callbacks = []
|
29
|
+
sp1 = spinners.register "[:spinner] one"
|
30
|
+
sp2 = spinners.register "[:spinner] two"
|
31
|
+
|
32
|
+
expect(sp1.done?).to eq(false)
|
33
|
+
expect(sp2.done?).to eq(false)
|
34
|
+
|
35
|
+
spinners.on(:error) { callbacks << :error }
|
36
|
+
.on(:done) { callbacks << :done }
|
37
|
+
.on(:success) { callbacks << :success }
|
38
|
+
|
39
|
+
spinners.stop
|
40
|
+
|
41
|
+
expect(sp1.done?).to eq(true)
|
42
|
+
expect(sp2.done?).to eq(true)
|
43
|
+
expect(callbacks).to eq([:done])
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'stops all registered spinners and emits a :done message' do
|
47
|
+
spinners = TTY::Spinner::Multi.new(output: output)
|
48
|
+
callbacks = []
|
49
|
+
sp1 = spinners.register "[:spinner] one"
|
50
|
+
sp2 = spinners.register "[:spinner] two"
|
51
|
+
|
52
|
+
expect(sp1.done?).to eq(false)
|
53
|
+
expect(sp2.done?).to eq(false)
|
54
|
+
|
55
|
+
spinners.on(:error) { callbacks << :error }
|
56
|
+
.on(:done) { callbacks << :done }
|
57
|
+
.on(:success) { callbacks << :success }
|
58
|
+
|
59
|
+
sp1.stop
|
60
|
+
sp2.stop
|
61
|
+
|
62
|
+
expect(spinners.done?).to eq(true)
|
63
|
+
expect(callbacks).to eq([:done])
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'stops all registered spinners under multispinner and emits a :done message' do
|
67
|
+
spinners = TTY::Spinner::Multi.new(":spinner", output: output)
|
68
|
+
callbacks = []
|
69
|
+
sp1 = spinners.register "[:spinner] one"
|
70
|
+
sp2 = spinners.register "[:spinner] two"
|
71
|
+
|
72
|
+
expect(sp1.done?).to eq(false)
|
73
|
+
expect(sp2.done?).to eq(false)
|
74
|
+
|
75
|
+
spinners.on(:error) { callbacks << :error }
|
76
|
+
.on(:done) { callbacks << :done }
|
77
|
+
.on(:success) { callbacks << :success }
|
78
|
+
|
79
|
+
sp1.stop
|
80
|
+
sp2.stop
|
81
|
+
|
82
|
+
expect(spinners.done?).to eq(true)
|
83
|
+
expect(callbacks).to eq([:done])
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'returns true when spinner is done' do
|
87
|
+
spinners = TTY::Spinner::Multi.new(output: output)
|
88
|
+
|
89
|
+
sp1 = spinners.register "[:spinner] one"
|
90
|
+
sp2 = spinners.register "[:spinner] two"
|
91
|
+
|
92
|
+
sp1.stop
|
93
|
+
sp2.error
|
94
|
+
|
95
|
+
expect(spinners.done?).to eq(true)
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
RSpec.describe TTY::Spinner::Multi, '#success' do
|
4
|
+
let(:output) { StringIO.new('', 'w+') }
|
5
|
+
|
6
|
+
it 'stops registerd multi spinner and emits a :success message' do
|
7
|
+
spinners = TTY::Spinner::Multi.new(":spinner", output: output)
|
8
|
+
callbacks = []
|
9
|
+
sp1 = spinners.register "[:spinner] one"
|
10
|
+
sp2 = spinners.register "[:spinner] two"
|
11
|
+
|
12
|
+
expect(sp1.success?).to eq(false)
|
13
|
+
expect(sp2.success?).to eq(false)
|
14
|
+
|
15
|
+
spinners.on(:error) { callbacks << :error }
|
16
|
+
.on(:done) { callbacks << :done }
|
17
|
+
.on(:success) { callbacks << :success }
|
18
|
+
|
19
|
+
spinners.success
|
20
|
+
|
21
|
+
expect(sp1.success?).to eq(true)
|
22
|
+
expect(sp2.success?).to eq(true)
|
23
|
+
expect(callbacks).to match_array([:success, :done])
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'stops unregistered multi spinner and emits a :success message' do
|
27
|
+
spinners = TTY::Spinner::Multi.new(output: output)
|
28
|
+
callbacks = []
|
29
|
+
sp1 = spinners.register "[:spinner] one"
|
30
|
+
sp2 = spinners.register "[:spinner] two"
|
31
|
+
|
32
|
+
expect(sp1.success?).to eq(false)
|
33
|
+
expect(sp2.success?).to eq(false)
|
34
|
+
|
35
|
+
spinners.on(:error) { callbacks << :error }
|
36
|
+
.on(:done) { callbacks << :done }
|
37
|
+
.on(:success) { callbacks << :success }
|
38
|
+
|
39
|
+
spinners.success
|
40
|
+
|
41
|
+
expect(sp1.success?).to eq(true)
|
42
|
+
expect(sp2.success?).to eq(true)
|
43
|
+
expect(callbacks).to match_array([:success, :done])
|
44
|
+
end
|
45
|
+
|
46
|
+
it "stops all registered spinners under top level and emits a :success message" do
|
47
|
+
spinners = TTY::Spinner::Multi.new(":spinner", output: output)
|
48
|
+
callbacks = []
|
49
|
+
sp1 = spinners.register "[:spinner] one"
|
50
|
+
sp2 = spinners.register "[:spinner] two"
|
51
|
+
|
52
|
+
expect(sp1.success?).to eq(false)
|
53
|
+
expect(sp2.success?).to eq(false)
|
54
|
+
|
55
|
+
spinners.on(:error) { callbacks << :error }
|
56
|
+
.on(:done) { callbacks << :done }
|
57
|
+
.on(:success) { callbacks << :success }
|
58
|
+
|
59
|
+
sp1.success
|
60
|
+
sp2.success
|
61
|
+
|
62
|
+
expect(spinners.success?).to eq(true)
|
63
|
+
expect(callbacks).to match_array([:success, :done])
|
64
|
+
end
|
65
|
+
|
66
|
+
it "stops all registered spinners and emits a success message" do
|
67
|
+
spinners = TTY::Spinner::Multi.new(output: output)
|
68
|
+
callbacks = []
|
69
|
+
sp1 = spinners.register "[:spinner] one"
|
70
|
+
sp2 = spinners.register "[:spinner] two"
|
71
|
+
|
72
|
+
expect(sp1.success?).to eq(false)
|
73
|
+
expect(sp2.success?).to eq(false)
|
74
|
+
|
75
|
+
spinners.on(:error) { callbacks << :error }
|
76
|
+
.on(:done) { callbacks << :done }
|
77
|
+
.on(:success) { callbacks << :success }
|
78
|
+
|
79
|
+
sp1.success
|
80
|
+
sp2.success
|
81
|
+
|
82
|
+
expect(spinners.success?).to eq(true)
|
83
|
+
expect(callbacks).to match_array([:success, :done])
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'returns false when a spinner has errored' do
|
87
|
+
spinners = TTY::Spinner::Multi.new(output: output)
|
88
|
+
|
89
|
+
sp1 = spinners.register("")
|
90
|
+
sp2 = spinners.register("")
|
91
|
+
|
92
|
+
sp1.success
|
93
|
+
sp2.error
|
94
|
+
|
95
|
+
expect(spinners.success?).to eq(false)
|
96
|
+
end
|
97
|
+
|
98
|
+
it "updates top spinner success state based on child spinners jobs status" do
|
99
|
+
spinners = TTY::Spinner::Multi.new("top", output: output)
|
100
|
+
|
101
|
+
spinners.register("one") { |sp| sp.success }
|
102
|
+
spinners.register("two") { |sp| sp.success }
|
103
|
+
|
104
|
+
expect(spinners.success?).to eq(false)
|
105
|
+
|
106
|
+
spinners.auto_spin
|
107
|
+
|
108
|
+
expect(spinners.success?).to eq(true)
|
109
|
+
end
|
110
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
RSpec.describe TTY::Spinner, '#new' do
|
4
|
+
|
5
|
+
it "creates spinner with default format" do
|
6
|
+
spinner = TTY::Spinner.new
|
7
|
+
expect(spinner.format).to eq(:classic)
|
8
|
+
end
|
9
|
+
|
10
|
+
it "doesn't accept unknown formatting tokens" do
|
11
|
+
expect {
|
12
|
+
TTY::Spinner.new(format: :unknown)
|
13
|
+
}.to raise_error(ArgumentError, /Unknown format token `:unknown`/)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "creates spinner with custom format" do
|
17
|
+
spinner = TTY::Spinner.new("Initializing... :spinner ")
|
18
|
+
expect(spinner.message).to eq("Initializing... :spinner ")
|
19
|
+
end
|
20
|
+
|
21
|
+
it "allows to set default output" do
|
22
|
+
output = $stdout
|
23
|
+
spinner = TTY::Spinner.new(output: output)
|
24
|
+
expect(spinner.output).to eq(output)
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
RSpec.describe TTY::Spinner, '#pause' do
|
4
|
+
let(:output) { StringIO.new('', 'w+') }
|
5
|
+
|
6
|
+
it "allows to pause auto spinning" do
|
7
|
+
spinner = TTY::Spinner.new(output: output, interval: 100)
|
8
|
+
allow(spinner).to receive(:spin)
|
9
|
+
|
10
|
+
spinner.auto_spin
|
11
|
+
expect(spinner.paused?).to eq(false)
|
12
|
+
|
13
|
+
sleep(0.02)
|
14
|
+
|
15
|
+
spinner.pause
|
16
|
+
expect(spinner.paused?).to eq(true)
|
17
|
+
|
18
|
+
spinner.resume
|
19
|
+
expect(spinner.paused?).to eq(true)
|
20
|
+
|
21
|
+
spinner.stop
|
22
|
+
|
23
|
+
expect(spinner).to have_received(:spin).at_least(1)
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
RSpec.describe TTY::Spinner, '#reset' do
|
4
|
+
let(:output) { StringIO.new('', 'w+') }
|
5
|
+
|
6
|
+
it "spins default frames" do
|
7
|
+
spinner = TTY::Spinner.new(output: output)
|
8
|
+
5.times do |n|
|
9
|
+
spinner.spin
|
10
|
+
spinner.reset if n == 2
|
11
|
+
end
|
12
|
+
output.rewind
|
13
|
+
expect(output.read).to eq([
|
14
|
+
"\e[1G|",
|
15
|
+
"\e[1G/",
|
16
|
+
"\e[1G-",
|
17
|
+
"\e[1G|",
|
18
|
+
"\e[1G/"
|
19
|
+
].join)
|
20
|
+
end
|
21
|
+
end
|