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.
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