ego 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +20 -0
  3. data/.rubocop_todo.yml +36 -0
  4. data/Gemfile +2 -0
  5. data/Guardfile +9 -2
  6. data/Rakefile +5 -1
  7. data/bin/ego +2 -0
  8. data/ego.gemspec +22 -17
  9. data/lib/ego.rb +3 -1
  10. data/lib/ego/capability.rb +2 -0
  11. data/lib/ego/filesystem.rb +2 -0
  12. data/lib/ego/handler.rb +8 -2
  13. data/lib/ego/options.rb +13 -8
  14. data/lib/ego/plugin.rb +3 -1
  15. data/lib/ego/plugin_helper.rb +18 -16
  16. data/lib/ego/plugins/capabilities.rb +9 -3
  17. data/lib/ego/plugins/fallback.rb +9 -7
  18. data/lib/ego/plugins/robot_io.rb +2 -0
  19. data/lib/ego/plugins/social.rb +3 -1
  20. data/lib/ego/plugins/status.rb +2 -0
  21. data/lib/ego/plugins/system.rb +4 -2
  22. data/lib/ego/printer.rb +9 -5
  23. data/lib/ego/robot.rb +9 -6
  24. data/lib/ego/robot_error.rb +2 -0
  25. data/lib/ego/runner.rb +12 -7
  26. data/lib/ego/version.rb +3 -1
  27. data/spec/ego/acceptance/help_spec.rb +9 -0
  28. data/spec/ego/acceptance/no_args_spec.rb +9 -0
  29. data/spec/ego/acceptance/shell_spec.rb +11 -0
  30. data/spec/ego/acceptance/simple_query_spec.rb +9 -0
  31. data/spec/ego/acceptance/template_spec.rb +43 -0
  32. data/spec/ego/acceptance/usage_error_spec.rb +17 -0
  33. data/spec/ego/acceptance/version_spec.rb +9 -0
  34. data/spec/ego/capability_spec.rb +2 -0
  35. data/spec/ego/handler_spec.rb +18 -6
  36. data/spec/ego/options_spec.rb +8 -1
  37. data/spec/ego/plugin_helper_spec.rb +4 -2
  38. data/spec/ego/plugin_spec.rb +5 -4
  39. data/spec/ego/plugins/capabilities_spec.rb +4 -4
  40. data/spec/ego/plugins/fallback_spec.rb +16 -6
  41. data/spec/ego/plugins/robot_io_spec.rb +3 -3
  42. data/spec/ego/plugins/social_spec.rb +3 -3
  43. data/spec/ego/plugins/status_spec.rb +3 -3
  44. data/spec/ego/plugins/system_spec.rb +8 -8
  45. data/spec/ego/printer_spec.rb +86 -86
  46. data/spec/ego/robot_error_spec.rb +2 -0
  47. data/spec/ego/robot_spec.rb +24 -22
  48. data/spec/ego/runner_spec.rb +12 -0
  49. data/spec/spec_helper.rb +5 -48
  50. data/spec/support/aruba.rb +3 -0
  51. data/spec/support/plugin_helper.rb +64 -0
  52. metadata +71 -9
@@ -1,8 +1,8 @@
1
- require 'ego/robot'
1
+ # frozen_string_literal: true
2
2
 
3
- RSpec.describe Ego::Robot, 'with capabilities plug-in' do
4
- subject { robot_with_plugin('capabilities') }
3
+ require 'ego/robot'
5
4
 
5
+ RSpec.describe Ego::Robot, 'with capabilities plug-in', plugin: 'capabilities' do
6
6
  describe '#understand?' do
7
7
  it 'is defined on the robot instance' do
8
8
  expect(subject.respond_to?(:understand?)).to be true
@@ -13,7 +13,7 @@ RSpec.describe Ego::Robot, 'with capabilities plug-in' do
13
13
  end
14
14
 
15
15
  it 'returns true for queries the robot can handle' do
