cliqr 1.1.0 → 1.2.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 (60) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +128 -1
  3. data/README.md +97 -71
  4. data/examples/README.md +12 -0
  5. data/examples/hbase +58 -0
  6. data/examples/my-command +63 -0
  7. data/examples/numbers +55 -0
  8. data/examples/vagrant +90 -0
  9. data/lib/cliqr.rb +17 -2
  10. data/lib/cliqr/argument_validation/argument_type_validator.rb +2 -2
  11. data/lib/cliqr/argument_validation/validator.rb +1 -1
  12. data/lib/cliqr/cli/argument_operator.rb +44 -0
  13. data/lib/cliqr/cli/argument_operator_context.rb +20 -0
  14. data/lib/cliqr/cli/command.rb +1 -1
  15. data/lib/cliqr/cli/command_context.rb +93 -12
  16. data/lib/cliqr/cli/command_runner_factory.rb +2 -2
  17. data/lib/cliqr/cli/config.rb +301 -33
  18. data/lib/cliqr/cli/executor.rb +14 -9
  19. data/lib/cliqr/cli/interface.rb +22 -7
  20. data/lib/cliqr/cli/router.rb +6 -2
  21. data/lib/cliqr/cli/shell_command.rb +69 -0
  22. data/lib/cliqr/cli/usage_builder.rb +185 -0
  23. data/lib/cliqr/config_validation/validator_factory.rb +59 -5
  24. data/lib/cliqr/error.rb +10 -4
  25. data/lib/cliqr/parser/action_token.rb +23 -0
  26. data/lib/cliqr/parser/argument_parser.rb +1 -1
  27. data/lib/cliqr/parser/argument_token.rb +1 -4
  28. data/lib/cliqr/parser/argument_tree_walker.rb +40 -8
  29. data/lib/cliqr/parser/option_token.rb +2 -1
  30. data/lib/cliqr/parser/parsed_input.rb +21 -2
  31. data/lib/cliqr/parser/parsed_input_builder.rb +11 -7
  32. data/lib/cliqr/parser/token.rb +3 -9
  33. data/lib/cliqr/parser/token_factory.rb +1 -1
  34. data/lib/cliqr/util.rb +135 -0
  35. data/lib/cliqr/version.rb +1 -1
  36. data/spec/argument_parser_spec_helper.rb +15 -0
  37. data/spec/config/action_config_validator_spec.rb +146 -0
  38. data/spec/config/config_finalize_spec.rb +1 -1
  39. data/spec/config/config_validator_spec.rb +29 -19
  40. data/spec/config/option_config_validator_spec.rb +13 -13
  41. data/spec/dsl/interface_spec.rb +1 -168
  42. data/spec/dsl/usage_spec.rb +705 -0
  43. data/spec/executor/action_executor_spec.rb +205 -0
  44. data/spec/executor/executor_spec.rb +405 -17
  45. data/spec/executor/help_executor_spec.rb +424 -0
  46. data/spec/executor/shell_executor_spec.rb +233 -0
  47. data/spec/fixtures/action_reader_command.rb +12 -0
  48. data/spec/fixtures/csv_argument_operator.rb +8 -0
  49. data/spec/fixtures/test_option_type_checker_command.rb +8 -0
  50. data/spec/parser/action_argument_parser_spec.rb +113 -0
  51. data/spec/parser/argument_parser_spec.rb +37 -44
  52. data/spec/spec_helper.rb +1 -0
  53. data/spec/validation/action_argument_validator_spec.rb +50 -0
  54. data/spec/validation/{argument_validation_spec.rb → command_argument_validation_spec.rb} +36 -18
  55. data/spec/validation/error_spec.rb +1 -1
  56. data/tasks/rdoc.rake +16 -0
  57. data/tasks/rubucop.rake +14 -0
  58. data/tasks/yard.rake +21 -0
  59. data/templates/usage.erb +39 -0
  60. metadata +48 -11
