simple_scripting 0.12.0 → 0.12.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6dec0612c673d96b8e5f8299faff45642f8da72a615b2bb424f1b509361da3b3
4
- data.tar.gz: a8111721013e564624ee4fdd72e063c7eb9ee33d0a6154781509131afa3c77c5
3
+ metadata.gz: 58e50fed7e20d97c590ebbab5466313a9a98393c7fbec6124131bcbf166af043
4
+ data.tar.gz: 7b16435d1eb0544743043b58f437a3d63407bac2ceb1595defa4ee557b6a7523
5
5
  SHA512:
6
- metadata.gz: 78c6995cdce8e0f495c0ae1028972a507ba4b88c5102d9da421f0afbcb1e113e03757474227e775a4b8676b00eccd8b3e3b56ab91fefa3a858dd65e7127b504a
7
- data.tar.gz: a05c83cdce85612d6b488604eec6bbb182f3d06dd9a2bb2bd90a8fcce0dade13482cf442cf2eca548d708e7e8c28ecd48dfd26cc4eaaaa1947e67ce914a934c9
6
+ metadata.gz: '088ce9b31b82294a6b0ac5a238edfabaff919c71358e82deae14ef31f620c33f2f44af4de4f6a8e1996c7b1f3d9574d2ac5b88a85ff65745e3b5752b02146b07'
7
+ data.tar.gz: a94f016103580b122129bd85070030d21b74b2b6b348e129259f674cffec2cbb847a86fcde5d0a4cac267ce4c7d7bc2fdae1e5ff6b0259d1f3a351dbe4df96cd
@@ -7,9 +7,19 @@ module SimpleScripting
7
7
  # The fact that the following errors don't descend from OptionParser::InvalidOption is somewhat
8
8
  # annoying, however, there should be no practical problem.
9
9
  #
10
- class InvalidCommand < StandardError; end
11
10
  class ArgumentError < StandardError; end
12
11
 
12
+ class InvalidCommand < StandardError
13
+
14
+ attr_reader :valid_commands
15
+
16
+ def initialize(message, valid_commands)
17
+ super(message)
18
+ @valid_commands = valid_commands
19
+ end
20
+
21
+ end
22
+
13
23
  class ExitWithCommandsHelpPrinting < Struct.new(:commands_definition)
14
24
  # Note that :long_help is not used.
15
25
  def print_help(output, long_help)
@@ -61,12 +71,18 @@ module SimpleScripting
61
71
  exit_data.print_help(output, @long_help)
62
72
 
63
73
  nil # to be used with the 'decode(...) || exit' pattern
64
- rescue SimpleScripting::Argv::ArgumentError, SimpleScripting::Argv::InvalidCommand, OptionParser::InvalidOption => error
65
- if raise_errors
66
- raise
67
- else
68
- output.puts "Command error!: #{error.message}"
69
- end
74
+ rescue SimpleScripting::Argv::ArgumentError, OptionParser::InvalidOption => error
75
+ raise if raise_errors
76
+
77
+ output.puts "Command error!: #{error.message}"
78
+ rescue SimpleScripting::Argv::InvalidCommand => error
79
+ raise if raise_errors
80
+
81
+ output.puts <<~MESSAGE
82
+ Command error!: #{error.message}"
83
+
84
+ Valid commands: #{error.valid_commands.join(", ")}
85
+ MESSAGE
70
86
  ensure
71
87
  @long_help = nil
72
88
  end
@@ -129,13 +145,13 @@ module SimpleScripting
129
145
 
130
146
  command = command_for_check
131
147
 
132
- raise InvalidCommand.new("Missing command") if command.nil?
148
+ raise InvalidCommand.new("Missing command!", commands_definition.keys) if command.nil?
133
149
 
134
150
  command_params_definition = commands_definition[command]
135
151
 
136
152
  case command_params_definition
137
153
  when nil
138
- raise InvalidCommand.new("Invalid command: #{command}")
154
+ raise InvalidCommand.new("Invalid command: #{command}", commands_definition.keys)
139
155
  when Hash
140
156
  commands_stack << command
141
157
 
@@ -1,5 +1,5 @@
1
1
  module SimpleScripting
2
2
 
3
- VERSION = "0.12.0"
3
+ VERSION = "0.12.1"
4
4
 
5
5
  end
@@ -10,7 +10,7 @@ Gem::Specification.new do |s|
10
10
  s.platform = Gem::Platform::RUBY