16
- subject.on(/^zzz$/) { }
16
+ subject.on(/^zzz$/) {}
17
17
  expect(subject.understand?('zzz')).to be true
18
18
  end
19
19
  end
@@ -1,22 +1,32 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'ego/robot'
2
4
 
3
- RSpec.describe Ego::Robot, 'with fallback plug-in' do
4
- subject { robot_with_plugin('fallback') }
5
+ RSpec.describe Ego::Robot, 'with fallback plug-in', plugin: 'fallback' do
5
6
  let(:unhandlable_query) { 'xxx' }
7
+ let(:empty_query) { '' }
6
8
 
7
9
  it { should be_able_to 'help you write plug-ins' }
8
10
 
9
- it { should_not handle_query :unhandlable_query }
11
+ it { should_not handle_query unhandlable_query }
10
12
 
11
13
  it 'prints a hint when a query is unhandled' do
12
- expect { subject.handle('xxx') }.to output(
14
+ expect { subject.handle(unhandlable_query) }.to output(
13
15
  /^Ego\.plugin/
14
16
  ).to_stdout
15
17
  end
16
18
 
17
19
  it 'prints a hint containing the original query' do
18
- expect { subject.handle('xxx') }.to output(
19
- /xxx/
20
+ expect { subject.handle(unhandlable_query) }.to output(
21
+ Regexp.new(unhandlable_query)
22
+ ).to_stdout
23
+ end
24
+
25
+ it { should handle_query empty_query }
26
+
27
+ it 'prints a message when the query is empty' do
28
+ expect { subject.handle(empty_query) }.to output(
29
+ /^(Yes|Hello|\.\.\.)\?$/
20
30
  ).to_stdout
21
31
  end
22
32
  end
@@ -1,8 +1,8 @@
1
- require 'ego/robot'
1
+ # frozen_string_literal: true
2
2
 
3
- RSpec.describe Ego::Robot, 'with robot_io plug-in' do
4
- subject { robot_with_plugin('robot_io') }
3
+ require 'ego/robot'
5
4
 
5
+ RSpec.describe Ego::Robot, 'with robot_io plug-in', plugin: 'robot_io' do
6
6
  it { should be_able_to 'output text to the terminal' }
7
7
 
8
8
  describe '#verbose?' do
@@ -1,8 +1,8 @@
1
- require 'ego/robot'
1
+ # frozen_string_literal: true
2
2
 
3
- RSpec.describe Ego::Robot, 'with social plug-in' do
4
- subject { robot_with_plugin('social') }
3
+ require 'ego/robot'
5
4
 
5
+ RSpec.describe Ego::Robot, 'with social plug-in', plugin: 'social' do
6
6
  it { should be_able_to 'socialize' }
7
7
 
8
8
  it { should handle_query 'who are you' }
@@ -1,8 +1,8 @@
1
- require 'ego/robot'
1
+ # frozen_string_literal: true
2
2
 
3
- RSpec.describe Ego::Robot, 'with status plug-in' do
4
- subject { robot_with_plugin('status') }
3
+ require 'ego/robot'
5
4
 
5
+ RSpec.describe Ego::Robot, 'with status plug-in', plugin: 'status' do
6
6
  it { should be_able_to 'report robot status' }
7
7
 
8
8
  it { should handle_query 'status' }
@@ -1,12 +1,12 @@
1
- require 'ego/robot'
1
+ # frozen_string_literal: true
2
2
 
3
- RSpec.describe Ego::Robot, 'with system plug-in' do
4
- subject { robot_with_plugin('system') }
3
+ require 'ego/robot'
5
4
 
5
+ RSpec.describe Ego::Robot, 'with system plug-in', plugin: 'system' do
6
6
  it { should be_able_to 'execute system commands' }
7
7
 
8
8
  describe '#system' do
9
- let(:args) { ['foo', 'bar'] }
9
+ let(:args) { %w[foo bar] }
10
10
 
11
11
  before do
12
12
  allow(Kernel).to receive(:system).and_return(true)
@@ -20,7 +20,7 @@ RSpec.describe Ego::Robot, 'with system plug-in' do
20
20
 
21
21
  it 'calls Kernel.system' do
22
22
  expect(Kernel).to receive(:system).with(*args)
23
- subject.system *args
23
+ subject.system(*args)
24
24
  end
25
25
 
26
26
  it 'prints a debug message' do
@@ -28,12 +28,12 @@ RSpec.describe Ego::Robot, 'with system plug-in' do
28
28
  'Running system with arguments %s.',
29
29
  args
30
30
  )
31
- subject.system *args
31
+ subject.system(*args)
32
32
  end
33
33
 
34
34
  it 'prints nothing on success' do
35
35
  expect(subject).not_to receive(:alert)
36
- subject.system *args
36
+ subject.system(*args)
37
37
  end
38
38
 
39
39
  it 'prints an alert on error' do
@@ -42,7 +42,7 @@ RSpec.describe Ego::Robot, 'with system plug-in' do
42
42
  'Sorry, there was a problem running %s.',
43
43
  args.first
44
44
  )