@@ -0,0 +1,205 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ require 'fixtures/test_command'
6
+ require 'fixtures/always_error_command'
7
+ require 'fixtures/action_reader_command'
8
+ require 'fixtures/test_option_reader_command'
9
+ require 'fixtures/test_option_checker_command'
10
+ require 'fixtures/argument_reader_command'
11
+
12
+ describe Cliqr::CLI::Executor do
13
+ it 'routes to action command with no arguments' do
14
+ cli = Cliqr.interface do
15
+ name 'my-command'
16
+ handler TestCommand
17
+
18
+ action 'my-action' do
19
+ handler TestCommand
20
+ end
21
+ end
22
+ result = cli.execute_internal ['my-action'], output: :buffer
23
+ expect(result[:stdout]).to eq "test command executed\n"
24
+ end
25
+
26
+ it 'handles error appropriately for an action' do
27
+ cli = Cliqr.interface do
28
+ name 'my-command'
29
+ handler AlwaysErrorCommand
30
+
31
+ action 'my-action-1' do
32
+ handler AlwaysErrorCommand
33
+
34
+ action 'my-action-2' do
35
+ handler AlwaysErrorCommand
36
+ end
37
+ end
38
+ end
39
+ expect { cli.execute_internal %w(my-action-1 my-action-2) }.to raise_error(Cliqr::Error::CommandRuntimeError,
40
+ "command 'my-command my-action-1 my-action-2' failed\n\nCause: StandardError - I always throw an error\n")
41
+ end
42
+
43
+ it 'routes to a action with option values' do
44
+ cli = Cliqr.interface do
45
+ name 'my-command'
46
+ handler TestCommand
47
+
48
+ action 'my-action' do
49
+ handler TestCommand
50
+
51
+ option 'test-option'
52
+ end
53
+ end
54
+ result = cli.execute_internal %w(my-action --test-option some-value), output: :buffer
55
+ expect(result[:stdout]).to eq "test command executed\n"
56
+ end
57
+
58
+ it 'lets a action command get all option values' do
59
+ cli = Cliqr.interface do
60
+ name 'my-command'
61
+ handler TestCommand
62
+
63
+ action 'my-action' do
64
+ handler ActionReaderCommand
65
+
66
+ option 'test-option-1'
67
+ option 'test-option-2'
68
+ end
69
+ end
70
+ result = cli.execute_internal %w(my-action --test-option-1 some-value --test-option-2 v2), output: :buffer
71
+ expect(result[:stdout]).to eq <<-EOS
72
+ command = my-command my-action
73
+
74
+ executing action = my-action
75
+ [option] test-option-1 => some-value
76
+ [option] test-option-2 => v2
77
+ EOS
78
+ end
79
+
80
+ it 'lets a deeply nested action command get all option values' do
81
+ cli = Cliqr.interface do
82
+ name 'my-command'
83
+ handler ActionReaderCommand
84
+
85
+ action 'my-action-1' do
86
+ handler ActionReaderCommand
87
+
88
+ action 'my-action-2' do
89
+ handler ActionReaderCommand
90
+
91
+ action 'my-action-3' do
92
+ handler ActionReaderCommand
93
+
94
+ option 'test-option-1'
95
+ option 'test-option-2'
96
+ end
97
+ end
98
+ end
99
+ end
100
+ result = cli.execute_internal %w(my-action-1 --test-option-1 some-value my-action-2 --test-option-2 v2 my-action-3), output: :buffer
101
+ expect(result[:stdout]).to eq <<-EOS
102
+ command = my-command my-action-1 my-action-2 my-action-3
103
+
104
+ executing action = my-action-3
105
+ [option] test-option-1 => some-value
106
+ [option] test-option-2 => v2
107
+ EOS
108
+ end
109
+
110
+ it 'does not depend on the order of action and option' do
111
+ cli = Cliqr.interface do
112
+ name 'my-command'
113
+ handler ActionReaderCommand
114
+
115
+ action 'my-action' do
116
+ handler ActionReaderCommand
117
+
118
+ option 'test-option'
119
+ end
120
+ end
121
+ result = cli.execute_internal %w(--test-option some-value my-action), output: :buffer
122
+ expect(result[:stdout]).to eq <<-EOS
123
+ command = my-command my-action
124
+
125
+ executing action = my-action
126
+ [option] test-option => some-value
127
+ EOS
128
+ end
129
+
130
+ it 'lets a action command get single option value' do
131
+ cli = Cliqr.interface do
132
+ name 'my-command'
133
+ handler TestOptionReaderCommand
134
+
135
+ action 'my-action' do
136
+ handler TestOptionReaderCommand
137
+ option 'test-option'
138
+ end
139
+ end
140
+ result = cli.execute_internal %w(my-action --test-option some-value), output: :buffer
141
+ expect(result[:stdout]).to eq <<-EOS
142
+ some-value
143
+ EOS
144
+ end
145
+
146
+ it 'lets different action commands get their own option values' do
147
+ cli = Cliqr.interface do
148
+ name 'my-command'
149
+ handler TestOptionReaderCommand
150
+
151
+ action 'my-action' do
152
+ handler TestOptionReaderCommand
153
+ option 'test-option'
154
+ end
155
+
156
+ action 'another-action' do
157
+ handler TestOptionReaderCommand
158
+ option 'test-option'
159
+ end
160
+
161
+ action 'third-action' do
162
+ handler ActionReaderCommand
163
+ option 'third-option'
164
+ end
165
+ end
166
+ result = cli.execute_internal %w(my-action --test-option some-value), output: :buffer
167
+ expect(result[:stdout]).to eq <<-EOS
168
+ some-value
169
+ EOS
170
+
171
+ result = cli.execute_internal %w(another-action --test-option another), output: :buffer
172
+ expect(result[:stdout]).to eq <<-EOS
173
+ another
174
+ EOS
175
+
176
+ result = cli.execute_internal %w(third-action --third-option 3), output: :buffer
177
+ expect(result[:stdout]).to eq <<-EOS
178
+ command = my-command third-action
179
+
180
+ executing action = third-action
181
+ [option] third-option => 3
182
+ EOS
183
+ end
184
+
185
+ it 'allows action command to access argument list' do
186
+ cli = Cliqr.interface do
187
+ name 'my-command'
188
+ handler TestOptionCheckerCommand
189
+
190
+ action 'my-action' do
191
+ handler ArgumentReaderCommand
192
+ arguments :enable
193
+
194
+ option 'test-option'
195
+ end
196
+ end
197
+
198
+ result = cli.execute_internal %w(my-action value1 --test-option qwerty value2 value3), output: :buffer
199
+ expect(result[:stdout]).to eq <<-EOS
200
+ value1
201
+ value2
202
+ value3
203
+ EOS
204
+ end
205
+ end
@@ -10,48 +10,61 @@ require 'fixtures/option_reader_command'
10
10
  require 'fixtures/test_option_reader_command'