11
11
  s.required_ruby_version = '>= 2.3.0'
12
12
  s.authors = ["Saverio Miroddi"]
13
- s.date = "2019-08-18"
13
+ s.date = "2020-02-13"
14
14
  s.email = ["saverio.pub2@gmail.com"]
15
15
  s.homepage = "https://github.com/saveriomiroddi/simple_scripting"
16
16
  s.summary = "Library for simplifying some typical scripting functionalities."
@@ -2,228 +2,143 @@ require_relative '../../lib/simple_scripting/argv.rb'
2
2
 
3
3
  require 'stringio'
4
4
 
5
- describe SimpleScripting::Argv do
6
-
7
- let(:output_buffer) do
8
- StringIO.new
9
- end
10
-
11
- describe 'Basic functionality' do
12
-
13
- let(:decoder_params) {[
14
- ['-a' ],
15
- ['-b', '"-b" description'],
16
- ['-c', '--c-switch VAL1,VAL2' ],
17
- ['-d', '--d-switch', '"-d" description'],
18
- ['-e', '--e-switch VALUE' ],
19
- ['-f', '--f-switch VALUE', '"-f" description'],
20
- 'mandatory',
21
- '[optional]',
22
- long_help: 'This is the long help!',
23
- output: output_buffer,
24
- ]}
25
-
26
- context 'help' do
27
-
28
- it 'should print help automatically by default' do
29
- decoder_params.last[:arguments] = ['-h']
30
-
31
- return_value = described_class.decode(*decoder_params)
32
-
33
- expected_output = <<~OUTPUT
34
- Usage: rspec [options] <mandatory> [<optional>]
35
- -a
36
- -b "-b" description
37
- -c, --c-switch VAL1,VAL2
38
- -d, --d-switch "-d" description
39
- -e, --e-switch VALUE
40
- -f, --f-switch VALUE "-f" description
41
- -h, --help Help
42
-
43
- This is the long help!
44
- OUTPUT
45
-
46
- expect(output_buffer.string).to eql(expected_output)
47
- expect(return_value).to be(nil)
48
- end
5
+ module SimpleScripting
49
6
 
50
- it 'should not interpret the --help argument, and not print the help, on auto_help: false' do
51
- decoder_params.last.merge!(
52
- arguments: ['--help', 'm_arg'],
53
- auto_help: false
54
- )
7
+ describe Argv do
55
8
 
56
- actual_result = described_class.decode(*decoder_params)
9
+ let(:output_buffer) do
10
+ StringIO.new
11
+ end
57
12
 
58
- expected_result = {
59
- help: true,
60
- mandatory: 'm_arg',
61
- }
13
+ describe 'Basic functionality' do
62
14
 
63
- expect(output_buffer.string).to eql('')
64
- expect(actual_result).to eql(expected_result)
65
- end
15
+ let(:decoder_params) {[
16
+ ['-a' ],
17
+ ['-b', '"-b" description'],
18
+ ['-c', '--c-switch VAL1,VAL2' ],
19
+ ['-d', '--d-switch', '"-d" description'],
20
+ ['-e', '--e-switch VALUE' ],
21
+ ['-f', '--f-switch VALUE', '"-f" description'],
22
+ 'mandatory',
23
+ '[optional]',
24
+ long_help: 'This is the long help!',
25
+ output: output_buffer,
26
+ ]}
66
27
 
67
- it "should check all the options/arguments when --help is passed, raising an error when they're not correct" do
68
- decoder_params.last.merge!(
69
- arguments: ['--help'],
70
- auto_help: false,
71
- raise_errors: true,
72
- )
28
+ context 'help' do
73
29
 
74
- decoding = -> { described_class.decode(*decoder_params) }
30
+ it 'should print help automatically by default' do
31
+ decoder_params.last[:arguments] = ['-h']
75
32
 
76
- expect(decoding).to raise_error(SimpleScripting::Argv::ArgumentError, "Missing mandatory argument(s)")
77
- end
33
+ return_value = described_class.decode(*decoder_params)
78
34
 
79
- end # context 'help'
35
+ expected_output = <<~OUTPUT
36
+ Usage: rspec [options] <mandatory> [<optional>]
37
+ -a
38
+ -b "-b" description
39
+ -c, --c-switch VAL1,VAL2
40
+ -d, --d-switch "-d" description
41
+ -e, --e-switch VALUE
42
+ -f, --f-switch VALUE "-f" description
43
+ -h, --help Help
80
44
 
