tty-spinner 0.8.0 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +120 -0
  3. data/README.md +28 -10
  4. data/Rakefile +8 -0
  5. data/examples/auto_spin.rb +8 -0
  6. data/examples/basic.rb +8 -0
  7. data/examples/clear.rb +9 -0
  8. data/examples/color.rb +12 -0
  9. data/examples/error.rb +9 -0
  10. data/examples/formats.rb +11 -0
  11. data/examples/hide_cursor.rb +12 -0
  12. data/examples/multi/basic.rb +13 -0
  13. data/examples/multi/basic_top_level.rb +13 -0
  14. data/examples/multi/custom_style.rb +26 -0
  15. data/examples/multi/files.rb +14 -0
  16. data/examples/multi/jobs.rb +10 -0
  17. data/examples/multi/multi.rb +17 -0
  18. data/examples/multi/multi_top_level.rb +18 -0
  19. data/examples/multi/pause.rb +26 -0
  20. data/examples/multi/threaded.rb +30 -0
  21. data/examples/pause.rb +19 -0
  22. data/examples/run.rb +18 -0
  23. data/examples/success.rb +9 -0
  24. data/examples/threaded.rb +11 -0
  25. data/examples/update.rb +11 -0
  26. data/lib/tty-spinner.rb +0 -2
  27. data/lib/tty/spinner.rb +40 -30
  28. data/lib/tty/spinner/formats.rb +3 -3
  29. data/lib/tty/spinner/multi.rb +31 -12
  30. data/lib/tty/spinner/version.rb +2 -2
  31. data/spec/spec_helper.rb +51 -0
  32. data/spec/unit/auto_spin_spec.rb +27 -0
  33. data/spec/unit/clear_spec.rb +18 -0
  34. data/spec/unit/error_spec.rb +46 -0
  35. data/spec/unit/events_spec.rb +37 -0
  36. data/spec/unit/formats_spec.rb +9 -0
  37. data/spec/unit/frames_spec.rb +33 -0
  38. data/spec/unit/hide_cursor_spec.rb +53 -0
  39. data/spec/unit/job_spec.rb +14 -0
  40. data/spec/unit/join_spec.rb +12 -0
  41. data/spec/unit/multi/auto_spin_spec.rb +34 -0
  42. data/spec/unit/multi/error_spec.rb +109 -0
  43. data/spec/unit/multi/line_inset_spec.rb +59 -0
  44. data/spec/unit/multi/on_spec.rb +13 -0
  45. data/spec/unit/multi/register_spec.rb +47 -0
  46. data/spec/unit/multi/spin_spec.rb +103 -0
  47. data/spec/unit/multi/stop_spec.rb +97 -0
  48. data/spec/unit/multi/success_spec.rb +110 -0
  49. data/spec/unit/new_spec.rb +26 -0
  50. data/spec/unit/pause_spec.rb +25 -0
  51. data/spec/unit/reset_spec.rb +21 -0
  52. data/spec/unit/run_spec.rb +32 -0
  53. data/spec/unit/spin_spec.rb +90 -0
  54. data/spec/unit/stop_spec.rb +64 -0
  55. data/spec/unit/success_spec.rb +46 -0
  56. data/spec/unit/update_spec.rb +87 -0
  57. data/tasks/console.rake +11 -0
  58. data/tasks/coverage.rake +11 -0
  59. data/tasks/spec.rake +29 -0
  60. data/tty-spinner.gemspec +27 -0
  61. 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