11
11
  require 'fixtures/test_option_checker_command'
12
12
  require 'fixtures/argument_reader_command'
13
+ require 'fixtures/test_option_type_checker_command'
14
+ require 'fixtures/csv_argument_operator'
13
15
 
14
16
  describe Cliqr::CLI::Executor do
15
17
  it 'returns code 0 for default command runner' do
16
- expect(Cliqr.command.new.execute).to eq(0)
18
+ expect(Cliqr.command.new.execute(nil)).to eq(0)
17
19
  end
18
20
 
19
- it 'routes base command with no arguments' do
21
+ it 'routes base command with no arguments to command class' do
20
22
  cli = Cliqr.interface do
21
- basename 'my-command'
23
+ name 'my-command'
22
24
  handler TestCommand
23
25
  end
24
- result = cli.execute [], output: :buffer
26
+ result = cli.execute_internal [], output: :buffer
27
+ expect(result[:stdout]).to eq "test command executed\n"
28
+ end
29
+
30
+ it 'routes base command with no arguments to command instance' do
31
+ cli = Cliqr.interface do
32
+ name 'my-command'
33
+ handler TestCommand.new
34
+ end
35
+ result = cli.execute_internal [], output: :buffer
25
36
  expect(result[:stdout]).to eq "test command executed\n"