81
- it "should implement basic switches, with conversion, and arguments (all set)" do
82
- decoder_params.last[:arguments] = ['-a', '-b', '-c', 'a,b,c', '-d', '-ev_swt', '-fv_swt', 'm_arg', 'o_arg']
45
+ This is the long help!
46
+ OUTPUT
83
47
 
84
- actual_result = described_class.decode(*decoder_params)
48
+ expect(output_buffer.string).to eql(expected_output)
49
+ expect(return_value).to be(nil)
50
+ end
85
51
 
86
- expected_result = {
87
- a: true,
88
- b: true,
89
- c_switch: %w(a b c),
90
- d_switch: true,
91
- e_switch: 'v_swt',
92
- f_switch: 'v_swt',
93
- mandatory: 'm_arg',
94
- optional: 'o_arg',
95
- }
52
+ it 'should not interpret the --help argument, and not print the help, on auto_help: false' do
53
+ decoder_params.last.merge!(
54
+ arguments: ['--help', 'm_arg'],
55
+ auto_help: false
56
+ )
96
57
 
97
- expect(actual_result).to eql(expected_result)
98
- end
58
+ actual_result = described_class.decode(*decoder_params)
99
59
 
100
- it "should implement basic switches and arguments (no optional argument)" do
101
- decoder_params.last[:arguments] = ['m_arg']
60
+ expected_result = {
61
+ help: true,
62
+ mandatory: 'm_arg',
63
+ }
102
64
 
103
- actual_result = described_class.decode(*decoder_params)
65
+ expect(output_buffer.string).to eql('')
66
+ expect(actual_result).to eql(expected_result)
67
+ end
104
68
 
105
- expected_result = {
106
- mandatory: 'm_arg',
107
- }
69
+ it "should check all the options/arguments when --help is passed, raising an error when they're not correct" do
70
+ decoder_params.last.merge!(
71
+ arguments: ['--help'],
72
+ auto_help: false,
73
+ raise_errors: true,
74
+ )
108
75
 
109
- expect(actual_result).to eql(expected_result)
110
- end
76
+ decoding = -> { described_class.decode(*decoder_params) }
111
77
 
112
- context "multiple optional arguments" do
78
+ expect(decoding).to raise_error(Argv::ArgumentError, "Missing mandatory argument(s)")
79
+ end
113
80
 
114
- let(:decoder_params) {[
115
- '[optional1]',
116
- '[optional2]',
117
- output: output_buffer,
118
- ]}
81
+ end # context 'help'
119
82
 
120
- it "should correctly decode a single argument passed" do
121
- decoder_params.last[:arguments] = ['o_arg1']
83
+ it "should implement basic switches, with conversion, and arguments (all set)" do
84
+ decoder_params.last[:arguments] = ['-a', '-b', '-c', 'a,b,c', '-d', '-ev_swt', '-fv_swt', 'm_arg', 'o_arg']
122
85
 
123
86
  actual_result = described_class.decode(*decoder_params)
124
87
 
125
88
  expected_result = {
126
- optional1: 'o_arg1',
89
+ a: true,
90
+ b: true,
91
+ c_switch: %w(a b c),
92
+ d_switch: true,
93
+ e_switch: 'v_swt',
94
+ f_switch: 'v_swt',
95
+ mandatory: 'm_arg',
96
+ optional: 'o_arg',
127
97
  }
128
98
 
129
99
  expect(actual_result).to eql(expected_result)
130
100
  end
131
101
 
132
- it "should correctly decode all arguments passed" do
133
- decoder_params.last[:arguments] = ['o_arg1', 'o_arg2']
102
+ it "should implement basic switches and arguments (no optional argument)" do
103
+ decoder_params.last[:arguments] = ['m_arg']
134
104
 
135
105
  actual_result = described_class.decode(*decoder_params)
136
106
 
137
107
  expected_result = {
138
- optional1: 'o_arg1',
139
- optional2: 'o_arg2',
108
+ mandatory: 'm_arg',
140
109
  }
141
110
 
142
111
  expect(actual_result).to eql(expected_result)
143
112
  end
144
113
 