45
- subject.system *args
45
+ subject.system(*args)
46
46
  end
47
47
  end
48
48
 
@@ -1,122 +1,122 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'ego/printer'
2
4
 
3
- module Ego
4
- RSpec.describe Printer do
5
- let(:verbose_printer) { (Class.new { include Printer; def verbose?; true; end }).new }
6
- let(:printer) { (Class.new { include Printer }).new }
5
+ RSpec.describe Ego::Printer do
6
+ let(:verbose_printer) { (Class.new { include Ego::Printer; def verbose?; true; end }).new }
7
+ let(:printer) { (Class.new { include Ego::Printer }).new }
7
8
 
8
- before(:all) { String.disable_colorization = false }
9
- after(:all) { String.disable_colorization = true }
9
+ before(:all) { String.disable_colorization = false }
10
+ after(:all) { String.disable_colorization = true }
10
11
 
11
- describe '#puts' do
12
- it 'is callable on the module' do
13
- expect(described_class.respond_to?(:puts)).to be true
14
- end
12
+ describe '#puts' do
13
+ it 'is callable on the module' do
14
+ expect(described_class.respond_to?(:puts)).to be true
15
+ end
15
16
 
16
- it 'is private on the instance' do
17
- expect(printer.respond_to?(:puts)).to be false
18
- end
17
+ it 'is private on the instance' do
18
+ expect(printer.respond_to?(:puts)).to be false
19
+ end
19
20
 
20
- it 'prints to STDOUT' do
21
- expect { described_class.puts 'bar' }.to output("bar\n").to_stdout
22
- end
21
+ it 'prints to STDOUT' do
22
+ expect { described_class.puts 'bar' }.to output("bar\n").to_stdout
23
+ end
23
24
 
24
- it 'concatenates multiple arguments' do
25
- expect { described_class.puts 'bar', 'baz' }.to output("bar\nbaz\n").to_stdout
26
- end
25
+ it 'concatenates multiple arguments' do
26
+ expect { described_class.puts 'bar', 'baz' }.to output("bar\nbaz\n").to_stdout
27
27
  end
28
+ end
28
29
 
29
- describe '#errs' do
30
- it 'is callable on the module' do
31
- expect(described_class.respond_to?(:errs)).to be true
32
- end
30
+ describe '#errs' do
31
+ it 'is callable on the module' do
32
+ expect(described_class.respond_to?(:errs)).to be true
33
+ end
33
34
 
34
- it 'is private on the instance' do
35
- expect(printer.respond_to?(:errs)).to be false
36
- end
35
+ it 'is private on the instance' do
36
+ expect(printer.respond_to?(:errs)).to be false
37
+ end
37
38
 
