simple_commander 0.0.1 → 0.1.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 (46) hide show
  1. checksums.yaml +4 -4
  2. data/.byebug_history +15 -0
  3. data/.rubocop.yml +9 -0
  4. data/.rubocop_todo.yml +77 -0
  5. data/.travis.yml +6 -0
  6. data/Gemfile +1 -0
  7. data/History.rdoc +3 -0
  8. data/bin/simple_commander +1 -1
  9. data/coverage/.last_run.json +5 -0
  10. data/coverage/.resultset.json +1660 -0
  11. data/coverage/.resultset.json.lock +0 -0
  12. data/dir_glob.rb +7 -8
  13. data/ember_c +7 -38
  14. data/helper.rb +5 -0
  15. data/helpers/http_helper.rb +5 -0
  16. data/lib/simple_commander/command.rb +3 -3
  17. data/lib/simple_commander/configure.rb +2 -2
  18. data/lib/simple_commander/core_ext.rb +2 -2
  19. data/lib/simple_commander/delegates.rb +4 -3
  20. data/lib/simple_commander/help_formatters/base.rb +1 -1
  21. data/lib/simple_commander/help_formatters/terminal.rb +1 -1
  22. data/lib/simple_commander/help_formatters/terminal_compact.rb +1 -1
  23. data/lib/simple_commander/help_formatters.rb +4 -4
  24. data/lib/simple_commander/helpers/io.rb +128 -0
  25. data/lib/simple_commander/helpers.rb +1 -0
  26. data/lib/simple_commander/import.rb +1 -1
  27. data/lib/simple_commander/methods.rb +4 -4
  28. data/lib/simple_commander/platform.rb +1 -1
  29. data/lib/simple_commander/runner.rb +28 -6
  30. data/lib/simple_commander/user_interaction.rb +2 -2
  31. data/lib/simple_commander/version.rb +2 -2
  32. data/lib/simple_commander.rb +1 -0
  33. data/simple_commander.gemspec +2 -1
  34. data/spec/command_spec.rb +157 -0
  35. data/spec/configure_spec.rb +37 -0
  36. data/spec/core_ext/array_spec.rb +18 -0
  37. data/spec/core_ext/object_spec.rb +19 -0
  38. data/spec/help_formatters/terminal_compact_spec.rb +69 -0
  39. data/spec/help_formatters/terminal_spec.rb +67 -0
  40. data/spec/methods_spec.rb +20 -0
  41. data/spec/runner_spec.rb +659 -0
  42. data/spec/spec_helper.rb +82 -0
  43. data/spec/ui_spec.rb +30 -0
  44. data/test.rb +24 -0
  45. data/todo.yml +16 -4
  46. metadata +37 -2