145
- end
146
-
147
- context "error handling" do
148
-
149
- # All the other UTs use error raising, for convenience.
150
- it "should print the error, with a previx, by default, instead of raising an error" do
151
- decoder_params.last[:arguments] = []
152
-
153
- actual_result = described_class.decode(*decoder_params)
154
-
155
- # Returning nil is an important specification, as it's part of the Argv protocol of doing
156
- # so in case of problem/exit.
157
- expect(actual_result).to be(nil)
158
-
159
- expect(output_buffer.string).to eql("Command error!: Missing mandatory argument(s)\n")
160
- end
161
-
162
- it "should raise an error when mandatory arguments are missing" do
163
- decoder_params.last.merge!(
164
- arguments: [],
165
- raise_errors: true,
166
- )
167
-
168
- decoding = -> { described_class.decode(*decoder_params) }
169
-
170
- expect(decoding).to raise_error(SimpleScripting::Argv::ArgumentError, "Missing mandatory argument(s)")
171
- end
172
-
173
- it "should raise an error when there are too many arguments" do
174
- decoder_params.last.merge!(
175
- arguments: ['arg1', 'arg2', 'excessive_arg'],
176
- raise_errors: true,
177
- )
178
-
179
- decoding = -> { described_class.decode(*decoder_params) }
180
-
181
- expect(decoding).to raise_error(SimpleScripting::Argv::ArgumentError, "Too many arguments")
182
- end
183
-
184
- end # context "error handling"
185
-
186
- end # describe 'Basic functionality'
187
-
188
- describe 'Varargs' do
189
-
190
- describe '(mandatory)' do
191
-
192
- context 'as only parameter' do
114
+ context "multiple optional arguments" do
193
115
 
194
116
  let(:decoder_params) {[
195
- '*varargs',
117
+ '[optional1]',
118
+ '[optional2]',
196
119
  output: output_buffer,
197
- arguments: ['varval1', 'varval2'],
198
120
  ]}
199
121
 
200
- it "should be decoded" do
122
+ it "should correctly decode a single argument passed" do
123
+ decoder_params.last[:arguments] = ['o_arg1']
124
+
201
125
  actual_result = described_class.decode(*decoder_params)
202
126
 
203
127
  expected_result = {
204
- varargs: ['varval1', 'varval2'],
128
+ optional1: 'o_arg1',
205
129
  }
206
130
 
207
131
  expect(actual_result).to eql(expected_result)
208
132
  end
209
133
 
210
- end
211
-
212
- context 'followed by varargs' do
213
-
214
- let(:decoder_params) {[
215
- 'mandatory',
216
- '*varargs',
217
- output: output_buffer,
218
- arguments: ['mandval', 'varval1', 'varval2']
219
- ]}
134
+ it "should correctly decode all arguments passed" do
135
+ decoder_params.last[:arguments] = ['o_arg1', 'o_arg2']
220
136
 
221
- it "should be decoded" do
222
137
  actual_result = described_class.decode(*decoder_params)
223
138
 
224
139
  expected_result = {
225
- mandatory: 'mandval',
226
- varargs: ['varval1', 'varval2'],
140
+ optional1: 'o_arg1',
141
+ optional2: 'o_arg2',
227
142
  }
228
143
 
229
144
  expect(actual_result).to eql(expected_result)
@@ -233,266 +148,361 @@ describe SimpleScripting::Argv do
233
148
 
234
149
  context "error handling" do
235
150
 
236
- let(:decoder_params) {[
237
- '*varargs',
238
- output: output_buffer,
239
- arguments: [],
240
- ]}
151
+ # All the other UTs use error raising, for convenience.
152
+ it "should print the error, with a previx, by default, instead of raising an error" do
153
+ decoder_params.last[:arguments] = []
154
+
155
+ actual_result = described_class.decode(*decoder_params)
241
156
 
242
- it "should raise an error when they are not specified" do
243
- decoder_params.last[:raise_errors] = true
157
+ # Returning nil is an important specification, as it's part of the Argv protocol of doing
158
+ # so in case of problem/exit.
159
+ expect(actual_result).to be(nil)
160
+
161
+ expect(output_buffer.string).to eql("Command error!: Missing mandatory argument(s)\n")
162
+ end
163
+
164
+ it "should raise an error when mandatory arguments are missing" do
165
+ decoder_params.last.merge!(
166
+ arguments: [],
167
+ raise_errors: true,
168
+ )
244
169
 
245
170
  decoding = -> { described_class.decode(*decoder_params) }
246
171
 