38
- it 'prints to STDERR' do
39
- expect { described_class.errs 'bar' }.to output("bar\n").to_stderr
40
- end
39
+ it 'prints to STDERR' do
40
+ expect { described_class.errs 'bar' }.to output("bar\n").to_stderr
41
+ end
41
42
 
42
- it 'concatenates multiple arguments' do
43
- expect { described_class.errs 'bar', 'baz' }.to output("bar\nbaz\n").to_stderr
44
- end
43
+ it 'concatenates multiple arguments' do
44
+ expect { described_class.errs 'bar', 'baz' }.to output("bar\nbaz\n").to_stderr
45
45
  end
46
+ end
46
47
 
47
- describe '#say' do
48
- it 'is not callable on the module' do
49
- expect(described_class.respond_to?(:say)).to be false
50
- end
48
+ describe '#say' do
49
+ it 'is not callable on the module' do
50
+ expect(described_class.respond_to?(:say)).to be false
51
+ end
51
52
 
52
- it 'is callable on the instance' do
53
- expect(printer.respond_to?(:say)).to be true
54
- end
53
+ it 'is callable on the instance' do
54
+ expect(printer.respond_to?(:say)).to be true
55
+ end
55
56
 
56
- it 'prints the message to STDOUT bolded with newline' do
57
- expect { printer.say('X') }.to output("\e[1;39;49mX\e[0m\n").to_stdout
58
- end
57
+ it 'prints the message to STDOUT bolded with newline' do
58
+ expect { printer.say('X') }.to output("\e[1;39;49mX\e[0m\n").to_stdout
59
+ end
59
60
 
60
- it 'accepts placeholders and replacement strings' do
61
- expect { printer.say('Hello, %s.', 'world') }.to output("\e[1;39;49mHello, world.\e[0m\n").to_stdout
62
- end
61
+ it 'accepts placeholders and replacement strings' do
62
+ expect { printer.say('Hello, %s.', 'world') }.to output("\e[1;39;49mHello, world.\e[0m\n").to_stdout
63
63
  end
64
+ end
64
65
 
65
- describe '#emote' do
66
- it 'is not callable on the module' do
67
- expect(described_class.respond_to?(:emote)).to be false
68
- end
66
+ describe '#emote' do
67
+ it 'is not callable on the module' do
68
+ expect(described_class.respond_to?(:emote)).to be false
69
+ end
69
70
 
70
- it 'is callable on the instance' do
71
- expect(printer.respond_to?(:emote)).to be true
72
- end
71
+ it 'is callable on the instance' do
72
+ expect(printer.respond_to?(:emote)).to be true
73
+ end
73
74
 
74
- it 'prints the message to STDOUT with color and asterisks' do
75
- expect { printer.emote('FOO') }.to output("\e[0;35;49m*FOO*\e[0m\n").to_stdout
76
- end
75
+ it 'prints the message to STDOUT with color and asterisks' do
76
+ expect { printer.emote('FOO') }.to output("\e[0;35;49m*FOO*\e[0m\n").to_stdout
77
77
  end
78
+ end
78
79
 
79
- describe '#alert' do
80
- it 'is not callable on the module' do
81
- expect(described_class.respond_to?(:alert)).to be false
82
- end
80
+ describe '#alert' do
81
+ it 'is not callable on the module' do
82
+ expect(described_class.respond_to?(:alert)).to be false
83
+ end
83
84
 
84
- it 'is callable on the instance' do
85
- expect(printer.respond_to?(:alert)).to be true
86
- end
85
+ it 'is callable on the instance' do
86
+ expect(printer.respond_to?(:alert)).to be true
87
+ end
87
88
 
88
- it 'prints the message to STDERR with color and newline' do
89
- expect { printer.alert('FOO') }.to output("\e[0;91;49mFOO\e[0m\n").to_stderr
90
- end
89
+ it 'prints the message to STDERR with color and newline' do
90
+ expect { printer.alert('FOO') }.to output("\e[0;91;49mFOO\e[0m\n").to_stderr
91
+ end
91
92
 