@@ -0,0 +1,659 @@
1
+ require 'spec_helper'
2
+ require 'byebug'
3
+
4
+ describe SimpleCommander do
5
+ include SimpleCommander::Methods
6
+
7
+ before :each do
8
+ $stderr = StringIO.new
9
+ mock_terminal
10
+ create_test_command
11
+ end
12
+
13
+ describe '#program' do
14
+ it 'should set / get program information' do
15
+ program :name, 'test'
16
+ expect(program(:name)).to eq('test')
17
+ end
18
+
19
+ it 'should allow arbitrary blocks of global help documentation' do
20
+ program :help, 'Copyright', 'TJ Holowaychuk'
21
+ expect(program(:help)['Copyright']).to eq('TJ Holowaychuk')
22
+ end
23
+
24
+ it 'should raise an error when required info has not been set' do
25
+ new_command_runner '--help'
26
+ program :version, ''
27
+ expect { run! }.to raise_error(SimpleCommander::Runner::CommandError)
28
+ end
29
+
30
+ it 'should allow aliases of help formatters' do
31
+ program :help_formatter, :compact
32
+ expect(program(:help_formatter)).to eq(SimpleCommander::HelpFormatter::TerminalCompact)
33
+ end
34
+ end
35
+
36
+ describe '#command' do
37
+ it 'should return a command instance when only the name is passed' do
38
+ expect(command(:test)).to be_instance_of(SimpleCommander::Command)
39
+ end
40
+
41
+ it 'should return nil when the command does not exist' do
42
+ expect(command(:im_not_real)).to be_nil
43
+ end
44
+ end
45
+
46
+ describe '#helpers' do
47
+ it 'should add module mixins to the runner class' do
48
+ runner = new_command_runner { helpers 'IO' }
49
+ expect(runner.methods.include?(:copy)).to be true
50
+ end
51
+
52
+ it 'raise an exeption if a module is not defined' do
53
+ expect do
54
+ new_command_runner { helpers 'ABC' }
55
+ end.to raise_error(SimpleCommander::Runner::UndefinedHelperError)
56
+ end
57
+ end
58
+
59
+ describe '#separate_switches_from_description' do
60
+ it 'should seperate switches and description returning both' do
61
+ switches, description = *SimpleCommander::Runner.separate_switches_from_description('-h', '--help', 'display help')
62
+ expect(switches).to eq(['-h', '--help'])
63
+ expect(description).to eq('display help')
64
+ end
65
+ end
66
+
67
+ describe '#switch_to_sym' do
68
+ it 'should return a symbol based on the switch name' do
69
+ expect(SimpleCommander::Runner.switch_to_sym('--trace')).to eq(:trace)
70
+ expect(SimpleCommander::Runner.switch_to_sym('--foo-bar')).to eq(:foo_bar)
71
+ expect(SimpleCommander::Runner.switch_to_sym('--[no-]feature"')).to eq(:feature)
72
+ expect(SimpleCommander::Runner.switch_to_sym('--[no-]feature ARG')).to eq(:feature)
73
+ expect(SimpleCommander::Runner.switch_to_sym('--file [ARG]')).to eq(:file)
74
+ expect(SimpleCommander::Runner.switch_to_sym('--colors colors')).to eq(:colors)
75
+ end
76
+ end
77
+
78
+ describe '#alias_command' do
79
+ it 'should alias a command' do
80
+ alias_command :foo, :test
81
+ expect(command(:foo)).to eq(command(:test))
82
+ end
83
+
84
+ it 'should pass arguments passed to the alias when called' do
85
+ gem_name = ''
86
+ new_command_runner 'install', 'gem', 'commander' do
87
+ command :install do |c|
88
+ c.option '--gem-name NAME', 'Install a gem'
89
+ c.when_called { |_, options| gem_name = options.gem_name }
90
+ end
91
+ alias_command :'install gem', :install, '--gem-name'
92
+ end.run!
93
+ expect(gem_name).to eq('commander')
94
+ end
95
+ end
96
+
97
+ describe '#global_option' do
98
+ it 'should be invoked when used in the args list' do
99
+ file = ''
100
+ new_command_runner 'test', '--config', 'foo' do
101
+ global_option('--config FILE') { |f| file = f }
102
+ end.run!
103
+ expect(file).to eq('foo')
104
+ end
105
+
106
+ it 'should be inherited by commands' do
107
+ quiet = nil
108
+ new_command_runner 'foo', '--quiet' do
109
+ global_option('--quiet', 'Suppress output')
110
+ command :foo do |c|
111
+ c.when_called { |_, options| quiet = options.quiet }
112
+ end
113
+ end.run!
114
+ expect(quiet).to be true
115
+ end
116
+
117
+ it 'should be inherited by commands even when a block is present' do
118
+ quiet = nil
119
+ new_command_runner 'foo', '--quiet' do
120
+ global_option('--quiet', 'Suppress output') {}
121
+ command :foo do |c|
122
+ c.when_called { |_, options| quiet = options.quiet }
123
+ end
124
+ end.run!
125
+ expect(quiet).to be true
126
+ end
127
+
128
+ it 'should be inherited by commands when the positive form of a [no-] option' do
129
+ quiet = nil
130
+ new_command_runner 'foo', '--quiet' do
131
+ global_option('--[no-]quiet', 'Suppress output') {}
132
+ command :foo do |c|
133
+ c.when_called { |_, options| quiet = options.quiet }
134
+ end
135
+ end.run!
136
+ expect(quiet).to be true
137
+ end
138
+
139
+ it 'should be inherited by commands when the negative form of a [no-] option' do
140
+ quiet = nil
141
+ new_command_runner 'foo', '--no-quiet' do
142
+ global_option('--[no-]quiet', 'Suppress output') {}
143
+ command :foo do |c|
144
+ c.when_called { |_, options| quiet = options.quiet }
145
+ end
146
+ end.run!
147
+ expect(quiet).to be false
148
+ end
149
+ end
150
+
151
+ describe '#parse_global_options' do
152
+ it 'should parse global options before command' do
153
+ global_option = nil
154
+ new_command_runner('--testing-global', 'foo') do
155
+ global_option('--testing-global') { global_option = 'MAGIC' }
156
+
157
+ command :foo do |c|
158
+ c.when_called {}
159
+ end
160
+ end.run!
161
+ expect(global_option).to eq('MAGIC')
162
+ end
163
+
164
+ it 'should parse global options after command' do
165
+ global_option = nil
166
+ new_command_runner('foo', '--testing-global') do
167
+ global_option('--testing-global') { global_option = 'MAGIC' }
168
+
169
+ command :foo do |c|
170
+ c.when_called {}
171
+ end
172
+ end.run!
173
+ expect(global_option).to eq('MAGIC')
174
+ end
175
+
176
+ it 'should parse global options placed before command options' do
177
+ global_option = nil
178
+ new_command_runner('foo', '--testing-global', '--testing-command') do
179
+ global_option('--testing-global') { global_option = 'MAGIC' }
180
+
181
+ command :foo do |c|
182
+ c.option('--testing-command') {}
183
+ c.when_called {}
184
+ end
185
+ end.run!
186
+
187
+ expect(global_option).to eq('MAGIC')
188
+ end
189
+
190
+ it 'should parse global options placed after command options' do
191
+ global_option = nil
192
+ new_command_runner('foo', '--testing-command', '--testing-global') do
193
+ global_option('--testing-global') { global_option = 'MAGIC' }
194
+
195
+ command :foo do |c|
196
+ c.option('--testing-command') {}
197
+ c.when_called {}
198
+ end
199
+ end.run!
200
+
201
+ expect(global_option).to eq('MAGIC')
202
+ end
203
+
204
+ it 'should parse global options surrounded by command options' do
205
+ global_option = nil
206
+ new_command_runner('foo', '--testing-command', '--testing-global', '--other-command') do
207
+ global_option('--testing-global') { global_option = 'MAGIC' }
208
+
209
+ command :foo do |c|
210
+ c.option('--testing-command') {}
211
+ c.option('--other-command') {}
212
+ c.when_called {}
213
+ end
214
+ end.run!
215
+
216
+ expect(global_option).to eq('MAGIC')
217
+ end
218
+
219
+ it 'should not parse command options' do
220
+ global_option = nil
221
+ command_option = nil
222
+ new_command_runner('foo', '--testing-command', '--testing-global') do
223
+ global_option('--testing-global') { global_option = 'MAGIC' }
224
+
225
+ command :foo do |c|
226
+ c.option('--testing-command') { command_option = 'NO!' }
227
+ c.when_called {}
228
+ end
229
+ end.parse_global_options
230
+
231
+ expect(command_option).to be_nil
232
+ expect(global_option).to eq('MAGIC')
233
+ end
234
+
235
+ it 'should not affect command arguments with values' do
236
+ global_option = nil
237
+ command_option = nil
238
+ new_command_runner('foo', '--testing-command', 'bar', '--testing-global') do
239
+ global_option('--testing-global') { global_option = 'MAGIC' }
240
+
241
+ command :foo do |c|
242
+ c.option('--testing-command VALUE') { |v| command_option = v }
243
+ c.when_called {}
244
+ end
245
+ end.run!
246
+
247
+ expect(command_option).to eq('bar')
248
+ expect(global_option).to eq('MAGIC')
249
+ end
250
+
251
+ it 'should not affect global arguments with values' do
252
+ global_option = nil
253
+ new_command_runner('foo', '--testing-command', '--testing-global', 'bar') do
254
+ global_option('--testing-global VALUE') { |v| global_option = v }
255
+
256
+ command :foo do |c|
257
+ c.option('--testing-command') {}
258
+ c.when_called {}
259
+ end
260
+ end.run!
261
+
262
+ expect(global_option).to eq('bar')
263
+ end
264
+
265
+ it 'should allow global arguments with values before command arguments (github issue #8)' do
266
+ global_option = nil
267
+ command_option = nil
268
+ new_command_runner('foo', '--config', 'path', 'bar') do
269
+ global_option('--config VALUE') { |v| global_option = v }
270
+
271
+ command :foo do |c|
272
+ c.option('bar') { command_option = 'bar' }
273
+ c.when_called {}
274
+ end
275
+ end.run!
276
+
277
+ expect(global_option).to eq('path')
278
+ expect(command_option).to eq('bar')
279
+ end
280
+ end
281
+
282
+ describe '#remove_global_options' do
283
+ it 'should remove only specified switches' do
284
+ options, args = [], []
285
+ options << { switches: ['-t', '--trace'] }
286
+ options << { switches: ['--help'] }
287
+ options << { switches: ['--paths PATHS'] }
288
+ args << '-t'
289
+ args << '--help'
290
+ args << '--command'
291
+ args << '--command-with-arg' << 'rawr'
292
+ args << '--paths' << '"lib/**/*.js","spec/**/*.js"'
293
+ command_runner.remove_global_options options, args
294
+ expect(args).to eq(['--command', '--command-with-arg', 'rawr'])
295
+ end
296
+
297
+ it 'should not swallow an argument unless it expects an argument' do
298
+ options, args = [], []
299
+ options << { switches: ['-n', '--no-arg'] }
300
+ options << { switches: ['-y', '--yes ARG'] }
301
+ options << { switches: ['-a', '--alternative=ARG'] }
302
+ args << '-n' << 'alpha'
303
+ args << '--yes' << 'deleted'
304
+ args << '-a' << 'deleted'
305
+ args << 'beta'
306
+ command_runner.remove_global_options options, args
307
+ expect(args).to eq(%w(alpha beta))
308
+ end
309
+
310
+ it 'should remove a switch that is the positive form of the [no-] option' do
311
+ options, args = [], []
312
+ options << { switches: ['-g', '--[no-]good'] }
313
+ options << { switches: ['-y', '--yes ARG'] }
314
+ options << { switches: ['-a', '--alternative=ARG'] }
315
+ args << '--good' << 'alpha'
316
+ args << '--yes' << 'deleted'
317
+ args << '-a' << 'deleted'
318
+ args << 'beta'
319
+ command_runner.remove_global_options options, args
320
+ expect(args).to eq(%w(alpha beta))
321
+ end
322
+
323
+ it 'should remove a switch that is the negative form of the [no-] option' do
324
+ options, args = [], []
325
+ options << { switches: ['-g', '--[no-]good'] }
326
+ options << { switches: ['-y', '--yes ARG'] }
327
+ options << { switches: ['-a', '--alternative=ARG'] }
328
+ args << '--no-good' << 'alpha'
329
+ args << '--yes' << 'deleted'
330
+ args << '-a' << 'deleted'
331
+ args << 'beta'
332
+ command_runner.remove_global_options options, args
333
+ expect(args).to eq(%w(alpha beta))
334
+ end
335
+
336
+ it 'should not remove options that start with a global option name' do
337
+ options, args = [], []
338
+ options << { switches: ['-v', '--version'] }
339
+ args << '--versionCode' << 'something'
340
+ command_runner.remove_global_options options, args
341
+ expect(args).to eq(%w(--versionCode something))
342
+ end
343
+ end
344
+
345
+ describe '--trace' do
346
+ it 'should display pretty errors by default' do
347
+ expect do
348
+ new_command_runner 'foo' do
349
+ command(:foo) { |c| c.when_called { fail 'cookies!' } }
350
+ end.run!
351
+ end.to raise_error(SystemExit, /error: cookies!. Use --trace/)
352
+ end
353
+
354
+ it 'should display callstack when using this switch' do
355
+ expect do
356
+ new_command_runner 'foo', '--trace' do
357
+ command(:foo) { |c| c.when_called { fail 'cookies!' } }
358
+ end.run!
359
+ end.to raise_error(RuntimeError)
360
+ end
361
+ end
362
+
363
+ describe '#always_trace!' do
364
+ it 'should enable tracing globally, regardless of whether --trace was passed or not' do
365
+ expect do
366
+ new_command_runner 'foo' do
367
+ always_trace!
368
+ command(:foo) { |c| c.when_called { fail 'cookies!' } }
369
+ end.run!
370
+ end.to raise_error(RuntimeError)
371
+ end
372
+ end
373
+
374
+ describe '#never_trace!' do
375
+ it 'should disable tracing globally, regardless of whether --trace was passed or not' do
376
+ expect do
377
+ new_command_runner 'help', '--trace' do
378
+ never_trace!
379
+ end.run!
380
+ end.to raise_error(SystemExit, /invalid option: --trace/)
381
+ end
382
+
383
+ it 'should not prompt to use --trace switch on errors' do
384
+ msg = nil
385
+ begin
386
+ new_command_runner 'foo' do
387
+ never_trace!
388
+ command(:foo) { |c| c.when_called { fail 'cookies!' } }
389
+ end.run!
390
+ rescue SystemExit => e
391
+ msg = e.message
392
+ end
393
+ expect(msg).to match(/error: cookies!/)
394
+ expect(msg).not_to match(/--trace/)
395
+ end
396
+ end
397
+
398
+ context 'conflict between #always_trace! and #never_trace!' do
399
+ it 'respects the last used command' do
400
+ expect do
401
+ new_command_runner 'foo' do
402
+ never_trace!
403
+ always_trace!
404
+ command(:foo) { |c| c.when_called { fail 'cookies!' } }
405
+ end.run!
406
+ end.to raise_error(RuntimeError)
407
+ end
408
+ end
409
+
410
+ describe '--version' do
411
+ it 'should output program version' do
412
+ expect(run('--version')).to eq("test 1.2.3\n")
413
+ end
414
+ end
415
+
416
+ describe '--help' do
417
+ it 'should not output an invalid command message' do
418
+ expect(run('--help')).not_to eq("invalid command. Use --help for more information\n")
419
+ end
420
+
421
+ it 'can be used before or after the command and options' do
422
+ expect(run('test', '--help')).to eq("Implement help for test here\n")
423
+ end
424
+ end
425
+
426
+ describe 'with invalid options' do
427
+ it 'should output an invalid option message' do
428
+ expect do
429
+ run('test', '--invalid-option')
430
+ end.to raise_error(SystemExit, /invalid option: --invalid-option/)
431
+ end
432
+ end
433
+
434
+ describe 'with invalid command passed' do
435
+ it 'should output an invalid command message' do
436
+ expect do
437
+ run('foo')
438
+ end.to raise_error(SystemExit, /invalid command. Use --help for more information/)
439
+ end
440
+ end
441
+
442
+ describe 'with nested commands' do
443
+ it 'should run nested command' do
444
+ new_command_runner('parent', 'child') do
445
+ command :parent do
446
+ command :child do
447
+ action do |args, options|
448
+ say 'nested child'
449
+ end
450
+ end
451
+ end
452
+ end.run!
453
+
454
+ expect(@output.string).to eq ("nested child\n")
455
+ end
456
+ end
457
+
458
+ describe 'with invalid command passed to help' do
459
+ it 'should output an invalid command message' do
460
+ expect do
461
+ run('help', 'does_not_exist')
462
+ end.to raise_error(SystemExit, /invalid command. Use --help for more information/)
463
+ end
464
+ end
465
+
466
+ describe 'with invalid command passed to --help' do
467
+ it 'should output an invalid command message' do
468
+ expect do
469
+ run('--help', 'does_not_exist')
470
+ end.to raise_error(SystemExit, /invalid command. Use --help for more information/)
471
+ end
472
+ end
473
+
474
+ describe 'with invalid option passed to --help' do
475
+ it 'should output an invalid option message' do
476
+ expect do
477
+ run('--help', 'test', '--invalid-option')
478
+ end.to raise_error(SystemExit, /invalid option: --invalid-option/)
479
+ end
480
+ end
481
+
482
+ describe '#valid_command_names_from' do
483
+ it 'should return array of valid command names' do
484
+ new_command_runner do
485
+ command('foo bar') {}
486
+ command('foo bar foo') {}
487
+ expect(command_runner.valid_command_names_from('foo', 'bar', 'foo').sort).to eq(['foo bar', 'foo bar foo'])
488
+ end
489
+ end
490
+
491
+ it 'should return empty array when no possible command names exist' do
492
+ new_command_runner do
493
+ expect(command_runner.valid_command_names_from('fake', 'command', 'name')).to eq([])
494
+ end
495
+ end
496
+
497
+ it 'should match exact commands only' do
498
+ new_command_runner do
499
+ command('foo') {}
500
+ expect(command_runner.valid_command_names_from('foobar')).to eq([])
501
+ end
502
+ end
503
+ end
504
+
505
+ describe '#command_name_from_args' do
506
+ it 'should locate command within arbitrary arguments passed' do
507
+ new_command_runner '--help', '--arbitrary', 'test'
508
+ expect(command_runner.command_name_from_args).to eq('test')
509
+ end
510
+
511
+ it 'should support multi-word commands' do
512
+ new_command_runner '--help', '--arbitrary', 'some', 'long', 'command', 'foo'
513
+ command('some long command') {}
514
+ expect(command_runner.command_name_from_args).to eq('some long command')
515
+ end
516
+
517
+ it 'should match the longest possible command' do
518
+ new_command_runner '--help', '--arbitrary', 'foo', 'bar', 'foo'
519
+ command('foo bar') {}
520
+ command('foo bar foo') {}
521
+ expect(command_runner.command_name_from_args).to eq('foo bar foo')
522
+ end
523
+
524
+ it 'should use the left-most command name when multiple are present' do
525
+ new_command_runner 'help', 'test'
526
+ expect(command_runner.command_name_from_args).to eq('help')
527
+ end
528
+ end
529
+
530
+ describe '#active_command' do
531
+ it 'should resolve the active command' do
532
+ new_command_runner '--help', 'test'
533
+ expect(command_runner.active_command).to be_instance_of(SimpleCommander::Command)
534
+ end
535
+
536
+ it 'should resolve active command when invalid options are passed' do
537
+ new_command_runner '--help', 'test', '--arbitrary'
538
+ expect(command_runner.active_command).to be_instance_of(SimpleCommander::Command)
539
+ end
540
+
541
+ it 'should return nil when the command is not found' do
542
+ new_command_runner 'foo'
543
+ expect(command_runner.active_command).to be_nil
544
+ end
545
+ end
546
+
547
+ describe '#default_command' do
548
+ it 'should allow you to default any command when one is not explicitly passed' do
549
+ new_command_runner '--trace' do
550
+ default_command :test
551
+ expect(command(:test)).to receive(:run).once
552
+ expect(command_runner.active_command).to eq(command(:test))
553
+ end.run!
554
+ end
555
+
556
+ it 'should not prevent other commands from being called' do
557
+ new_command_runner 'foo', 'bar', '--trace' do
558
+ default_command :test
559
+ command(:'foo bar') {}
560
+ expect(command(:'foo bar')).to receive(:run).once
561
+ expect(command_runner.active_command).to eq(command(:'foo bar'))
562
+ end.run!
563
+ end
564
+
565
+ it 'should not prevent longer commands to use the same words as the default' do
566
+ new_command_runner 'foo', 'bar', 'something'
567
+ default_command :'foo bar'
568
+ command(:'foo bar') {}
569
+ command(:'foo bar something') {}
570
+ expect(command_runner.active_command).to eq(command(:'foo bar something'))
571
+ end
572
+
573
+ it 'should allow defaulting of command aliases' do
574
+ new_command_runner '--trace' do
575
+ default_command :foobar
576
+ alias_command :foobar, :test
577
+ expect(command(:test)).to receive(:run).once
578
+ end.run!
579
+ end
580
+ end
581
+
582
+ describe 'should function correctly' do
583
+ it 'when options are passed before the command name' do
584
+ new_command_runner '--verbose', 'test', 'foo', 'bar' do
585
+ @command.when_called do |args, options|
586
+ expect(args).to eq(%w(foo bar))
587
+ expect(options.verbose).to be true
588
+ end
589
+ end.run!
590
+ end
591
+
592
+ it 'when options are passed after the command name' do
593
+ new_command_runner 'test', '--verbose', 'foo', 'bar' do
594
+ @command.when_called do |args, options|
595
+ expect(args).to eq(%w(foo bar))
596
+ expect(options.verbose).to be true
597
+ end
598
+ end.run!
599
+ end
600
+
601
+ it 'when an argument passed is the same name as the command' do
602
+ new_command_runner 'test', '--verbose', 'foo', 'test', 'bar' do
603
+ @command.when_called do |args, options|
604
+ expect(args).to eq(%w(foo test bar))
605
+ expect(options.verbose).to be true
606
+ end
607
+ end.run!
608
+ end
609
+
610
+ it 'when using multi-word commands' do
611
+ new_command_runner '--verbose', 'my', 'command', 'something', 'foo', 'bar' do
612
+ command('my command') { |c| c.option('--verbose') }
613
+ expect(command_runner.command_name_from_args).to eq('my command')
614
+ expect(command_runner.args_without_command_name).to eq(['--verbose', 'something', 'foo', 'bar'])
615
+ end.run!
616
+ end
617
+
618
+ it 'when using multi-word commands with parts of the command name as arguments' do
619
+ new_command_runner '--verbose', 'my', 'command', 'something', 'my', 'command' do
620
+ command('my command') { |c| c.option('--verbose') }
621
+ expect(command_runner.command_name_from_args).to eq('my command')
622
+ expect(command_runner.args_without_command_name).to eq(['--verbose', 'something', 'my', 'command'])
623
+ end.run!
624
+ end
625
+
626
+ it 'when using multi-word commands with other commands using the same words' do
627
+ new_command_runner '--verbose', 'my', 'command', 'something', 'my', 'command' do
628
+ command('my command') {}
629
+ command('my command something') { |c| c.option('--verbose') }
630
+ expect(command_runner.command_name_from_args).to eq('my command something')
631
+ expect(command_runner.args_without_command_name).to eq(['--verbose', 'my', 'command'])
632
+ end.run!
633
+ end
634
+ end
635
+
636
+ describe 'options with optional arguments' do
637
+ it 'should return the argument when it is specified' do
638
+ new_command_runner 'foo', '--optional', 'arg1' do
639
+ command('foo') do |c|
640
+ c.option('--optional [argument]')
641
+ c.when_called do |_, options|
642
+ expect(options.optional).to eq('arg1')
643
+ end
644
+ end
645
+ end.run!
646
+ end
647
+
648
+ it 'should return true when no argument is specified for the option' do
649
+ new_command_runner 'foo', '--optional' do
650
+ command('foo') do |c|
651
+ c.option('--optional [argument]')
652
+ c.when_called do |_, options|
653
+ expect(options.optional).to be true
654
+ end
655
+ end
656
+ end.run!
657
+ end
658
+ end
659
+ end