247
- expect(decoding).to raise_error(SimpleScripting::Argv::ArgumentError, "Missing mandatory argument(s)")
172
+ expect(decoding).to raise_error(Argv::ArgumentError, "Missing mandatory argument(s)")
173
+ end
174
+
175
+ it "should raise an error when there are too many arguments" do
176
+ decoder_params.last.merge!(
177
+ arguments: ['arg1', 'arg2', 'excessive_arg'],
178
+ raise_errors: true,
179
+ )
180
+
181
+ decoding = -> { described_class.decode(*decoder_params) }
182
+
183
+ expect(decoding).to raise_error(Argv::ArgumentError, "Too many arguments")
248
184
  end
249
185
 
250
186
  end # context "error handling"
251
187
 
252
- end # describe '(mandatory)'
188
+ end # describe 'Basic functionality'
253
189
 
254
- describe '(optional)' do
190
+ describe 'Varargs' do
255
191
 
256
- let(:decoder_params) {[
257
- '[*varargs]',
258
- output: output_buffer,
259
- ]}
192
+ describe '(mandatory)' do
260
193
 
261
- it "should be decoded" do
262
- decoder_params.last[:arguments] = ['varval1', 'varval2']
194
+ context 'as only parameter' do
263
195
 
264
- actual_result = described_class.decode(*decoder_params)
196
+ let(:decoder_params) {[
197
+ '*varargs',
198
+ output: output_buffer,
199
+ arguments: ['varval1', 'varval2'],
200
+ ]}
265
201
 
266
- expected_result = {
267
- varargs: ['varval1', 'varval2'],
268
- }
202
+ it "should be decoded" do
203
+ actual_result = described_class.decode(*decoder_params)
269
204
 
270
- expect(actual_result).to eql(expected_result)
271
- end
205
+ expected_result = {
206
+ varargs: ['varval1', 'varval2'],
207
+ }
272
208
 
273
- it "should be allowed not to be specified" do
274
- decoder_params.last[:arguments] = []
209
+ expect(actual_result).to eql(expected_result)
210
+ end
275
211
 
276
- actual_result = described_class.decode(*decoder_params)
212
+ end
277
213
 
278
- expected_result = {
279
- varargs: [],
280
- }
214
+ context 'followed by varargs' do
281
215
 
282
- expect(actual_result).to eql(expected_result)
283
- end
216
+ let(:decoder_params) {[
217
+ 'mandatory',
218
+ '*varargs',
219
+ output: output_buffer,
220
+ arguments: ['mandval', 'varval1', 'varval2']
221
+ ]}
284
222
 
285
- end # describe '(optional)'
223
+ it "should be decoded" do
224
+ actual_result = described_class.decode(*decoder_params)
286
225
 
287
- end # describe 'Varargs'
226
+ expected_result = {
227
+ mandatory: 'mandval',
228
+ varargs: ['varval1', 'varval2'],
229
+ }
288
230
 
289
- describe 'Commands' do
231
+ expect(actual_result).to eql(expected_result)
232
+ end
290
233
 
291
- describe 'regular case' do
234
+ end
292
235
 
293
- let(:decoder_params) {{
294
- 'command1' => [
295
- 'arg1',
296
- long_help: 'This is the long help.'
297
- ],
298
- 'command2' => [
299
- 'arg2'
300
- ],
301
- output: output_buffer,
302
- }}
236
+ context "error handling" do
303
237
 
304
- it 'should be decoded' do
305
- decoder_params[:arguments] = ['command1', 'value1']
238
+ let(:decoder_params) {[
239
+ '*varargs',
240
+ output: output_buffer,
241
+ arguments: [],
242
+ ]}
306
243
 
307
- actual_result = described_class.decode(decoder_params)
244
+ it "should raise an error when they are not specified" do
245
+ decoder_params.last[:raise_errors] = true
308
246
 
309
- expected_result = ['command1', arg1: 'value1']
247
+ decoding = -> { described_class.decode(*decoder_params) }
310
248
 
311
- expect(actual_result).to eql(expected_result)
312
- end
249
+ expect(decoding).to raise_error(Argv::ArgumentError, "Missing mandatory argument(s)")
250
+ end
313
251
 
314
- context "error handling" do
252
+ end # context "error handling"
315
253
 
316
- it "should raise an error on invalid command" do
317
- decoder_params.merge!(
318
- arguments: ['pizza'],
319
- raise_errors: true,
320
- )
254
+ end # describe '(mandatory)'
321
255
 