92
- it 'accepts placeholders and replacement strings' do
93
- expect { printer.alert('Error: %s.', 'foo') }.to output("\e[0;91;49mError: foo.\e[0m\n").to_stderr
94
- end
93
+ it 'accepts placeholders and replacement strings' do
94
+ expect { printer.alert('Error: %s.', 'foo') }.to output("\e[0;91;49mError: foo.\e[0m\n").to_stderr
95
95
  end
96
+ end
96
97
 
97
- describe '#debug' do
98
- it 'is not callable on the module' do
99
- expect(described_class.respond_to?(:debug)).to be false
100
- end
98
+ describe '#debug' do
99
+ it 'is not callable on the module' do
100
+ expect(described_class.respond_to?(:debug)).to be false
101
+ end
101
102
 
102
- it 'is callable on the instance' do
103
- expect(printer.respond_to?(:debug)).to be true
104
- end
103
+ it 'is callable on the instance' do
104
+ expect(printer.respond_to?(:debug)).to be true
105
+ end
105
106
 
106
- context 'in verbose instance' do
107
- it 'prints the message to STDERR with newline' do
108
- expect { verbose_printer.debug('FOO') }.to output("FOO\n").to_stderr
109
- end
107
+ context 'in verbose instance' do
108
+ it 'prints the message to STDERR with newline' do
109
+ expect { verbose_printer.debug('FOO') }.to output("FOO\n").to_stderr
110
+ end
110
111
 
111
- it 'accepts placeholders and replacement strings' do
112
- expect { verbose_printer.debug('Hello, %s.', 'world') }.to output("Hello, world.\n").to_stderr
113
- end
112
+ it 'accepts placeholders and replacement strings' do
113
+ expect { verbose_printer.debug('Hello, %s.', 'world') }.to output("Hello, world.\n").to_stderr
114
114
  end
115
+ end
115
116
 
116
- context 'in default instance' do
117
- it 'does not print anything' do
118
- expect { printer.debug('FOO') }.not_to output.to_stderr
119
- end
117
+ context 'in default instance' do
118
+ it 'does not print anything' do
119
+ expect { printer.debug('FOO') }.not_to output.to_stderr
120
120
  end
121
121
  end
122
122
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'ego/robot_error'
2
4
 
3
5
  RSpec.describe Ego::RobotError do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'ego/robot'
2
4
 
3
5
  RSpec.describe Ego::Robot do
@@ -5,10 +7,10 @@ RSpec.describe Ego::Robot do
5
7
  let(:options) { double('Ego::Options') }
6
8
  let(:plugin) { double('Ego::Plugin') }
7
9
  subject do
8
- allow(options).to receive_messages({
10
+ allow(options).to receive_messages(
9
11
  robot_name: name,
10
- verbose: false,
11
- })
12
+ verbose: false
13
+ )
12
14
 
13
15
  described_class.new(options)
14
16
  end
@@ -97,7 +99,7 @@ RSpec.describe Ego::Robot do
97
99
  let(:priority) { 9 }
98
100
 
99
101
  before do
100
- subject.on(condition, priority) { }
102
+ subject.on(condition, priority) {}
101
103
  end
102
104
 
103
105
  it 'passes the condition and action to a new handler' do
@@ -114,9 +116,9 @@ RSpec.describe Ego::Robot do
114
116
  context 'given a hash' do
115
117
  before do
116
118
  subject.on(
117
- ->(q) { 'foo' } => 1,
118
- ->(q) { 'bar' } => 2,
119
- ) { }
119
+ ->(_q) { 'foo' } => 1,
120
+ ->(_q) { 'bar' } => 2
121
+ ) {}
120
122
  end
121
123
 
