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,32 @@
1
+ # coding: utf-8
2
+
3
+ RSpec.describe TTY::Spinner, '#run' do
4
+ let(:output) { StringIO.new('', 'w+') }
5
+
6
+ it "runs animation while executing block" do
7
+ spinner = TTY::Spinner.new(output: output, interval: 100)
8
+ allow(spinner).to receive(:spin)
9
+ spinner.run("done") { sleep(0.1) }
10
+ expect(spinner).to have_received(:spin).at_least(5).times
11
+ end
12
+
13
+ it "runs animation and executes block within context" do
14
+ context = spy('context')
15
+ spinner = TTY::Spinner.new(":title", output: output)
16
+
17
+ spinner.run("done") do
18
+ context.call
19
+ spinner.update(title: 'executing')
20
+ end
21
+
22
+ expect(context).to have_received(:call).once
23
+ end
24
+
25
+ it "yields spinner instance when block argument is provided" do
26
+ spinner = TTY::Spinner.new(":title", output: output)
27
+
28
+ expect { |job|
29
+ spinner.run("done", &job)
30
+ }.to yield_with_args(spinner)
31
+ end
32
+ end
@@ -0,0 +1,90 @@
1
+ # coding: utf-8
2
+
3
+ RSpec.describe TTY::Spinner, '#spin' do
4
+ let(:output) { StringIO.new('', 'w+') }
5
+ let(:save) { TTY::Cursor.save }
6
+ let(:restore) { TTY::Cursor.restore }
7
+
8
+ it "spins default frames" do
9
+ spinner = TTY::Spinner.new(output: output)
10
+
11
+ expect(spinner.done?).to eq(false)
12
+
13
+ 5.times { spinner.spin }
14
+ output.rewind
15
+ expect(output.read).to eq([
16
+ "\e[1G|",
17
+ "\e[1G/",
18
+ "\e[1G-",
19
+ "\e[1G\\",
20
+ "\e[1G|"
21
+ ].join)
22
+ end
23
+
24
+ it "spins chosen frame" do
25
+ spinner = TTY::Spinner.new(output: output, format: :spin)
26
+ 5.times { spinner.spin }
27
+ output.rewind
28
+ expect(output.read).to eq([
29
+ "\e[1G◴",
30
+ "\e[1G◷",
31
+ "\e[1G◶",
32
+ "\e[1G◵",
33
+ "\e[1G◴"
34
+ ].join)
35
+ end
36
+
37
+ it "spins with message" do
38
+ spinner = TTY::Spinner.new("Loading ... :spinner", output: output)
39
+ 4.times { spinner.spin }
40
+ output.rewind
41
+ expect(output.read).to eq([
42
+ "\e[1GLoading ... |",
43
+ "\e[1GLoading ... /",
44
+ "\e[1GLoading ... -",
45
+ "\e[1GLoading ... \\"
46
+ ].join)
47
+ end
48
+
49
+ it "can spin and redraw indent" do
50
+ multi_spinner = double("MultiSpinner")
51
+ allow(multi_spinner).to receive(:synchronize).and_yield
52
+ allow(multi_spinner).to receive(:next_row).and_return(1)
53
+ allow(multi_spinner).to receive(:rows).and_return(1)
54
+ allow(multi_spinner).to receive(:line_inset).and_return("--- ")
55
+
56
+ spinner = TTY::Spinner.new(output: output)
57
+ spinner.attach_to(multi_spinner)
58
+ spinner.spin
59
+ spinner.redraw_indent
60
+
61
+ output.rewind
62
+ expect(output.read).to eq([
63
+ "\e[1G--- |\n",
64
+ save,
65
+ "\e[1A",
66
+ "--- ",
67
+ restore,
68
+ ].join)
69
+ end
70
+
71
+ it "spins with many threads" do
72
+ spinner = TTY::Spinner.new(output: output)
73
+
74
+ th1 = Thread.new { 3.times { spinner.spin; sleep(0.05) } }
75
+ th2 = Thread.new { 4.times { spinner.spin; sleep(0.05) } }
76
+
77
+ [th1, th2].each(&:join)
78
+
79
+ output.rewind
80
+ expect(output.read).to eq([
81
+ "\e[1G|",
82
+ "\e[1G/",
83
+ "\e[1G-",
84
+ "\e[1G\\",
85
+ "\e[1G|",
86
+ "\e[1G/",
87
+ "\e[1G-"
88
+ ].join)
89
+ end
90
+ end
@@ -0,0 +1,64 @@
1
+ # coding: utf-8
2
+
3
+ RSpec.describe TTY::Spinner, '#stop' do
4
+ let(:output) { StringIO.new('', 'w+') }
5
+
6
+ it "doesn't reprint stop message" do
7
+ spinner = TTY::Spinner.new(output: output)
8
+ spinner.spin
9
+ 3.times { spinner.stop }
10
+ output.rewind
11
+ expect(output.read).to eq([
12
+ "\e[1G|",
13
+ "\e[0m\e[2K",
14
+ "\e[1G|\n",
15
+ ].join)
16
+ end
17
+
18
+ it "stops after 2 spins" do
19
+ spinner = TTY::Spinner.new(output: output)
20
+ 5.times do |n|
21
+ spinner.spin
22
+ spinner.stop if n == 1
23
+ end
24
+ output.rewind
25
+ expect(output.read).to eq([
26
+ "\e[1G|",
27
+ "\e[1G/",
28
+ "\e[0m\e[2K",
29
+ "\e[1G/\n"
30
+ ].join)
31
+ end
32
+
33
+ it "stops after 2 spins and prints stop message" do
34
+ spinner = TTY::Spinner.new(output: output)
35
+ 5.times do |n|
36
+ spinner.spin
37
+ spinner.stop('Done!') if n == 1
38
+ end
39
+ output.rewind
40
+ expect(output.read).to eq([
41
+ "\e[1G|",
42
+ "\e[1G/",
43
+ "\e[0m\e[2K",
44
+ "\e[1G/ Done!\n"
45
+ ].join)
46
+
47
+ expect(spinner.done?).to eq(true)
48
+ end
49
+
50
+ it "stops after 2 spins with message and prints stop message" do
51
+ spinner = TTY::Spinner.new("Loading ... :spinner", output: output)
52
+ 5.times do |n|
53
+ spinner.spin
54
+ spinner.stop('Done!') if n == 1
55
+ end
56
+ output.rewind
57
+ expect(output.read).to eq([
58
+ "\e[1GLoading ... |",
59
+ "\e[1GLoading ... /",
60
+ "\e[0m\e[2K",
61
+ "\e[1GLoading ... / Done!\n"
62
+ ].join)
63
+ end
64
+ end
@@ -0,0 +1,46 @@
1
+ # coding: utf-8
2
+
3
+ RSpec.describe TTY::Spinner, '#success' do
4
+ let(:output) { StringIO.new('', 'w+') }
5
+
6
+ it "marks spinner as success" do
7
+ spinner = TTY::Spinner.new(output: output)
8
+ 3.times { spinner.spin }
9
+ spinner.success
10
+ output.rewind
11
+ expect(output.read).to eq([
12
+ "\e[1G|",
13
+ "\e[1G/",
14
+ "\e[1G-",
15
+ "\e[0m\e[2K",
16
+ "\e[1G#{TTY::Spinner::TICK}\n"
17
+ ].join)
18
+
19
+ expect(spinner.success?).to eq(true)
20
+ end
21
+
22
+ it "marks spinner as success with message" do
23
+ spinner = TTY::Spinner.new(output: output)
24
+ 3.times { spinner.spin }
25
+ spinner.success('Successful')
26
+ output.rewind
27
+ expect(output.read).to eq([
28
+ "\e[1G|",
29
+ "\e[1G/",
30
+ "\e[1G-",
31
+ "\e[0m\e[2K",
32
+ "\e[1G#{TTY::Spinner::TICK} Successful\n"
33
+ ].join)
34
+
35
+ expect(spinner.success?).to be(true)
36
+ end
37
+
38
+ it "changes success spinner marker" do
39
+ spinner = TTY::Spinner.new(success_mark: '*', output: output)
40
+ spinner.success('(successful)')
41
+ output.rewind
42
+ expect(output.read).to eq("\e[0m\e[2K\e[1G* (successful)\n")
43
+
44
+ expect(spinner.success?).to be(true)
45
+ end
46
+ end
@@ -0,0 +1,87 @@
1
+ # encoding: utf-8
2
+
3
+ RSpec.describe TTY::Spinner, '#update' do
4
+ let(:output) { StringIO.new('', 'w+') }
5
+
6
+ it "updates message content with custom token" do
7
+ spinner = TTY::Spinner.new(":title :spinner", output: output, interval: 100)
8
+ spinner.update(title: 'task')
9
+ 5.times { spinner.spin }
10
+ spinner.stop('done')
11
+ output.rewind
12
+ expect(output.read).to eq([
13
+ "\e[1Gtask |",
14
+ "\e[1Gtask /",
15
+ "\e[1Gtask -",
16
+ "\e[1Gtask \\",
17
+ "\e[1Gtask |",
18
+ "\e[0m\e[2K",
19
+ "\e[1Gtask | done\n"
20
+ ].join)
21
+ end
22
+
23
+ it "updates message many times before stopping" do
24
+ spinner = TTY::Spinner.new(":title :spinner", output: output)
25
+
26
+ spinner.update(title: 'task_a')
27
+ 2.times { spinner.spin }
28
+ spinner.update(title: 'task_b')
29
+ 2.times { spinner.spin }
30
+ spinner.stop('done')
31
+ output.rewind
32
+
33
+ expect(output.read).to eq([
34
+ "\e[1Gtask_a |",
35
+ "\e[1Gtask_a /",
36
+ "\e[0m\e[2K\e[1G",
37
+ "\e[1Gtask_b -",
38
+ "\e[1Gtask_b \\",
39
+ "\e[0m\e[2K",
40
+ "\e[1Gtask_b \\ done\n"
41
+ ].join)
42
+ end
43
+
44
+ it "updates message after stopping" do
45
+ spinner = TTY::Spinner.new(":title :spinner", output: output)
46
+
47
+ spinner.update(title: 'task_a')
48
+ 2.times { spinner.spin }
49
+ spinner.stop('done')
50
+
51
+ spinner.start
52
+ spinner.update(title: 'task_b')
53
+ 2.times { spinner.spin }
54
+ spinner.stop('done')
55
+
56
+ output.rewind
57
+ expect(output.read).to eq([
58
+ "\e[1Gtask_a |",
59
+ "\e[1Gtask_a /",
60
+ "\e[0m\e[2K",
61
+ "\e[1Gtask_a / done\n",
62
+ "\e[1Gtask_b |",
63
+ "\e[1Gtask_b /",
64
+ "\e[0m\e[2K",
65
+ "\e[1Gtask_b / done\n"
66
+ ].join)
67
+ end
68
+
69
+ it "maintains current tokens" do
70
+ spinner = TTY::Spinner.new(":foo :bar", output: output)
71
+ expect(spinner.tokens).to eq({})
72
+
73
+ spinner.update(foo: 'FOO')
74
+ spinner.update(bar: 'BAR')
75
+
76
+ expect(spinner.tokens).to include({foo: 'FOO', bar: 'BAR'})
77
+ end
78
+
79
+ it "updates more than one token" do
80
+ spinner = TTY::Spinner.new(":foo :bar", output: output)
81
+ expect(spinner.tokens).to eq({})
82
+
83
+ spinner.update(foo: 'FOO', bar: 'BAR')
84
+
85
+ expect(spinner.tokens).to include({foo: 'FOO', bar: 'BAR'})
86
+ end
87
+ end
@@ -0,0 +1,11 @@
1
+ # encoding: utf-8
2
+
3
+ desc 'Load gem inside irb console'
4
+ task :console do
5
+ require 'irb'
6
+ require 'irb/completion'
7
+ require_relative '../lib/tty-spinner'
8
+ ARGV.clear
9
+ IRB.start
10
+ end
11
+ task :c => :console
@@ -0,0 +1,11 @@
1
+ # encoding: utf-8
2
+
3
+ desc 'Measure code coverage'
4
+ task :coverage do
5
+ begin
6
+ original, ENV['COVERAGE'] = ENV['COVERAGE'], 'true'
7
+ Rake::Task['spec'].invoke
8
+ ensure
9
+ ENV['COVERAGE'] = original
10
+ end
11
+ end
@@ -0,0 +1,29 @@
1
+ # encoding: utf-8
2
+
3
+ begin
4
+ require 'rspec/core/rake_task'
5
+
6
+ desc 'Run all specs'
7
+ RSpec::Core::RakeTask.new(:spec) do |task|
8
+ task.pattern = 'spec/{unit,integration}{,/*/**}/*_spec.rb'
9
+ end
10
+
11
+ namespace :spec do
12
+ desc 'Run unit specs'
13
+ RSpec::Core::RakeTask.new(:unit) do |task|
14
+ task.pattern = 'spec/unit{,/*/**}/*_spec.rb'
15
+ end
16
+
17
+ desc 'Run integration specs'
18
+ RSpec::Core::RakeTask.new(:integration) do |task|
19
+ task.pattern = 'spec/integration{,/*/**}/*_spec.rb'
20
+ end
21
+ end
22
+
23
+ rescue LoadError
24
+ %w[spec spec:unit spec:integration].each do |name|
25
+ task name do
26
+ $stderr.puts "In order to run #{name}, do `gem install rspec`"
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,27 @@
1
+ lib = File.expand_path('../lib', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require 'tty/spinner/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'tty-spinner'
7
+ spec.version = TTY::Spinner::VERSION
8
+ spec.authors = ['Piotr Murach']
9
+ spec.email = ['pmurach@gmail.com']
10
+ spec.summary = %q{A terminal spinner for tasks that have non-deterministic time frame.}
11
+ spec.description = %q{A terminal spinner for tasks that have non-deterministic time frame.}
12
+ spec.homepage = "https://piotrmurach.github.io/tty"
13
+ spec.license = 'MIT'
14
+
15
+ spec.files = Dir['{lib,spec,examples}/**/*.rb']
16
+ spec.files += Dir['{bin,tasks}/*', 'tty-spinner.gemspec']
17
+ spec.files += Dir['README.md', 'CHANGELOG.md', 'LICENSE.txt', 'Rakefile']
18
+ spec.require_paths = ['lib']
19
+
20
+ spec.required_ruby_version = '>= 2.0.0'
21
+
22
+ spec.add_runtime_dependency 'tty-cursor', '~> 0.6.0'
23
+
24
+ spec.add_development_dependency 'bundler', '>= 1.5.0', '< 2.0'
25
+ spec.add_development_dependency 'rspec', '~> 3.1'
26
+ spec.add_development_dependency 'rake'
27
+ end
metadata CHANGED
@@ -1,29 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tty-spinner
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Piotr Murach
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-01-11 00:00:00.000000000 Z
11
+ date: 2018-12-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: tty-cursor
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 0.5.0
19
+ version: 0.6.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ">="
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 0.5.0
26
+ version: 0.6.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: bundler
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -79,14 +79,67 @@ executables: []
79
79
  extensions: []
80
80
  extra_rdoc_files: []
81
81
  files:
82
+ - CHANGELOG.md
82
83
  - LICENSE.txt
83
84
  - README.md
85
+ - Rakefile
86
+ - examples/auto_spin.rb
87
+ - examples/basic.rb
88
+ - examples/clear.rb
89
+ - examples/color.rb
90
+ - examples/error.rb
91
+ - examples/formats.rb
92
+ - examples/hide_cursor.rb
93
+ - examples/multi/basic.rb
94
+ - examples/multi/basic_top_level.rb
95
+ - examples/multi/custom_style.rb
96
+ - examples/multi/files.rb
97
+ - examples/multi/jobs.rb
98
+ - examples/multi/multi.rb
99
+ - examples/multi/multi_top_level.rb
100
+ - examples/multi/pause.rb
101
+ - examples/multi/threaded.rb
102
+ - examples/pause.rb
103
+ - examples/run.rb
104
+ - examples/success.rb
105
+ - examples/threaded.rb
106
+ - examples/update.rb
84
107
  - lib/tty-spinner.rb
85
108
  - lib/tty/spinner.rb
86
109
  - lib/tty/spinner/formats.rb
87
110
  - lib/tty/spinner/multi.rb
88
111
  - lib/tty/spinner/version.rb
89
- homepage: https://github.com/piotrmurach/tty-spinner
112
+ - spec/spec_helper.rb
113
+ - spec/unit/auto_spin_spec.rb
114
+ - spec/unit/clear_spec.rb
115
+ - spec/unit/error_spec.rb
116
+ - spec/unit/events_spec.rb
117
+ - spec/unit/formats_spec.rb
118
+ - spec/unit/frames_spec.rb
119
+ - spec/unit/hide_cursor_spec.rb
120
+ - spec/unit/job_spec.rb
121
+ - spec/unit/join_spec.rb
122
+ - spec/unit/multi/auto_spin_spec.rb
123
+ - spec/unit/multi/error_spec.rb
124
+ - spec/unit/multi/line_inset_spec.rb
125
+ - spec/unit/multi/on_spec.rb
126
+ - spec/unit/multi/register_spec.rb
127
+ - spec/unit/multi/spin_spec.rb
128
+ - spec/unit/multi/stop_spec.rb
129
+ - spec/unit/multi/success_spec.rb
130
+ - spec/unit/new_spec.rb
131
+ - spec/unit/pause_spec.rb
132
+ - spec/unit/reset_spec.rb
133
+ - spec/unit/run_spec.rb
134
+ - spec/unit/spin_spec.rb
135
+ - spec/unit/stop_spec.rb
136
+ - spec/unit/success_spec.rb
137
+ - spec/unit/update_spec.rb
138
+ - tasks/console.rake
139
+ - tasks/coverage.rake
140
+ - tasks/spec.rake
141
+ - tty-spinner.gemspec
142
+ homepage: https://piotrmurach.github.io/tty
90
143
  licenses:
91
144
  - MIT
92
145
  metadata: {}
@@ -98,7 +151,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
98
151
  requirements:
99
152
  - - ">="
100
153
  - !ruby/object:Gem::Version
101
- version: '0'
154
+ version: 2.0.0
102
155
  required_rubygems_version: !ruby/object:Gem::Requirement
103
156
  requirements:
104
157
  - - ">="
@@ -106,7 +159,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
106
159
  version: '0'
107
160
  requirements: []
108
161
  rubyforge_project:
109
- rubygems_version: 2.5.1
162
+ rubygems_version: 2.7.3
110
163
  signing_key:
111
164
  specification_version: 4
112
165
  summary: A terminal spinner for tasks that have non-deterministic time frame.