322
- decoding = -> { described_class.decode(decoder_params) }
256
+ describe '(optional)' do
323
257
 
324
- expect(decoding).to raise_error(SimpleScripting::Argv::InvalidCommand, "Invalid command: pizza")
325
- end
258
+ let(:decoder_params) {[
259
+ '[*varargs]',
260
+ output: output_buffer,
261
+ ]}
326
262
 
327
- it "should raise a specific error message on missing command" do
328
- decoder_params.merge!(
329
- arguments: [],
330
- raise_errors: true,
331
- )
263
+ it "should be decoded" do
264
+ decoder_params.last[:arguments] = ['varval1', 'varval2']
332
265
 
333
- decoding = -> { described_class.decode(decoder_params) }
266
+ actual_result = described_class.decode(*decoder_params)
334
267
 
335
- expect(decoding).to raise_error(SimpleScripting::Argv::InvalidCommand, "Missing command")
268
+ expected_result = {
269
+ varargs: ['varval1', 'varval2'],
270
+ }
271
+
272
+ expect(actual_result).to eql(expected_result)
336
273
  end
337
274
 
338
- end # context "error handling"
275
+ it "should be allowed not to be specified" do
276
+ decoder_params.last[:arguments] = []
339
277
 
340
- context "help" do
278
+ actual_result = described_class.decode(*decoder_params)
341
279
 
342
- it 'should implement the commands help' do
343
- decoder_params[:arguments] = ['-h']
280
+ expected_result = {
281
+ varargs: [],
282
+ }
344
283
 
345
- described_class.decode(decoder_params)
284
+ expect(actual_result).to eql(expected_result)
285
+ end
346
286
 
347
- expected_output = <<~OUTPUT
348
- Valid commands:
287
+ end # describe '(optional)'
349
288
 
350
- command1, command2
351
- OUTPUT
289
+ end # describe 'Varargs'
352
290
 
353
- expect(output_buffer.string).to eql(expected_output)
354
- end
291
+ describe 'Commands' do
355
292
 
356
- it "should display the command given command's help" do
357
- decoder_params[:arguments] = ['command1', '-h']
293
+ describe 'regular case' do
358
294
 
359
- described_class.decode(decoder_params)
295
+ let(:decoder_params) {{
296
+ 'command1' => [
297
+ 'arg1',
298
+ long_help: 'This is the long help.'
299
+ ],
300
+ 'command2' => [
301
+ 'arg2'
302
+ ],
303
+ output: output_buffer,
304
+ }}
360
305
 
361
- expected_output = <<~OUTPUT
362
- Usage: rspec command1 [options] <arg1>
363
- -h, --help Help
306
+ it 'should be decoded' do
307
+ decoder_params[:arguments] = ['command1', 'value1']
364
308
 
365
- This is the long help.
366
- OUTPUT
309
+ actual_result = described_class.decode(decoder_params)
367
310
 
368
- expect(output_buffer.string).to eql(expected_output)
311
+ expected_result = ['command1', arg1: 'value1']
312
+
313
+ expect(actual_result).to eql(expected_result)
369
314
  end
370
315
 
371
- context 'auto_help: false' do
316
+ context "error handling" do
372
317
 
373
- it 'should not interpret the --help argument, and not print the help' do
318
+ it "should raise an error on invalid command" do
374
319
  decoder_params.merge!(
375
- arguments: ['-h'],
376
- auto_help: false,
320
+ arguments: ['pizza'],
321
+ raise_errors: true,
377
322
  )
378
323
 
379
- actual_result = described_class.decode(decoder_params)
324
+ decoding = -> { described_class.decode(decoder_params) }
380
325
 
381
- expected_result = {
382
- help: true,
383
- }
384
-
385
- expect(actual_result).to eql(expected_result)
326
+ expect(decoding).to raise_error(an_instance_of(Argv::InvalidCommand).and having_attributes(
327
+ message: "Invalid command: pizza",
328
+ valid_commands: ["command1", "command2"],
329
+ ))
386
330
  end
387
331
 
388
- it 'should ignore and not return all the other arguments' do
332
+ it "should raise a specific error message on missing command" do
389
333
  decoder_params.merge!(
390
- arguments: ['-h', 'pizza'],
391
- auto_help: false,
334
+ arguments: [],
335
+ raise_errors: true,
392
336
  )