122
124
  it 'creates a new handler for each item' do
@@ -145,7 +147,7 @@ RSpec.describe Ego::Robot do
145
147
  end
146
148
 
147
149
  it 'executes the action in the context of the robot instance' do
148
- expect(subject.run_action(->() { name }, [])).to eq(subject.name)
150
+ expect(subject.run_action(-> { name }, [])).to eq(subject.name)
149
151
  end
150
152
  end
151
153
 
@@ -161,12 +163,12 @@ RSpec.describe Ego::Robot do
161
163
 
162
164
  it 'is run by #run_action' do
163
165
  subject.before_action { print 'Before!' }
164
- expect { subject.run_action(->(p) { true }, 'p') }.to output('Before!').to_stdout
166
+ expect { subject.run_action(->(_p) { true }, 'p') }.to output('Before!').to_stdout
165
167
  end
166
168
 
167
169
  it 'receives the action and action parameters' do
168
- subject.before_action { |action, params| print params }
169
- expect { subject.run_action(->(p) { true }, 'p') }.to output('p').to_stdout
170
+ subject.before_action { |_action, params| print params }
171
+ expect { subject.run_action(->(_p) { true }, 'p') }.to output('p').to_stdout
170
172
  end
171
173
  end
172
174
 
@@ -182,22 +184,22 @@ RSpec.describe Ego::Robot do
182
184
 
183
185
  it 'is run by #run_action' do
184
186
  subject.after_action { print 'After!' }
185
- expect { subject.run_action(->(p) { 'out' }, 'p') }.to output('After!').to_stdout
187
+ expect { subject.run_action(->(_p) { 'out' }, 'p') }.to output('After!').to_stdout
186
188
  end
187
189
 
188
190
  it 'receives the action, parameters, and return value' do
189
- subject.after_action { |action, params, result| print result + params }
190
- expect { subject.run_action(->(p) { 'out' }, 'p') }.to output('outp').to_stdout
191
+ subject.after_action { |_action, params, result| print result + params }
192
+ expect { subject.run_action(->(_p) { 'out' }, 'p') }.to output('outp').to_stdout
191
193
  end
192
194
  end
193
195
 
194
196
  describe '#first_handler_for' do
195
197
  before do
196
198
  subject.on(
197
- ->(q) { {} if 'bar'.match(q) } => 3,
198
- ->(q) { {} if 'foo'.match(q) } => 2,
199
- ->(q) { {} if 'foo'.match(q) } => 1,
200
- ) { }
199
+ ->(q) { {} if /bar/ =~ q } => 3,
200
+ ->(q) { {} if /foo/ =~ q } => 2,
201
+ ->(q) { {} if /foo/ =~ q } => 1
202
+ ) {}
201
203
  end
202
204
 
203
205
  it 'chooses the highest-priority handler that matches the query' do
@@ -212,9 +214,9 @@ RSpec.describe Ego::Robot do
212
214
  describe '#handle' do
213
215
  before do
214
216
  subject.on(
215
- ->(q) { {param: :three} if 'bar'.match(q) } => 3,
216
- ->(q) { {param: :two} if 'foo'.match(q) } => 2,
217
- ->(q) { {param: :one} if 'foo'.match(q) } => 1,
217
+ ->(q) { { param: :three } if /bar/ =~ q } => 3,
218
+ ->(q) { { param: :two } if /foo/ =~ q } => 2,
219
+ ->(q) { { param: :one } if /foo/ =~ q } => 1
218
220
  ) { |param| param }
219
221
  end
220
222
 
@@ -289,7 +291,7 @@ RSpec.describe Ego::Robot do
289
291
  end
290
292
 
291
293
  it 'is not run by #handle when the query is handled' do
292
- subject.on('xxx') { }
294
+ subject.on('xxx') {}
293
295
  expect { subject.handle('xxx') }.not_to output('Oops!').to_stdout
294
296
  end
295
297