26
37
  end
27
38
 
28
39
  it 'handles error appropriately' do
29
40
  cli = Cliqr.interface do
30
- basename 'my-command'
41
+ name 'my-command'
31
42
  handler AlwaysErrorCommand
32
43
  end
33
- expect { cli.execute [] }.to raise_error(Cliqr::Error::CommandRuntimeException)
44
+ expect { cli.execute_internal [] }.to(
45
+ raise_error(Cliqr::Error::CommandRuntimeError,
46
+ "command 'my-command' failed\n\nCause: StandardError - I always throw an error\n"))
34
47
  end
35
48
 
36
49
  it 'routes a command with option values' do
37
50
  cli = Cliqr.interface do
38
- basename 'my-command'
51
+ name 'my-command'
39
52
  handler TestCommand
40
53
 
41
54
  option 'test-option'
42
55
  end
43
- result = cli.execute %w(--test-option some-value), output: :buffer
56
+ result = cli.execute_internal %w(--test-option some-value), output: :buffer
44
57
  expect(result[:stdout]).to eq "test command executed\n"
45
58
  end
46
59
 
47
60
  it 'lets a command get all option values' do
48
61
  cli = Cliqr.interface do
49
- basename 'my-command'
62
+ name 'my-command'
50
63
  handler OptionReaderCommand
51
64
 
52
65
  option 'test-option'
53
66
  end
54
- result = cli.execute %w(--test-option some-value), output: :buffer
67
+ result = cli.execute_internal %w(--test-option some-value), output: :buffer
55
68
  expect(result[:stdout]).to eq <<-EOS
56
69
  my-command
57
70
 
@@ -61,12 +74,12 @@ my-command
61
74
 
62
75
  it 'lets a command get single option value' do
63
76
  cli = Cliqr.interface do
64
- basename 'my-command'
77
+ name 'my-command'
65
78
  handler TestOptionReaderCommand
66
79
 
67
80
  option 'test-option'
68
81
  end
69
- result = cli.execute %w(--test-option some-value), output: :buffer
82
+ result = cli.execute_internal %w(--test-option some-value), output: :buffer
70
83
  expect(result[:stdout]).to eq <<-EOS
71
84
  some-value
72
85
  EOS
@@ -74,7 +87,7 @@ some-value
74
87
 
75
88
  it 'handles executor error cause properly' do
76
89
  cli = Cliqr.interface do
77
- basename 'my-command'
90
+ name 'my-command'
78
91
  handler AlwaysErrorCommand
79
92
  end
80
93
  begin
@@ -87,7 +100,7 @@ some-value
87
100
 
88
101
  it 'allows command to check if an option exists or not' do
89
102
  cli = Cliqr.interface do
90
- basename 'my-command'
103
+ name 'my-command'
91
104
  description 'a command used to test cliqr'
92
105
  handler TestOptionCheckerCommand
93
106
 
@@ -96,7 +109,7 @@ some-value
96
109
  end
97
110
  end
98
111
 
99
- result = cli.execute %w(--test-option), output: :buffer
112
+ result = cli.execute_internal %w(--test-option), output: :buffer
100
113
  expect(result[:stdout]).to eq <<-EOS
101
114
  test-option is defined
102
115
  EOS
@@ -104,18 +117,393 @@ test-option is defined
104
117
 
105
118
  it 'allows command to access argument list' do
106
119
  cli = Cliqr.interface do