393
337
 
394
- actual_result = described_class.decode(decoder_params)
338
+ decoding = -> { described_class.decode(decoder_params) }
395
339
 
396
- expected_result = {
397
- help: true,
398
- }
340
+ expect(decoding).to raise_error(an_instance_of(Argv::InvalidCommand).and having_attributes(
341
+ message: "Missing command!",
342
+ valid_commands: ["command1", "command2"],
343
+ ))
344
+ end
399
345
 
400
- expect(actual_result).to eql(expected_result)
346
+ end # context "error handling"
347
+
348
+ context "help" do
349
+
350
+ it 'should implement the commands help' do
351
+ decoder_params[:arguments] = ['-h']
352
+
353
+ described_class.decode(decoder_params)
354
+
355
+ expected_output = <<~OUTPUT
356
+ Valid commands:
357
+
358
+ command1, command2
359
+ OUTPUT
360
+
361
+ expect(output_buffer.string).to eql(expected_output)
401
362
  end
402
363
 
403
- end # context 'auto_help: false'
364
+ it "should display the command given command's help" do
365
+ decoder_params[:arguments] = ['command1', '-h']
404
366
 
405
- end # context 'help'
367
+ described_class.decode(decoder_params)
406
368
 
407
- end # describe 'regular case'
369
+ expected_output = <<~OUTPUT
370
+ Usage: rspec command1 [options] <arg1>
371
+ -h, --help Help
408
372
 
409
- describe 'Nested commands' do
373
+ This is the long help.
374
+ OUTPUT
410
375
 
