uh-wm 0.0.2.pre → 0.0.2
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 +4 -4
- data/.gitignore +3 -0
- data/.rspec +1 -0
- data/.travis.yml +15 -0
- data/Gemfile +5 -0
- data/Guardfile +12 -0
- data/LICENSE +30 -0
- data/README.md +68 -0
- data/Rakefile +40 -0
- data/bin/uhwm +5 -0
- data/config/cucumber.yaml +1 -0
- data/features/actions/execute.feature +9 -0
- data/features/actions/layout_delegation.feature +31 -0
- data/features/actions/quit.feature +9 -0
- data/features/cli/debug.feature +5 -0
- data/features/cli/layout.feature +15 -0
- data/features/cli/require.feature +5 -0
- data/features/cli/run_control.feature +9 -0
- data/features/cli/usage.feature +11 -0
- data/features/cli/verbose.feature +5 -0
- data/features/cli/version.feature +6 -0
- data/features/cli/worker.feature +9 -0
- data/features/layout/manage.feature +12 -0
- data/features/layout/protocol.feature +24 -0
- data/features/layout/unmanage.feature +10 -0
- data/features/manager/check_other_wm.feature +8 -0
- data/features/manager/input_events.feature +8 -0
- data/features/manager/manage.feature +14 -0
- data/features/manager/unmanage.feature +13 -0
- data/features/manager/x_errors.feature +17 -0
- data/features/run_control/evaluation.feature +18 -0
- data/features/run_control/key.feature +33 -0
- data/features/run_control/modifier.feature +10 -0
- data/features/run_control/worker.feature +9 -0
- data/features/session/connection.feature +5 -0
- data/features/session/termination.feature +13 -0
- data/features/steps/filesystem_steps.rb +3 -0
- data/features/steps/output_steps.rb +44 -0
- data/features/steps/run_control_steps.rb +3 -0
- data/features/steps/run_steps.rb +41 -0
- data/features/steps/x_steps.rb +53 -0
- data/features/support/env.rb +33 -0
- data/lib/uh/wm.rb +8 -0
- data/lib/uh/wm/actions_handler.rb +46 -0
- data/lib/uh/wm/cli.rb +20 -13
- data/lib/uh/wm/client.rb +64 -0
- data/lib/uh/wm/dispatcher.rb +3 -1
- data/lib/uh/wm/env.rb +15 -9
- data/lib/uh/wm/env_logging.rb +8 -0
- data/lib/uh/wm/logger_formatter.rb +16 -0
- data/lib/uh/wm/manager.rb +96 -14
- data/lib/uh/wm/run_control.rb +8 -3
- data/lib/uh/wm/runner.rb +82 -14
- data/lib/uh/wm/testing/acceptance_helpers.rb +140 -18
- data/lib/uh/wm/version.rb +1 -1
- data/lib/uh/wm/workers.rb +21 -0
- data/lib/uh/wm/workers/base.rb +27 -0
- data/lib/uh/wm/workers/blocking.rb +11 -0
- data/lib/uh/wm/workers/mux.rb +18 -0
- data/spec/spec_helper.rb +26 -0
- data/spec/support/exit_helpers.rb +6 -0
- data/spec/support/filesystem_helpers.rb +11 -0
- data/spec/uh/wm/actions_handler_spec.rb +30 -0
- data/spec/uh/wm/cli_spec.rb +214 -0
- data/spec/uh/wm/client_spec.rb +133 -0
- data/spec/uh/wm/dispatcher_spec.rb +76 -0
- data/spec/uh/wm/env_spec.rb +145 -0
- data/spec/uh/wm/manager_spec.rb +355 -0
- data/spec/uh/wm/run_control_spec.rb +102 -0
- data/spec/uh/wm/runner_spec.rb +186 -0
- data/uh-wm.gemspec +25 -0
- metadata +112 -9
@@ -1,7 +1,11 @@
|
|
1
|
+
require 'uh'
|
2
|
+
|
1
3
|
module Uh
|
2
4
|
module WM
|
3
5
|
module Testing
|
4
6
|
module AcceptanceHelpers
|
7
|
+
TIMEOUT_DEFAULT = 2
|
8
|
+
|
5
9
|
def uhwm_run options = '-v'
|
6
10
|
command = %w[uhwm]
|
7
11
|
command << options if options
|
@@ -9,7 +13,10 @@ module Uh
|
|
9
13
|
end
|
10
14
|
|
11
15
|
def uhwm_ensure_stop
|
12
|
-
|
16
|
+
if @process
|
17
|
+
x_key 'alt+shift+q'
|
18
|
+
@process.terminate
|
19
|
+
end
|
13
20
|
end
|
14
21
|
|
15
22
|
def uhwm_pid
|
@@ -20,33 +27,30 @@ module Uh
|
|
20
27
|
@process.stdout
|
21
28
|
end
|
22
29
|
|
23
|
-
def uhwm_wait_output message
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
end
|
30
|
-
sleep 0.1
|
30
|
+
def uhwm_wait_output message
|
31
|
+
output = -> { @process.stdout + @process.stderr }
|
32
|
+
timeout_until do
|
33
|
+
case message
|
34
|
+
when Regexp then output.call =~ message
|
35
|
+
when String then output.call.include? message
|
31
36
|
end
|
32
37
|
end
|
33
|
-
rescue
|
34
|
-
output = (@process.stdout + @process.stderr).lines
|
35
|
-
.map { |e| " #{e}" }
|
36
|
-
.join
|
38
|
+
rescue TimeoutError => e
|
37
39
|
fail [
|
38
|
-
"expected `#{message}' not seen after #{timeout} seconds in:",
|
39
|
-
" ```\n#{output} ```"
|
40
|
+
"expected `#{message}' not seen after #{e.timeout} seconds in:",
|
41
|
+
" ```\n#{output.call.lines.map { |e| " #{e}" }.join} ```"
|
40
42
|
].join "\n"
|
41
43
|
end
|
42
44
|
|
43
|
-
def uhwm_run_wait_ready
|
44
|
-
uhwm_run
|
45
|
+
def uhwm_run_wait_ready options = nil
|
46
|
+
if options then uhwm_run options else uhwm_run end
|
45
47
|
uhwm_wait_output 'Connected to'
|
46
48
|
end
|
47
49
|
|
48
50
|
def with_other_wm
|
49
|
-
@other_wm = ChildProcess.build('twm')
|
51
|
+
@other_wm = ChildProcess.build('twm')
|
52
|
+
@other_wm.start
|
53
|
+
yield
|
50
54
|
@other_wm.stop
|
51
55
|
end
|
52
56
|
|
@@ -54,6 +58,19 @@ module Uh
|
|
54
58
|
@other_wm
|
55
59
|
end
|
56
60
|
|
61
|
+
def x_client ident: :default
|
62
|
+
@x_clients ||= {}
|
63
|
+
@x_clients[ident] ||= XClient.new(ident)
|
64
|
+
end
|
65
|
+
|
66
|
+
def x_focused_window_id
|
67
|
+
Integer(`xdpyinfo`[/^focus:\s+window\s+(0x\h+)/, 1])
|
68
|
+
end
|
69
|
+
|
70
|
+
def x_input_event_masks
|
71
|
+
`xdpyinfo`[/current input event mask:\s+0x\h+([\w\s]+):/, 1].split(/\s+/).grep /Mask\z/
|
72
|
+
end
|
73
|
+
|
57
74
|
def x_key key
|
58
75
|
fail "cannot simulate X key `#{key}'" unless system "xdotool key #{key}"
|
59
76
|
end
|
@@ -66,6 +83,111 @@ module Uh
|
|
66
83
|
`sockstat -u`.lines.grep /\s+ruby.+\s+#{pid}/
|
67
84
|
end.any?
|
68
85
|
end
|
86
|
+
|
87
|
+
def x_window_id **options
|
88
|
+
x_client(options).window_id
|
89
|
+
end
|
90
|
+
|
91
|
+
def x_window_name
|
92
|
+
x_client.window_name
|
93
|
+
end
|
94
|
+
|
95
|
+
def x_window_map times: 1, **options
|
96
|
+
times.times { x_client(options).map }
|
97
|
+
x_client(options).sync
|
98
|
+
end
|
99
|
+
|
100
|
+
def x_window_map_state **options
|
101
|
+
`xwininfo -id #{x_window_id options}`[/Map State: (\w+)/, 1]
|
102
|
+
end
|
103
|
+
|
104
|
+
def x_window_unmap **options
|
105
|
+
x_client(options).unmap
|
106
|
+
x_client(options).sync
|
107
|
+
end
|
108
|
+
|
109
|
+
def x_window_destroy **options
|
110
|
+
x_client(options).destroy
|
111
|
+
x_client(options).sync
|
112
|
+
end
|
113
|
+
|
114
|
+
def x_clients_ensure_stop
|
115
|
+
@x_clients and @x_clients.any? and @x_clients.values.each &:terminate
|
116
|
+
end
|
117
|
+
|
118
|
+
|
119
|
+
private
|
120
|
+
|
121
|
+
def timeout_until
|
122
|
+
timeout = ENV.key?('UHWMTEST_TIMEOUT') ?
|
123
|
+
ENV['UHWMTEST_TIMEOUT'].to_i :
|
124
|
+
TIMEOUT_DEFAULT
|
125
|
+
Timeout.timeout(timeout) do
|
126
|
+
loop do
|
127
|
+
break if yield
|
128
|
+
sleep 0.1
|
129
|
+
end
|
130
|
+
end
|
131
|
+
rescue Timeout::Error
|
132
|
+
fail TimeoutError.new('execution expired', timeout)
|
133
|
+
end
|
134
|
+
|
135
|
+
|
136
|
+
class TimeoutError < ::StandardError
|
137
|
+
attr_reader :timeout
|
138
|
+
|
139
|
+
def initialize message, timeout
|
140
|
+
super message
|
141
|
+
@timeout = timeout
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
class XClient
|
146
|
+
attr_reader :name
|
147
|
+
|
148
|
+
def initialize name = object_id
|
149
|
+
@name = "#{self.class.name.split('::').last}/#{name}"
|
150
|
+
@geo = Geo.new(0, 0, 640, 480)
|
151
|
+
@display = Display.new.tap { |o| o.open }
|
152
|
+
end
|
153
|
+
|
154
|
+
def terminate
|
155
|
+
@display.close
|
156
|
+
end
|
157
|
+
|
158
|
+
def sync
|
159
|
+
@display.sync false
|
160
|
+
end
|
161
|
+
|
162
|
+
def window
|
163
|
+
@window ||= @display.create_window(@geo).tap do |o|
|
164
|
+
o.name = @name
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
def window_id
|
169
|
+
@window.id
|
170
|
+
end
|
171
|
+
|
172
|
+
def window_name
|
173
|
+
@name
|
174
|
+
end
|
175
|
+
|
176
|
+
def map
|
177
|
+
window.map
|
178
|
+
self
|
179
|
+
end
|
180
|
+
|
181
|
+
def unmap
|
182
|
+
window.unmap
|
183
|
+
self
|
184
|
+
end
|
185
|
+
|
186
|
+
def destroy
|
187
|
+
window.destroy
|
188
|
+
self
|
189
|
+
end
|
190
|
+
end
|
69
191
|
end
|
70
192
|
end
|
71
193
|
end
|
data/lib/uh/wm/version.rb
CHANGED
@@ -0,0 +1,21 @@
|
|
1
|
+
module Uh
|
2
|
+
module WM
|
3
|
+
module Workers
|
4
|
+
FACTORIES = {
|
5
|
+
block: ->(options) { Blocking.new(options) },
|
6
|
+
mux: ->(options) { Mux.new(options) }
|
7
|
+
}.freeze
|
8
|
+
|
9
|
+
class << self
|
10
|
+
def types
|
11
|
+
FACTORIES.keys
|
12
|
+
end
|
13
|
+
|
14
|
+
def build type, **options
|
15
|
+
(FACTORIES[type] or fail ArgumentError, "unknown worker: `#{type}'")
|
16
|
+
.call options
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Uh
|
2
|
+
module WM
|
3
|
+
module Workers
|
4
|
+
class Base
|
5
|
+
CALLBACKS = %w[before_wait on_timeout on_read on_read_next].freeze
|
6
|
+
|
7
|
+
def initialize **options
|
8
|
+
@ios = []
|
9
|
+
end
|
10
|
+
|
11
|
+
def watch io
|
12
|
+
@ios << io
|
13
|
+
end
|
14
|
+
|
15
|
+
CALLBACKS.each do |m|
|
16
|
+
define_method m do |*_, &block|
|
17
|
+
if block
|
18
|
+
instance_variable_set "@#{m}".to_sym, block
|
19
|
+
else
|
20
|
+
instance_variable_get "@#{m}".to_sym
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Uh
|
2
|
+
module WM
|
3
|
+
module Workers
|
4
|
+
class Mux < Base
|
5
|
+
def initialize timeout: 1
|
6
|
+
super
|
7
|
+
@timeout = timeout
|
8
|
+
end
|
9
|
+
|
10
|
+
def work_events
|
11
|
+
@before_wait.call if @before_wait
|
12
|
+
if res = select(@ios, [], [], @timeout) then @on_read.call res
|
13
|
+
else @on_timeout.call if @on_timeout end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'headless'
|
2
|
+
|
3
|
+
require 'uh/wm'
|
4
|
+
|
5
|
+
RSpec.configure do |config|
|
6
|
+
config.expect_with :rspec do |expectations|
|
7
|
+
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
|
8
|
+
end
|
9
|
+
|
10
|
+
config.mock_with :rspec do |mocks|
|
11
|
+
mocks.verify_partial_doubles = true
|
12
|
+
end
|
13
|
+
|
14
|
+
config.disable_monkey_patching!
|
15
|
+
|
16
|
+
config.before :all do
|
17
|
+
# Ensure current X display is not available from rspec test suite.
|
18
|
+
ENV.delete 'DISPLAY'
|
19
|
+
end
|
20
|
+
|
21
|
+
config.around :example, :xvfb do |example|
|
22
|
+
Headless.ly do
|
23
|
+
example.run
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Uh
|
2
|
+
module WM
|
3
|
+
RSpec.describe ActionsHandler do
|
4
|
+
let(:env) { Env.new(StringIO.new) }
|
5
|
+
let(:events) { Dispatcher.new }
|
6
|
+
subject(:actions) { described_class.new env, events }
|
7
|
+
|
8
|
+
describe '#evaluate' do
|
9
|
+
it 'evaluates given code' do
|
10
|
+
expect { actions.evaluate proc { throw :action_code } }
|
11
|
+
.to throw_symbol :action_code
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe '#quit' do
|
16
|
+
it 'emits the quit event' do
|
17
|
+
expect(events).to receive(:emit).with :quit
|
18
|
+
actions.quit
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe '#layout_*' do
|
23
|
+
it 'delegates messages to the layout with handle_ prefix' do
|
24
|
+
expect(env.layout).to receive :handle_screen_sel
|
25
|
+
actions.layout_screen_sel :succ
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,214 @@
|
|
1
|
+
require 'support/exit_helpers'
|
2
|
+
|
3
|
+
module Uh
|
4
|
+
module WM
|
5
|
+
RSpec.describe CLI do
|
6
|
+
include ExitHelpers
|
7
|
+
|
8
|
+
let(:stdout) { StringIO.new }
|
9
|
+
let(:stderr) { StringIO.new }
|
10
|
+
let(:arguments) { [] }
|
11
|
+
subject(:cli) { described_class.new arguments, stdout: stdout }
|
12
|
+
|
13
|
+
describe '.run' do
|
14
|
+
subject(:run) do
|
15
|
+
described_class.run arguments, stdout: stdout, stderr: stderr
|
16
|
+
end
|
17
|
+
|
18
|
+
# Prevent Runner from connecting a Manager and blocking.
|
19
|
+
before { allow(Runner).to receive :run }
|
20
|
+
|
21
|
+
it 'builds a new CLI with given arguments' do
|
22
|
+
expect(described_class)
|
23
|
+
.to receive(:new).with(arguments, stdout: stdout).and_call_original
|
24
|
+
run
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'parses new CLI arguments' do
|
28
|
+
cli
|
29
|
+
allow(described_class).to receive(:new) { cli }
|
30
|
+
expect(cli).to receive :parse_arguments!
|
31
|
+
run
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'runs new CLI' do
|
35
|
+
cli
|
36
|
+
allow(described_class).to receive(:new) { cli }
|
37
|
+
expect(cli).to receive :run
|
38
|
+
run
|
39
|
+
end
|
40
|
+
|
41
|
+
context 'with invalid arguments' do
|
42
|
+
let(:arguments) { %w[--unknown-option] }
|
43
|
+
|
44
|
+
it 'prints the usage on standard error stream' do
|
45
|
+
trap_exit { run }
|
46
|
+
expect(stderr.string).to match /\AUsage: .+/
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'exits with a return status of 64' do
|
50
|
+
expect { run }.to raise_error(SystemExit) do |e|
|
51
|
+
expect(e.status).to eq 64
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'when the new CLI raises a runtime error' do
|
57
|
+
before do
|
58
|
+
allow(cli).to receive(:run) { fail RuntimeError, 'some error' }
|
59
|
+
allow(described_class).to receive(:new) { cli }
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'exits with a return status of 70' do
|
63
|
+
expect { run }.to raise_error(SystemExit) do |e|
|
64
|
+
expect(e.status).to eq 70
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'formats the error' do
|
69
|
+
trap_exit { run }
|
70
|
+
expect(stderr.string)
|
71
|
+
.to match /\AUh::WM::RuntimeError: some error\n/
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'does not output a backtrace' do
|
75
|
+
trap_exit { run }
|
76
|
+
expect(stderr.string).not_to include __FILE__
|
77
|
+
end
|
78
|
+
|
79
|
+
context 'when debug mode is enabled' do
|
80
|
+
let(:arguments) { %w[-d] }
|
81
|
+
|
82
|
+
it 'outputs a backtrace' do
|
83
|
+
trap_exit { run }
|
84
|
+
expect(stderr.string).to include __FILE__
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
describe '#initialize' do
|
91
|
+
it 'builds an env with given stdout' do
|
92
|
+
expect(cli.env.output).to be stdout
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'syncs the output' do
|
96
|
+
expect(stdout).to receive(:sync=).with(true)
|
97
|
+
cli
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
describe '#run' do
|
102
|
+
it 'runs a runner with the env' do
|
103
|
+
expect(Runner).to receive(:run).with(cli.env)
|
104
|
+
cli.run
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
describe '#parse_arguments!' do
|
109
|
+
context 'with verbose option' do
|
110
|
+
let(:arguments) { %w[-v] }
|
111
|
+
|
112
|
+
it 'sets the env as verbose' do
|
113
|
+
cli.parse_arguments!
|
114
|
+
expect(cli.env).to be_verbose
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'tells the env to log its logger level' do
|
118
|
+
expect(cli.env).to receive :log_logger_level
|
119
|
+
cli.parse_arguments!
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
context 'with debug option' do
|
124
|
+
let(:arguments) { %w[-d] }
|
125
|
+
|
126
|
+
it 'sets the env as debug' do
|
127
|
+
cli.parse_arguments!
|
128
|
+
expect(cli.env).to be_debug
|
129
|
+
end
|
130
|
+
|
131
|
+
it 'tells the env to log its logger level' do
|
132
|
+
expect(cli.env).to receive :log_logger_level
|
133
|
+
cli.parse_arguments!
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
context 'with run control option' do
|
138
|
+
let(:arguments) { %w[-f uhwmrc.rb] }
|
139
|
+
|
140
|
+
it 'assigns run control file path in the env' do
|
141
|
+
cli.parse_arguments!
|
142
|
+
expect(cli.env.rc_path).to eq 'uhwmrc.rb'
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
context 'with require option' do
|
147
|
+
let(:arguments) { %w[-r abbrev] }
|
148
|
+
|
149
|
+
it 'requires the given ruby feature' do
|
150
|
+
expect { cli.parse_arguments! }
|
151
|
+
.to change { $LOADED_FEATURES.grep(/abbrev/).any? }
|
152
|
+
.from(false).to(true)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
context 'with layout option' do
|
157
|
+
let(:arguments) { %w[-l Object] }
|
158
|
+
|
159
|
+
it 'assigns the layout class in the env' do
|
160
|
+
cli.parse_arguments!
|
161
|
+
expect(cli.env.layout_class).to eq Object
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
context 'with worker option' do
|
166
|
+
let(:arguments) { %w[-w mux] }
|
167
|
+
|
168
|
+
it 'assigns the worker type in the env' do
|
169
|
+
cli.parse_arguments!
|
170
|
+
expect(cli.env.worker).to eq :mux
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
context 'with help option' do
|
175
|
+
let(:arguments) { %w[-h] }
|
176
|
+
|
177
|
+
it 'prints the usage banner on standard output' do
|
178
|
+
trap_exit { cli.parse_arguments! }
|
179
|
+
expect(stdout.string).to match /\AUsage: .+/
|
180
|
+
end
|
181
|
+
|
182
|
+
it 'prints options usage on standard output' do
|
183
|
+
trap_exit { cli.parse_arguments! }
|
184
|
+
expect(stdout.string).to match /\n^options:\n\s+-/
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
context 'with version option' do
|
189
|
+
let(:arguments) { %w[-V] }
|
190
|
+
|
191
|
+
it 'prints the version on standard output' do
|
192
|
+
trap_exit { cli.parse_arguments! }
|
193
|
+
expect(stdout.string).to eq "#{::Uh::WM::VERSION}\n"
|
194
|
+
end
|
195
|
+
|
196
|
+
it 'exits with a return status of 0' do
|
197
|
+
expect { cli.parse_arguments! }.to raise_error(SystemExit) do |e|
|
198
|
+
expect(e.status).to eq 0
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
context 'with invalid option' do
|
204
|
+
let(:arguments) { %w[--unknown-option] }
|
205
|
+
|
206
|
+
it 'raises a CLI::ArgumentError' do
|
207
|
+
expect { cli.parse_arguments! }
|
208
|
+
.to raise_error CLI::ArgumentError
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|