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 +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.
|