107
- basename 'my-command'
120
+ name 'my-command'
108
121
  handler ArgumentReaderCommand
109
122
  arguments :enable
110
123
 
111
124
  option 'test-option'
112
125
  end
113
126
 
114
- result = cli.execute %w(value1 --test-option qwerty value2 value3), output: :buffer
127
+ result = cli.execute_internal %w(value1 --test-option qwerty value2 value3), output: :buffer
115
128
  expect(result[:stdout]).to eq <<-EOS
116
129
  value1
117
130
  value2
118
131
  value3
119
132
  EOS
120
133
  end
134
+
135
+ it 'properly handles string type arguments' do
136
+ cli = Cliqr.interface do
137
+ name 'my-command'
138
+ handler TestOptionTypeCheckerCommand
139
+
140
+ option 'test-option'
141
+ end
142
+
143
+ result = cli.execute_internal %w(--test-option qwerty), output: :buffer
144
+ expect(result[:stdout]).to eq <<-EOS
145
+ test-option is of type String
146
+ EOS
147
+ end
148
+
149
+ it 'properly handles boolean type arguments' do
150
+ cli = Cliqr.interface do
151
+ name 'my-command'
152
+ handler TestOptionTypeCheckerCommand
153
+
154
+ option 'test-option' do
155
+ type :boolean
156
+ end
157
+ end
158
+
159
+ result = cli.execute_internal %w(--test-option), output: :buffer
160
+ expect(result[:stdout]).to eq <<-EOS
161
+ test-option is of type TrueClass
162
+ EOS
163
+
164
+ result = cli.execute_internal %w(--no-test-option), output: :buffer
165
+ expect(result[:stdout]).to eq <<-EOS
166
+ test-option is of type FalseClass
167
+ EOS
168
+ end
169
+
170
+ it 'properly handles integer type arguments' do
171
+ cli = Cliqr.interface do
172
+ name 'my-command'
173
+ handler TestOptionTypeCheckerCommand
174
+
175
+ option 'test-option' do
176
+ type :numeric
177
+ end
178
+ end
179
+
180
+ result = cli.execute_internal %w(--test-option 123), output: :buffer
181
+ expect(result[:stdout]).to eq <<-EOS
182
+ test-option is of type Fixnum
183
+ EOS
184
+ end
185
+
186
+ it 'allows custom argument operators' do
187
+ cli = Cliqr.interface do
188
+ name 'my-command'
189
+ handler TestOptionReaderCommand
190
+
191
+ option 'test-option' do
192
+ operator CSVArgumentOperator
193
+ end
194
+ end
195
+
196
+ result = cli.execute_internal %w(--test-option a,b,c,d), output: :buffer
197
+ expect(result[:stdout]).to eq <<-EOS
198
+ a
199
+ b
200
+ c
201
+ d
202
+ EOS
203
+ end
204
+
205
+ it 'allows inline executor' do
206
+ cli = Cliqr.interface do
207
+ name 'my-command'
208
+
209
+ handler do
210
+ puts "value = #{option('test-option').value}"
211
+ end
212
+
213
+ option 'test-option'
214
+ end
215
+
216
+ result = cli.execute_internal %w(--test-option executor-inline), output: :buffer
217
+ expect(result[:stdout]).to eq <<-EOS
218
+ value = executor-inline
219
+ EOS
220
+ end
221
+
222
+ it 'allows inline argument operator' do
223
+ cli = Cliqr.interface do
224
+ name 'my-command'
225
+ handler TestOptionReaderCommand
226
+
227
+ option 'test-option' do
228
+ operator do
229
+ "value = #{value}"
230
+ end
231
+ end
232
+ end
233
+
234
+ result = cli.execute_internal %w(--test-option operator-inline), output: :buffer
235
+ expect(result[:stdout]).to eq <<-EOS
236
+ value = operator-inline
237
+ EOS
238
+ end
239
+
240
+ it 'allows inline executor to access all context methods directly' do
241
+ cli = Cliqr.interface do
242
+ name 'my-command'
243
+
244
+ handler do
245
+ puts 'in my-command'
246
+ puts options.map { |option| "#{option.name} => #{option.value}" }
247
+ puts action?
248
+ puts option?('option-1')
249
+ puts option?('option-2')
250
+ puts option?('option-3')
251
+ end
252
+
253
+ option 'option-1'
254
+ option 'option-2'
255
+
256
+ action 'my-action' do
257
+ handler do
258
+ puts 'in my-action'
259
+ puts options.map { |option| "#{option.name} => #{option.value}" }
260
+ puts option('option-3').value
261
+ puts action?
262
+ puts option?('option-1')
263
+ puts option?('option-2')
264
+ puts option?('option-3')
265
+ end
266
+
267
+ option 'option-3'
268
+ end
269
+ end
270
+
271
+ result = cli.execute_internal %w(--option-1 val1 --option-2 val2), output: :buffer
272
+ expect(result[:stdout]).to eq <<-EOS
273
+ in my-command
274
+ option-1 => val1
275
+ option-2 => val2
276
+ false
277
+ true
278
+ true
279
+ false
280
+ EOS
281
+
282
+ result = cli.execute_internal %w(my-action --option-3 val3), output: :buffer
283
+ expect(result[:stdout]).to eq <<-EOS
284
+ in my-action
285
+ option-3 => val3
286
+ val3
287
+ true
288
+ false
289
+ false
290
+ true
291
+ EOS
292
+ end
293
+
294
+ it 'allows inline executor to get option value by calling method' do
295
+ cli = Cliqr.interface do
296
+ name 'my-command'
297
+
298
+ handler do
299
+ puts test_option
300
+ puts test_option?
301
+ puts second_option
302
+ end
303
+
304
+ option 'test_option'
305
+
306
+ option 'second_option' do
307
+ type :boolean
308
+ end
309
+ end
310
+
311
+ result = cli.execute_internal %w(--test_option executor-inline --second_option), output: :buffer
312
+ expect(result[:stdout]).to eq <<-EOS
313
+ executor-inline
314
+ true
315
+ true
316
+ EOS
317
+
318
+ result = cli.execute_internal [], output: :buffer
319
+ expect(result[:stdout]).to eq <<-EOS
320
+
321
+ false
322
+ false
323
+ EOS
324
+ end
325
+
326
+ it 'makes false the default for boolean options' do
327
+ cli = Cliqr.interface do
328
+ name 'my-command'
329
+
330
+ handler do
331
+ puts test_option
332
+ puts test_option?
333
+ end
334
+
335
+ option 'test_option' do
336
+ type :boolean
337
+ end
338
+ end
339
+
340
+ result = cli.execute_internal [], output: :buffer
341
+ expect(result[:stdout]).to eq <<-EOS
342
+ false
343
+ false
344
+ EOS
345
+ end
346
+
347
+ it 'can override default to true' do
348
+ cli = Cliqr.interface do
349
+ name 'my-command'
350
+
351
+ handler do
352
+ puts test_option
353
+ puts test_option?
354
+ end
355
+
356
+ option 'test_option' do
357
+ type :boolean
358
+ default true
359
+ end
360
+ end
361
+
362
+ result = cli.execute_internal [], output: :buffer
363
+ expect(result[:stdout]).to eq <<-EOS
364
+ true
365
+ false
366
+ EOS
367
+ end
368
+
369
+ it 'makes 0 as default for numerical' do
370
+ cli = Cliqr.interface do
371
+ name 'my-command'
372
+
373
+ handler do
374
+ puts test_option
375
+ puts test_option?
376
+ end
377
+
378
+ option 'test_option' do
379
+ type :numeric
380
+ end
381
+ end
382
+
383
+ result = cli.execute_internal [], output: :buffer
384
+ expect(result[:stdout]).to eq <<-EOS
385
+ 0
386
+ false
387
+ EOS
388
+ end
389
+
390
+ it 'allows non-zero default for numerical option' do
391
+ cli = Cliqr.interface do
392
+ name 'my-command'
393
+
394
+ handler do
395
+ puts test_option
396
+ puts test_option?
397
+ end
398
+
399
+ option :test_option do
400
+ type :numeric
401
+ default 123
402
+ end
403
+ end
404
+
405
+ result = cli.execute_internal [], output: :buffer
406
+ expect(result[:stdout]).to eq <<-EOS
407
+ 123
408
+ false
409
+ EOS
410
+ end
411
+
412
+ it 'can use version action on base command' do
413
+ cli = Cliqr.interface do
414
+ name 'my-command'
415
+ version '1234'
416
+ end
417
+
418
+ result = cli.execute_internal ['version'], output: :buffer
419
+ expect(result[:stdout]).to eq <<-EOS
420
+ 1234
421
+ EOS
422
+ end
423
+
424
+ it 'can get version by option on base command' do
425
+ cli = Cliqr.interface do
426
+ name 'my-command'
427
+ version '1234'
428
+ end
429
+
430
+ result = cli.execute_internal ['--version'], output: :buffer
431
+ expect(result[:stdout]).to eq <<-EOS
432
+ 1234
433
+ EOS
434
+
435
+ result = cli.execute_internal ['-v'], output: :buffer
436
+ expect(result[:stdout]).to eq <<-EOS
437
+ 1234
438
+ EOS
439
+ end
440
+
441
+ it 'can use version action on action command' do
442
+ cli = Cliqr.interface do
443
+ name 'my-command'
444
+
445
+ action :bla do
446
+ version '1234'
447
+ end
448
+ end
449
+
450
+ result = cli.execute_internal ['bla version'], output: :buffer
451
+ expect(result[:stdout]).to eq <<-EOS
452
+ 1234
453
+ EOS
454
+ end
455
+
456
+ describe 'error handling' do
457
+ it 'returns 0 if no error' do
458
+ cli = Cliqr.interface do
459
+ name 'my-command'
460
+ handler do
461
+ puts 'I am happy!'
462
+ end
463
+ end
464
+
465
+ old_stdout = $stdout
466
+ $stdout = old_stdout.is_a?(StringIO) ? old_stdout : StringIO.new('', 'w')
467
+ begin
468
+ expect(cli.execute).to(eq(0))
469
+ expect($stdout.string).to(eq("I am happy!\n"))
470
+ ensure
471
+ $stdout = old_stdout
472
+ end
473
+ end
474
+
475
+ it 'can handle errors in command handler' do
476
+ cli = Cliqr.interface do
477
+ name 'my-command'
478
+ handler do
479
+ fail StandardError, 'I am not a happy handler!'
480
+ end
481
+ end
482
+
483
+ old_stdout = $stdout
484
+ $stdout = old_stdout.is_a?(StringIO) ? old_stdout : StringIO.new('', 'w')
485
+ begin
486
+ expect(cli.execute(['abcd'])).to(eq(1))
487
+ expect($stdout.string).to(eq("command 'my-command' failed\n\nCause: StandardError - I am not a happy handler!\n"))
488
+ ensure
489
+ $stdout = old_stdout
490
+ end
491
+ end
492
+
493
+ it 'can handle errors in command arguments' do
494
+ cli = Cliqr.interface do
495
+ name 'my-command'
496
+ arguments :disable
497
+ end
498
+
499
+ old_stdout = $stdout
500
+ $stdout = old_stdout.is_a?(StringIO) ? old_stdout : StringIO.new('', 'w')
501
+ begin
502
+ expect(cli.execute(['abcd'])).to(eq(2))
503
+ expect($stdout.string).to(eq("invalid command argument \"abcd\"\n"))
504
+ ensure
505
+ $stdout = old_stdout
506
+ end
507
+ end
508
+ end
121
509
  end