411
- let(:decoder_params) {{
412
- 'command1' => {
413
- 'nested1a' => [
414
- 'arg1',
415
- long_help: 'nested1a long help.'
416
- ],
417
- 'nested1b' => [
418
- 'arg1b'
376
+ expect(output_buffer.string).to eql(expected_output)
377
+ end
378
+
379
+ context 'auto_help: false' do
380
+
381
+ it 'should not interpret the --help argument, and not print the help' do
382
+ decoder_params.merge!(
383
+ arguments: ['-h'],
384
+ auto_help: false,
385
+ )
386
+
387
+ actual_result = described_class.decode(decoder_params)
388
+
389
+ expected_result = {
390
+ help: true,
391
+ }
392
+
393
+ expect(actual_result).to eql(expected_result)
394
+ end
395
+
396
+ it 'should ignore and not return all the other arguments' do
397
+ decoder_params.merge!(
398
+ arguments: ['-h', 'pizza'],
399
+ auto_help: false,
400
+ )
401
+
402
+ actual_result = described_class.decode(decoder_params)
403
+
404
+ expected_result = {
405
+ help: true,
406
+ }
407
+
408
+ expect(actual_result).to eql(expected_result)
409
+ end
410
+
411
+ end # context 'auto_help: false'
412
+
413
+ end # context 'help'
414
+
415
+ end # describe 'regular case'
416
+
417
+ describe 'Nested commands' do
418
+
419
+ let(:decoder_params) {{
420
+ 'command1' => {
421
+ 'nested1a' => [
422
+ 'arg1',
423
+ long_help: 'nested1a long help.'
424
+ ],
425
+ 'nested1b' => [
426
+ 'arg1b'
427
+ ],
428
+ },
429
+ 'command2' => [
430
+ 'arg2'
419
431
  ],
420
- },
421
- 'command2' => [
422
- 'arg2'
423
- ],
424
- output: output_buffer
425
- }}
432
+ output: output_buffer
433
+ }}
426
434
 
427
- it 'should be decoded (two levels)' do
428
- decoder_params[:arguments] = ['command1', 'nested1a', 'value1']
435
+ it 'should be decoded (two levels)' do
436
+ decoder_params[:arguments] = ['command1', 'nested1a', 'value1']
429
437
 
430
- actual_result = described_class.decode(decoder_params)
438
+ actual_result = described_class.decode(decoder_params)
431
439
 
432
- expected_result = ['command1.nested1a', arg1: 'value1']
440
+ expected_result = ['command1.nested1a', arg1: 'value1']
433
441
 
434
- expect(actual_result).to eql(expected_result)
435
- end
442
+ expect(actual_result).to eql(expected_result)
443
+ end
436
444
 
437
- it 'should be decoded (one level)' do
438
- decoder_params[:arguments] = ['command2', 'value2']
445
+ it 'should be decoded (one level)' do
446
+ decoder_params[:arguments] = ['command2', 'value2']
439
447
 
440
- actual_result = described_class.decode(decoder_params)
448
+ actual_result = described_class.decode(decoder_params)
441
449
 
442
- expected_result = ['command2', arg2: 'value2']
450
+ expected_result = ['command2', arg2: 'value2']
443
451
 
444
- expect(actual_result).to eql(expected_result)
445
- end
452
+ expect(actual_result).to eql(expected_result)
453
+ end
446
454
 
447
- it 'should print the command1 help' do
448
- decoder_params[:arguments] = ['command1', '-h']
455
+ it 'should print the command1 help' do
456
+ decoder_params[:arguments] = ['command1', '-h']
449
457
 
450
- actual_result = described_class.decode(decoder_params)
458
+ actual_result = described_class.decode(decoder_params)
451
459
 
452
- expected_output = <<~OUTPUT
453
- Valid commands:
460
+ expected_output = <<~OUTPUT
461
+ Valid commands:
454
462
 
455
- nested1a, nested1b
456
- OUTPUT
463
+ nested1a, nested1b
464
+ OUTPUT
457
465
 
458
- expect(output_buffer.string).to eql(expected_output)
459
- end
466
+ expect(output_buffer.string).to eql(expected_output)
467
+ end
460
468
 
461
- it 'should print the nested1a help, and long help' do
462
- decoder_params[:arguments] = ['command1', 'nested1a', '-h']
469
+ it 'should print the nested1a help, and long help' do
470
+ decoder_params[:arguments] = ['command1', 'nested1a', '-h']
463
471
 
464
- actual_result = described_class.decode(decoder_params)
472
+ actual_result = described_class.decode(decoder_params)
465
473
 
466
- expected_output = <<~OUTPUT
467
- Usage: rspec command1 nested1a [options] <arg1>
468
- -h, --help Help
474
+ expected_output = <<~OUTPUT
475
+ Usage: rspec command1 nested1a [options] <arg1>
476
+ -h, --help Help
469
477
 
470
- nested1a long help.
471
- OUTPUT
478
+ nested1a long help.
479
+ OUTPUT
472
480
 
473
- expect(output_buffer.string).to eql(expected_output)
474
- end
475
- end # describe 'Nested commands'
481
+ expect(output_buffer.string).to eql(expected_output)
482
+ end
483
+ end # describe 'Nested commands'
476
484
 
477
- end # describe 'Commands'
485
+ end # describe 'Commands'
478
486
 
479
- # Special case.
480
- #
481
- describe 'No definitions given' do
487
+ # Special case.
488
+ #
489
+ describe 'No definitions given' do
482
490
 
483
- let(:decoder_params) {{
484
- output: output_buffer,
485
- }}
491
+ let(:decoder_params) {{
492
+ output: output_buffer,
493
+ }}
486
494
 
487
- it 'should avoid options being interpreted as definitions' do
488
- decoder_params[:arguments] = ['pizza']
489
- decoder_params[:raise_errors] = true
495
+ it 'should avoid options being interpreted as definitions' do
496
+ decoder_params[:arguments] = ['pizza']
497
+ decoder_params[:raise_errors] = true
490
498
 
491
- decoding = -> { described_class.decode(decoder_params) }
499
+ decoding = -> { described_class.decode(decoder_params) }
492
500
 
493
- expect(decoding).to raise_error(SimpleScripting::Argv::ArgumentError, "Too many arguments")
494
- end
501
+ expect(decoding).to raise_error(Argv::ArgumentError, "Too many arguments")
502
+ end
503
+
504
+ end # describe 'No definitions given'
495
505
 
496
- end # describe 'No definitions given'
506
+ end # describe Argv
497
507
 
498
- end
508
+ end # module SimpleScripting
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: simple_scripting
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.12.0
4
+ version: 0.12.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Saverio Miroddi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-08-18 00:00:00.000000000 Z
11
+ date: 2020-02-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: parseconfig
@@ -99,8 +99,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
99
99
  - !ruby/object:Gem::Version
100
100
  version: '0'
101
101
  requirements: []
102
- rubyforge_project:
103
- rubygems_version: 2.7.8
102
+ rubygems_version: 3.0.6
104
103
  signing_key:
105
104
  specification_version: 4
106
105
  summary: Library for simplifying some typical scripting functionalities.