simple_scripting 0.12.0 → 0.12.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/simple_scripting/argv.rb +25 -9
- data/lib/simple_scripting/version.rb +1 -1
- data/simple_scripting.gemspec +1 -1
- data/spec/simple_scripting/argv_spec.rb +347 -337
- metadata +3 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 58e50fed7e20d97c590ebbab5466313a9a98393c7fbec6124131bcbf166af043
|
4
|
+
data.tar.gz: 7b16435d1eb0544743043b58f437a3d63407bac2ceb1595defa4ee557b6a7523
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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,
|
65
|
-
if raise_errors
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
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
|
|
data/simple_scripting.gemspec
CHANGED
@@ -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 = "
|
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
|
-
|
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
|
-
|
51
|
-
decoder_params.last.merge!(
|
52
|
-
arguments: ['--help', 'm_arg'],
|
53
|
-
auto_help: false
|
54
|
-
)
|
7
|
+
describe Argv do
|
55
8
|
|
56
|
-
|
9
|
+
let(:output_buffer) do
|
10
|
+
StringIO.new
|
11
|
+
end
|
57
12
|
|
58
|
-
|
59
|
-
help: true,
|
60
|
-
mandatory: 'm_arg',
|
61
|
-
}
|
13
|
+
describe 'Basic functionality' do
|
62
14
|
|
63
|
-
|
64
|
-
|
65
|
-
|
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
|
-
|
68
|
-
decoder_params.last.merge!(
|
69
|
-
arguments: ['--help'],
|
70
|
-
auto_help: false,
|
71
|
-
raise_errors: true,
|
72
|
-
)
|
28
|
+
context 'help' do
|
73
29
|
|
74
|
-
|
30
|
+
it 'should print help automatically by default' do
|
31
|
+
decoder_params.last[:arguments] = ['-h']
|
75
32
|
|
76
|
-
|
77
|
-
end
|
33
|
+
return_value = described_class.decode(*decoder_params)
|
78
34
|
|
79
|
-
|
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
|
-
|
82
|
-
|
45
|
+
This is the long help!
|
46
|
+
OUTPUT
|
83
47
|
|
84
|
-
|
48
|
+
expect(output_buffer.string).to eql(expected_output)
|
49
|
+
expect(return_value).to be(nil)
|
50
|
+
end
|
85
51
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
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
|
-
|
98
|
-
end
|
58
|
+
actual_result = described_class.decode(*decoder_params)
|
99
59
|
|
100
|
-
|
101
|
-
|
60
|
+
expected_result = {
|
61
|
+
help: true,
|
62
|
+
mandatory: 'm_arg',
|
63
|
+
}
|
102
64
|
|
103
|
-
|
65
|
+
expect(output_buffer.string).to eql('')
|
66
|
+
expect(actual_result).to eql(expected_result)
|
67
|
+
end
|
104
68
|
|
105
|
-
|
106
|
-
|
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
|
-
|
110
|
-
end
|
76
|
+
decoding = -> { described_class.decode(*decoder_params) }
|
111
77
|
|
112
|
-
|
78
|
+
expect(decoding).to raise_error(Argv::ArgumentError, "Missing mandatory argument(s)")
|
79
|
+
end
|
113
80
|
|
114
|
-
|
115
|
-
'[optional1]',
|
116
|
-
'[optional2]',
|
117
|
-
output: output_buffer,
|
118
|
-
]}
|
81
|
+
end # context 'help'
|
119
82
|
|
120
|
-
it "should
|
121
|
-
decoder_params.last[:arguments] = ['
|
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
|
-
|
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
|
133
|
-
decoder_params.last[:arguments] = ['
|
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
|
-
|
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
|
-
|
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
|
-
'
|
117
|
+
'[optional1]',
|
118
|
+
'[optional2]',
|
196
119
|
output: output_buffer,
|
197
|
-
arguments: ['varval1', 'varval2'],
|
198
120
|
]}
|
199
121
|
|
200
|
-
it "should
|
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
|
-
|
128
|
+
optional1: 'o_arg1',
|
205
129
|
}
|
206
130
|
|
207
131
|
expect(actual_result).to eql(expected_result)
|
208
132
|
end
|
209
133
|
|
210
|
-
|
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
|
-
|
226
|
-
|
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
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
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
|
-
|
243
|
-
|
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(
|
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 '
|
188
|
+
end # describe 'Basic functionality'
|
253
189
|
|
254
|
-
describe '
|
190
|
+
describe 'Varargs' do
|
255
191
|
|
256
|
-
|
257
|
-
'[*varargs]',
|
258
|
-
output: output_buffer,
|
259
|
-
]}
|
192
|
+
describe '(mandatory)' do
|
260
193
|
|
261
|
-
|
262
|
-
decoder_params.last[:arguments] = ['varval1', 'varval2']
|
194
|
+
context 'as only parameter' do
|
263
195
|
|
264
|
-
|
196
|
+
let(:decoder_params) {[
|
197
|
+
'*varargs',
|
198
|
+
output: output_buffer,
|
199
|
+
arguments: ['varval1', 'varval2'],
|
200
|
+
]}
|
265
201
|
|
266
|
-
|
267
|
-
|
268
|
-
}
|
202
|
+
it "should be decoded" do
|
203
|
+
actual_result = described_class.decode(*decoder_params)
|
269
204
|
|
270
|
-
|
271
|
-
|
205
|
+
expected_result = {
|
206
|
+
varargs: ['varval1', 'varval2'],
|
207
|
+
}
|
272
208
|
|
273
|
-
|
274
|
-
|
209
|
+
expect(actual_result).to eql(expected_result)
|
210
|
+
end
|
275
211
|
|
276
|
-
|
212
|
+
end
|
277
213
|
|
278
|
-
|
279
|
-
varargs: [],
|
280
|
-
}
|
214
|
+
context 'followed by varargs' do
|
281
215
|
|
282
|
-
|
283
|
-
|
216
|
+
let(:decoder_params) {[
|
217
|
+
'mandatory',
|
218
|
+
'*varargs',
|
219
|
+
output: output_buffer,
|
220
|
+
arguments: ['mandval', 'varval1', 'varval2']
|
221
|
+
]}
|
284
222
|
|
285
|
-
|
223
|
+
it "should be decoded" do
|
224
|
+
actual_result = described_class.decode(*decoder_params)
|
286
225
|
|
287
|
-
|
226
|
+
expected_result = {
|
227
|
+
mandatory: 'mandval',
|
228
|
+
varargs: ['varval1', 'varval2'],
|
229
|
+
}
|
288
230
|
|
289
|
-
|
231
|
+
expect(actual_result).to eql(expected_result)
|
232
|
+
end
|
290
233
|
|
291
|
-
|
234
|
+
end
|
292
235
|
|
293
|
-
|
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
|
-
|
305
|
-
|
238
|
+
let(:decoder_params) {[
|
239
|
+
'*varargs',
|
240
|
+
output: output_buffer,
|
241
|
+
arguments: [],
|
242
|
+
]}
|
306
243
|
|
307
|
-
|
244
|
+
it "should raise an error when they are not specified" do
|
245
|
+
decoder_params.last[:raise_errors] = true
|
308
246
|
|
309
|
-
|
247
|
+
decoding = -> { described_class.decode(*decoder_params) }
|
310
248
|
|
311
|
-
|
312
|
-
|
249
|
+
expect(decoding).to raise_error(Argv::ArgumentError, "Missing mandatory argument(s)")
|
250
|
+
end
|
313
251
|
|
314
|
-
|
252
|
+
end # context "error handling"
|
315
253
|
|
316
|
-
|
317
|
-
decoder_params.merge!(
|
318
|
-
arguments: ['pizza'],
|
319
|
-
raise_errors: true,
|
320
|
-
)
|
254
|
+
end # describe '(mandatory)'
|
321
255
|
|
322
|
-
|
256
|
+
describe '(optional)' do
|
323
257
|
|
324
|
-
|
325
|
-
|
258
|
+
let(:decoder_params) {[
|
259
|
+
'[*varargs]',
|
260
|
+
output: output_buffer,
|
261
|
+
]}
|
326
262
|
|
327
|
-
it "should
|
328
|
-
decoder_params.
|
329
|
-
arguments: [],
|
330
|
-
raise_errors: true,
|
331
|
-
)
|
263
|
+
it "should be decoded" do
|
264
|
+
decoder_params.last[:arguments] = ['varval1', 'varval2']
|
332
265
|
|
333
|
-
|
266
|
+
actual_result = described_class.decode(*decoder_params)
|
334
267
|
|
335
|
-
|
268
|
+
expected_result = {
|
269
|
+
varargs: ['varval1', 'varval2'],
|
270
|
+
}
|
271
|
+
|
272
|
+
expect(actual_result).to eql(expected_result)
|
336
273
|
end
|
337
274
|
|
338
|
-
|
275
|
+
it "should be allowed not to be specified" do
|
276
|
+
decoder_params.last[:arguments] = []
|
339
277
|
|
340
|
-
|
278
|
+
actual_result = described_class.decode(*decoder_params)
|
341
279
|
|
342
|
-
|
343
|
-
|
280
|
+
expected_result = {
|
281
|
+
varargs: [],
|
282
|
+
}
|
344
283
|
|
345
|
-
|
284
|
+
expect(actual_result).to eql(expected_result)
|
285
|
+
end
|
346
286
|
|
347
|
-
|
348
|
-
Valid commands:
|
287
|
+
end # describe '(optional)'
|
349
288
|
|
350
|
-
|
351
|
-
OUTPUT
|
289
|
+
end # describe 'Varargs'
|
352
290
|
|
353
|
-
|
354
|
-
end
|
291
|
+
describe 'Commands' do
|
355
292
|
|
356
|
-
|
357
|
-
decoder_params[:arguments] = ['command1', '-h']
|
293
|
+
describe 'regular case' do
|
358
294
|
|
359
|
-
|
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
|
-
|
362
|
-
|
363
|
-
-h, --help Help
|
306
|
+
it 'should be decoded' do
|
307
|
+
decoder_params[:arguments] = ['command1', 'value1']
|
364
308
|
|
365
|
-
|
366
|
-
OUTPUT
|
309
|
+
actual_result = described_class.decode(decoder_params)
|
367
310
|
|
368
|
-
|
311
|
+
expected_result = ['command1', arg1: 'value1']
|
312
|
+
|
313
|
+
expect(actual_result).to eql(expected_result)
|
369
314
|
end
|
370
315
|
|
371
|
-
context
|
316
|
+
context "error handling" do
|
372
317
|
|
373
|
-
it
|
318
|
+
it "should raise an error on invalid command" do
|
374
319
|
decoder_params.merge!(
|
375
|
-
arguments: ['
|
376
|
-
|
320
|
+
arguments: ['pizza'],
|
321
|
+
raise_errors: true,
|
377
322
|
)
|
378
323
|
|
379
|
-
|
324
|
+
decoding = -> { described_class.decode(decoder_params) }
|
380
325
|
|
381
|
-
|
382
|
-
|
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
|
332
|
+
it "should raise a specific error message on missing command" do
|
389
333
|
decoder_params.merge!(
|
390
|
-
arguments: [
|
391
|
-
|
334
|
+
arguments: [],
|
335
|
+
raise_errors: true,
|
392
336
|
)
|
393
337
|
|
394
|
-
|
338
|
+
decoding = -> { described_class.decode(decoder_params) }
|
395
339
|
|
396
|
-
|
397
|
-
|
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
|
-
|
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
|
-
|
364
|
+
it "should display the command given command's help" do
|
365
|
+
decoder_params[:arguments] = ['command1', '-h']
|
404
366
|
|
405
|
-
|
367
|
+
described_class.decode(decoder_params)
|
406
368
|
|
407
|
-
|
369
|
+
expected_output = <<~OUTPUT
|
370
|
+
Usage: rspec command1 [options] <arg1>
|
371
|
+
-h, --help Help
|
408
372
|
|
409
|
-
|
373
|
+
This is the long help.
|
374
|
+
OUTPUT
|
410
375
|
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
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
|
-
|
422
|
-
'arg2'
|
423
|
-
],
|
424
|
-
output: output_buffer
|
425
|
-
}}
|
432
|
+
output: output_buffer
|
433
|
+
}}
|
426
434
|
|
427
|
-
|
428
|
-
|
435
|
+
it 'should be decoded (two levels)' do
|
436
|
+
decoder_params[:arguments] = ['command1', 'nested1a', 'value1']
|
429
437
|
|
430
|
-
|
438
|
+
actual_result = described_class.decode(decoder_params)
|
431
439
|
|
432
|
-
|
440
|
+
expected_result = ['command1.nested1a', arg1: 'value1']
|
433
441
|
|
434
|
-
|
435
|
-
|
442
|
+
expect(actual_result).to eql(expected_result)
|
443
|
+
end
|
436
444
|
|
437
|
-
|
438
|
-
|
445
|
+
it 'should be decoded (one level)' do
|
446
|
+
decoder_params[:arguments] = ['command2', 'value2']
|
439
447
|
|
440
|
-
|
448
|
+
actual_result = described_class.decode(decoder_params)
|
441
449
|
|
442
|
-
|
450
|
+
expected_result = ['command2', arg2: 'value2']
|
443
451
|
|
444
|
-
|
445
|
-
|
452
|
+
expect(actual_result).to eql(expected_result)
|
453
|
+
end
|
446
454
|
|
447
|
-
|
448
|
-
|
455
|
+
it 'should print the command1 help' do
|
456
|
+
decoder_params[:arguments] = ['command1', '-h']
|
449
457
|
|
450
|
-
|
458
|
+
actual_result = described_class.decode(decoder_params)
|
451
459
|
|
452
|
-
|
453
|
-
|
460
|
+
expected_output = <<~OUTPUT
|
461
|
+
Valid commands:
|
454
462
|
|
455
|
-
|
456
|
-
|
463
|
+
nested1a, nested1b
|
464
|
+
OUTPUT
|
457
465
|
|
458
|
-
|
459
|
-
|
466
|
+
expect(output_buffer.string).to eql(expected_output)
|
467
|
+
end
|
460
468
|
|
461
|
-
|
462
|
-
|
469
|
+
it 'should print the nested1a help, and long help' do
|
470
|
+
decoder_params[:arguments] = ['command1', 'nested1a', '-h']
|
463
471
|
|
464
|
-
|
472
|
+
actual_result = described_class.decode(decoder_params)
|
465
473
|
|
466
|
-
|
467
|
-
|
468
|
-
|
474
|
+
expected_output = <<~OUTPUT
|
475
|
+
Usage: rspec command1 nested1a [options] <arg1>
|
476
|
+
-h, --help Help
|
469
477
|
|
470
|
-
|
471
|
-
|
478
|
+
nested1a long help.
|
479
|
+
OUTPUT
|
472
480
|
|
473
|
-
|
474
|
-
|
475
|
-
|
481
|
+
expect(output_buffer.string).to eql(expected_output)
|
482
|
+
end
|
483
|
+
end # describe 'Nested commands'
|
476
484
|
|
477
|
-
|
485
|
+
end # describe 'Commands'
|
478
486
|
|
479
|
-
|
480
|
-
|
481
|
-
|
487
|
+
# Special case.
|
488
|
+
#
|
489
|
+
describe 'No definitions given' do
|
482
490
|
|
483
|
-
|
484
|
-
|
485
|
-
|
491
|
+
let(:decoder_params) {{
|
492
|
+
output: output_buffer,
|
493
|
+
}}
|
486
494
|
|
487
|
-
|
488
|
-
|
489
|
-
|
495
|
+
it 'should avoid options being interpreted as definitions' do
|
496
|
+
decoder_params[:arguments] = ['pizza']
|
497
|
+
decoder_params[:raise_errors] = true
|
490
498
|
|
491
|
-
|
499
|
+
decoding = -> { described_class.decode(decoder_params) }
|
492
500
|
|
493
|
-
|
494
|
-
|
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
|
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.
|
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:
|
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
|
-
|
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.
|