command_kit 0.1.0 → 0.3.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.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +18 -3
- data/.rubocop.yml +141 -0
- data/ChangeLog.md +165 -0
- data/Gemfile +3 -0
- data/README.md +186 -118
- data/Rakefile +3 -2
- data/command_kit.gemspec +4 -4
- data/examples/command.rb +1 -1
- data/gemspec.yml +7 -0
- data/lib/command_kit/arguments/argument.rb +2 -2
- data/lib/command_kit/arguments.rb +36 -7
- data/lib/command_kit/colors.rb +702 -53
- data/lib/command_kit/command.rb +2 -3
- data/lib/command_kit/commands/auto_load.rb +8 -1
- data/lib/command_kit/commands/help.rb +3 -2
- data/lib/command_kit/commands/subcommand.rb +1 -1
- data/lib/command_kit/commands.rb +24 -9
- data/lib/command_kit/env/path.rb +1 -1
- data/lib/command_kit/file_utils.rb +46 -0
- data/lib/command_kit/help/man.rb +17 -33
- data/lib/command_kit/inflector.rb +47 -17
- data/lib/command_kit/interactive.rb +9 -0
- data/lib/command_kit/main.rb +7 -9
- data/lib/command_kit/man.rb +44 -0
- data/lib/command_kit/open_app.rb +69 -0
- data/lib/command_kit/options/option.rb +41 -27
- data/lib/command_kit/options/option_value.rb +3 -2
- data/lib/command_kit/options/parser.rb +17 -22
- data/lib/command_kit/options.rb +102 -14
- data/lib/command_kit/os/linux.rb +157 -0
- data/lib/command_kit/os.rb +159 -11
- data/lib/command_kit/package_manager.rb +200 -0
- data/lib/command_kit/pager.rb +46 -4
- data/lib/command_kit/printing/indent.rb +4 -4
- data/lib/command_kit/printing.rb +14 -3
- data/lib/command_kit/program_name.rb +9 -0
- data/lib/command_kit/sudo.rb +40 -0
- data/lib/command_kit/terminal.rb +5 -0
- data/lib/command_kit/version.rb +1 -1
- data/spec/arguments/argument_spec.rb +1 -1
- data/spec/arguments_spec.rb +84 -1
- data/spec/colors_spec.rb +357 -70
- data/spec/command_spec.rb +77 -6
- data/spec/commands/auto_load_spec.rb +33 -2
- data/spec/commands_spec.rb +101 -29
- data/spec/env/path_spec.rb +6 -0
- data/spec/exception_handler_spec.rb +1 -1
- data/spec/file_utils_spec.rb +59 -0
- data/spec/fixtures/template.erb +5 -0
- data/spec/help/man_spec.rb +54 -57
- data/spec/inflector_spec.rb +70 -8
- data/spec/man_spec.rb +46 -0
- data/spec/open_app_spec.rb +85 -0
- data/spec/options/option_spec.rb +38 -2
- data/spec/options/option_value_spec.rb +55 -0
- data/spec/options/parser_spec.rb +0 -10
- data/spec/options_spec.rb +328 -0
- data/spec/os/linux_spec.rb +164 -0
- data/spec/os_spec.rb +200 -13
- data/spec/package_manager_spec.rb +806 -0
- data/spec/pager_spec.rb +71 -6
- data/spec/printing/indent_spec.rb +7 -5
- data/spec/printing_spec.rb +23 -1
- data/spec/program_name_spec.rb +8 -0
- data/spec/sudo_spec.rb +51 -0
- data/spec/terminal_spec.rb +30 -0
- data/spec/usage_spec.rb +1 -1
- metadata +23 -4
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'command_kit/open_app'
|
3
|
+
|
4
|
+
describe CommandKit::OpenApp do
|
5
|
+
module TestOpenApp
|
6
|
+
class TestCommand
|
7
|
+
include CommandKit::OpenApp
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
let(:command_class) { TestOpenApp::TestCommand }
|
12
|
+
|
13
|
+
subject { command_class.new }
|
14
|
+
|
15
|
+
describe "#initialize" do
|
16
|
+
context "when the OS is macOS" do
|
17
|
+
subject { command_class.new(os: :macos) }
|
18
|
+
|
19
|
+
it "must set @open_command to \"open\"" do
|
20
|
+
expect(subject.instance_variable_get("@open_command")).to eq("open")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context "when the OS is Linux" do
|
25
|
+
subject { command_class.new(os: :linux) }
|
26
|
+
|
27
|
+
it "must set @open_command to \"xdg-open\"" do
|
28
|
+
expect(subject.instance_variable_get("@open_command")).to eq("xdg-open")
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context "when the OS is FreeBSD" do
|
33
|
+
subject { command_class.new(os: :freebsd) }
|
34
|
+
|
35
|
+
it "must set @open_command to \"xdg-open\"" do
|
36
|
+
expect(subject.instance_variable_get("@open_command")).to eq("xdg-open")
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context "when the OS is OpenBSD" do
|
41
|
+
subject { command_class.new(os: :openbsd) }
|
42
|
+
|
43
|
+
it "must set @open_command to \"xdg-open\"" do
|
44
|
+
expect(subject.instance_variable_get("@open_command")).to eq("xdg-open")
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context "when the OS is NetBSD" do
|
49
|
+
subject { command_class.new(os: :openbsd) }
|
50
|
+
|
51
|
+
it "must set @open_command to \"xdg-open\"" do
|
52
|
+
expect(subject.instance_variable_get("@open_command")).to eq("xdg-open")
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context "when the OS is Windows" do
|
57
|
+
subject { command_class.new(os: :windows) }
|
58
|
+
|
59
|
+
it "must set @open_command to \"start\"" do
|
60
|
+
expect(subject.instance_variable_get("@open_command")).to eq("start")
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe "#open_app_for" do
|
66
|
+
context "when @open_command is set" do
|
67
|
+
let(:file_or_uri) { "foo" }
|
68
|
+
let(:status) { true }
|
69
|
+
|
70
|
+
it "must execute the @open_command with the given URI or file" do
|
71
|
+
expect(subject).to receive(:system).with(subject.instance_variable_get("@open_command"),file_or_uri).and_return(status)
|
72
|
+
|
73
|
+
expect(subject.open_app_for(file_or_uri)).to be(status)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
context "when @open_command is not set" do
|
78
|
+
before do
|
79
|
+
subject.instance_variable_set("@open_command",nil)
|
80
|
+
end
|
81
|
+
|
82
|
+
it { expect(subject.open_app_for("foo")).to be(nil) }
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
data/spec/options/option_spec.rb
CHANGED
@@ -18,12 +18,12 @@ describe CommandKit::Options::Option do
|
|
18
18
|
end
|
19
19
|
|
20
20
|
subject do
|
21
|
-
described_class.new
|
21
|
+
described_class.new(name, short: short,
|
22
22
|
long: long,
|
23
23
|
equals: equals,
|
24
24
|
desc: desc,
|
25
25
|
value: value,
|
26
|
-
&block
|
26
|
+
&block)
|
27
27
|
end
|
28
28
|
|
29
29
|
describe "#initialize" do
|
@@ -145,6 +145,20 @@ describe CommandKit::Options::Option do
|
|
145
145
|
end
|
146
146
|
end
|
147
147
|
|
148
|
+
it "must default #category to nil" do
|
149
|
+
expect(subject.category).to be(nil)
|
150
|
+
end
|
151
|
+
|
152
|
+
context "when the category: keyword is given" do
|
153
|
+
let(:category) { 'Other Options' }
|
154
|
+
|
155
|
+
subject { described_class.new(name, desc: desc, category: category) }
|
156
|
+
|
157
|
+
it "must set #category" do
|
158
|
+
expect(subject.category).to eq(category)
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
148
162
|
context "when a block is given" do
|
149
163
|
subject { described_class.new(name, desc: desc, &block) }
|
150
164
|
|
@@ -293,5 +307,27 @@ describe CommandKit::Options::Option do
|
|
293
307
|
expect(subject.desc).to eq("#{desc} (Default: #{default})")
|
294
308
|
end
|
295
309
|
end
|
310
|
+
|
311
|
+
context "when #desc was initialized with an Array" do
|
312
|
+
let(:desc) do
|
313
|
+
[
|
314
|
+
'Line 1',
|
315
|
+
'Line 2'
|
316
|
+
]
|
317
|
+
end
|
318
|
+
|
319
|
+
it "must return the desc: value" do
|
320
|
+
expect(subject.desc).to eq(desc)
|
321
|
+
end
|
322
|
+
|
323
|
+
context "when #value has been initialized with a default value" do
|
324
|
+
let(:default) { "foo" }
|
325
|
+
let(:value) { {default: default} }
|
326
|
+
|
327
|
+
it "should append '(Default: ...)' to the desc Array" do
|
328
|
+
expect(subject.desc).to eq([*desc, "(Default: #{default})"])
|
329
|
+
end
|
330
|
+
end
|
331
|
+
end
|
296
332
|
end
|
297
333
|
end
|
@@ -7,6 +7,61 @@ describe CommandKit::Options::OptionValue do
|
|
7
7
|
let(:required) { true }
|
8
8
|
let(:default) { 1 }
|
9
9
|
|
10
|
+
describe ".default_usage" do
|
11
|
+
subject { described_class }
|
12
|
+
|
13
|
+
context "when given a Hash" do
|
14
|
+
let(:type) do
|
15
|
+
{'foo' => :foo, "bar" => :bar}
|
16
|
+
end
|
17
|
+
|
18
|
+
it "must join the Hash's keys with a '|' character" do
|
19
|
+
expect(subject.default_usage(type)).to eq(type.keys.join('|'))
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context "when given an Array" do
|
24
|
+
let(:type) do
|
25
|
+
['foo', 'bar', 'baz']
|
26
|
+
end
|
27
|
+
|
28
|
+
it "must join the Array's elements with a '|' character" do
|
29
|
+
expect(subject.default_usage(type)).to eq(type.join('|'))
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context "when given a Regexp" do
|
34
|
+
let(:type) { /[0-9a-f]+/ }
|
35
|
+
|
36
|
+
it "must return the Regexp's source" do
|
37
|
+
expect(subject.default_usage(type)).to eq(type.source)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context "when given a Class" do
|
42
|
+
module TestOptionValue
|
43
|
+
class FooBarBaz
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
let(:type) { TestOptionValue::FooBarBaz }
|
48
|
+
|
49
|
+
it "must return the uppercase and underscored version of it's name" do
|
50
|
+
expect(subject.default_usage(type)).to eq("FOO_BAR_BAZ")
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context "when given another kind of Object" do
|
55
|
+
let(:type) { Object.new }
|
56
|
+
|
57
|
+
it do
|
58
|
+
expect {
|
59
|
+
subject.default_usage(type)
|
60
|
+
}.to raise_error(TypeError,"unsupported option type: #{type.inspect}")
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
10
65
|
describe "#initialize" do
|
11
66
|
context "when the type: keyword is given" do
|
12
67
|
let(:type) { Integer }
|
data/spec/options/parser_spec.rb
CHANGED
@@ -34,16 +34,6 @@ describe CommandKit::Options::Parser do
|
|
34
34
|
expect(subject.option_parser.banner).to eq("Usage: #{subject.usage}")
|
35
35
|
end
|
36
36
|
|
37
|
-
it "must include a 'Options:' separator" do
|
38
|
-
expect(subject.option_parser.to_s).to include(
|
39
|
-
[
|
40
|
-
'',
|
41
|
-
'Options:',
|
42
|
-
''
|
43
|
-
].join($/)
|
44
|
-
)
|
45
|
-
end
|
46
|
-
|
47
37
|
it "must define a default --help option" do
|
48
38
|
expect(subject.option_parser.to_s).to include(
|
49
39
|
[
|
data/spec/options_spec.rb
CHANGED
@@ -133,5 +133,333 @@ describe CommandKit::Options do
|
|
133
133
|
it "must initialize #options" do
|
134
134
|
expect(subject.options).to eq({})
|
135
135
|
end
|
136
|
+
|
137
|
+
context "when options have default values" do
|
138
|
+
module TestOptions
|
139
|
+
class TestCommandWithDefaultValues
|
140
|
+
|
141
|
+
include CommandKit::Options
|
142
|
+
|
143
|
+
option :option1, value: {
|
144
|
+
required: true,
|
145
|
+
type: String
|
146
|
+
},
|
147
|
+
desc: 'Option 1'
|
148
|
+
|
149
|
+
option :option2, value: {
|
150
|
+
required: false,
|
151
|
+
type: String,
|
152
|
+
default: "foo"
|
153
|
+
},
|
154
|
+
desc: 'Option 2'
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
let(:command_class) { TestOptions::TestCommandWithDefaultValues }
|
159
|
+
|
160
|
+
it "must pre-populate #options with the default values" do
|
161
|
+
expect(subject.options).to_not have_key(:option1)
|
162
|
+
expect(subject.options).to have_key(:option2)
|
163
|
+
expect(subject.options[:option2]).to eq("foo")
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
module TestOptions
|
169
|
+
class TestCommandWithOptionsAndArguments
|
170
|
+
|
171
|
+
include CommandKit::Options
|
172
|
+
|
173
|
+
usage '[OPTIONS] ARG1 [ARG2]'
|
174
|
+
|
175
|
+
option :option1, short: '-a',
|
176
|
+
value: {
|
177
|
+
type: Integer,
|
178
|
+
default: 1
|
179
|
+
},
|
180
|
+
desc: "Option 1"
|
181
|
+
|
182
|
+
option :option2, short: '-b',
|
183
|
+
value: {
|
184
|
+
type: String,
|
185
|
+
usage: 'FILE'
|
186
|
+
},
|
187
|
+
desc: "Option 2"
|
188
|
+
|
189
|
+
argument :argument1, required: true,
|
190
|
+
usage: 'ARG1',
|
191
|
+
desc: "Argument 1"
|
192
|
+
|
193
|
+
argument :argument2, required: false,
|
194
|
+
usage: 'ARG2',
|
195
|
+
desc: "Argument 2"
|
196
|
+
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
describe "#option_parser" do
|
201
|
+
context "when an option does not accept a value" do
|
202
|
+
module TestOptions
|
203
|
+
class TestCommandWithOptionWithoutValue
|
204
|
+
|
205
|
+
include CommandKit::Options
|
206
|
+
|
207
|
+
option :opt, desc: "Option without a value"
|
208
|
+
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
let(:command_class) { TestOptions::TestCommandWithOptionWithoutValue }
|
213
|
+
|
214
|
+
context "but the option flag was not given" do
|
215
|
+
let(:argv) { [] }
|
216
|
+
|
217
|
+
before { subject.option_parser.parse(argv) }
|
218
|
+
|
219
|
+
it "must not populate #options with a value" do
|
220
|
+
expect(subject.options).to be_empty
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
context "and the option flag was given" do
|
225
|
+
let(:argv) { %w[--opt] }
|
226
|
+
|
227
|
+
before { subject.option_parser.parse(argv) }
|
228
|
+
|
229
|
+
it "must set a key in #options to true" do
|
230
|
+
expect(subject.options[:opt]).to be(true)
|
231
|
+
end
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
context "when an option requires a value" do
|
236
|
+
module TestOptions
|
237
|
+
class TestCommandWithOptionWithRequiredValue
|
238
|
+
|
239
|
+
include CommandKit::Options
|
240
|
+
|
241
|
+
option :opt, value: {
|
242
|
+
required: true,
|
243
|
+
type: String
|
244
|
+
},
|
245
|
+
desc: "Option without a value"
|
246
|
+
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
let(:command_class) do
|
251
|
+
TestOptions::TestCommandWithOptionWithRequiredValue
|
252
|
+
end
|
253
|
+
|
254
|
+
context "but the option flag was not given" do
|
255
|
+
let(:argv) { [] }
|
256
|
+
|
257
|
+
before { subject.option_parser.parse(argv) }
|
258
|
+
|
259
|
+
it "must not populate #options with a value" do
|
260
|
+
expect(subject.options).to be_empty
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
context "and the option flag and value were given" do
|
265
|
+
let(:value) { 'foo' }
|
266
|
+
let(:argv) { ['--opt', value] }
|
267
|
+
|
268
|
+
before { subject.option_parser.parse(argv) }
|
269
|
+
|
270
|
+
it "must set a key in #options to the value" do
|
271
|
+
expect(subject.options[:opt]).to eq(value)
|
272
|
+
end
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
276
|
+
context "when an option does not require a value" do
|
277
|
+
module TestOptions
|
278
|
+
class TestCommandWithOptionWithOptionalValue
|
279
|
+
|
280
|
+
include CommandKit::Options
|
281
|
+
|
282
|
+
option :opt, value: {
|
283
|
+
required: false,
|
284
|
+
type: String
|
285
|
+
},
|
286
|
+
desc: "Option without a value"
|
287
|
+
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
291
|
+
let(:command_class) do
|
292
|
+
TestOptions::TestCommandWithOptionWithOptionalValue
|
293
|
+
end
|
294
|
+
|
295
|
+
context "but the option flag was not given" do
|
296
|
+
let(:argv) { [] }
|
297
|
+
|
298
|
+
before { subject.option_parser.parse(argv) }
|
299
|
+
|
300
|
+
it "must not populate #options with a value" do
|
301
|
+
expect(subject.options).to be_empty
|
302
|
+
end
|
303
|
+
end
|
304
|
+
|
305
|
+
context "and the option flag and value were given" do
|
306
|
+
let(:value) { 'foo' }
|
307
|
+
let(:argv) { ['--opt', value] }
|
308
|
+
|
309
|
+
before { subject.option_parser.parse(argv) }
|
310
|
+
|
311
|
+
it "must set a key in #options to the value" do
|
312
|
+
expect(subject.options[:opt]).to eq(value)
|
313
|
+
end
|
314
|
+
end
|
315
|
+
|
316
|
+
context "and the option has a default value" do
|
317
|
+
module TestOptions
|
318
|
+
class TestCommandWithOptionWithOptionalValueAndDefaultValue
|
319
|
+
|
320
|
+
include CommandKit::Options
|
321
|
+
|
322
|
+
option :opt, value: {
|
323
|
+
required: false,
|
324
|
+
type: String,
|
325
|
+
default: "bar"
|
326
|
+
},
|
327
|
+
desc: "Option without a value"
|
328
|
+
|
329
|
+
end
|
330
|
+
end
|
331
|
+
|
332
|
+
let(:command_class) do
|
333
|
+
TestOptions::TestCommandWithOptionWithOptionalValueAndDefaultValue
|
334
|
+
end
|
335
|
+
|
336
|
+
context "but the option flag was not given" do
|
337
|
+
let(:argv) { [] }
|
338
|
+
|
339
|
+
before { subject.option_parser.parse(argv) }
|
340
|
+
|
341
|
+
it "must set a key in #options to the default value" do
|
342
|
+
expect(subject.options[:opt]).to eq("bar")
|
343
|
+
end
|
344
|
+
end
|
345
|
+
|
346
|
+
context "and the option flag and value were given" do
|
347
|
+
let(:value) { 'foo' }
|
348
|
+
let(:argv) { ['--opt', value] }
|
349
|
+
|
350
|
+
before { subject.option_parser.parse(argv) }
|
351
|
+
|
352
|
+
it "must set a key in #options to the value" do
|
353
|
+
expect(subject.options[:opt]).to eq(value)
|
354
|
+
end
|
355
|
+
end
|
356
|
+
|
357
|
+
context "and the option flag but not the value are given" do
|
358
|
+
let(:argv) { ['--opt'] }
|
359
|
+
|
360
|
+
before { subject.option_parser.parse(argv) }
|
361
|
+
|
362
|
+
it "must set a key in #options to nil" do
|
363
|
+
expect(subject.options).to have_key(:opt)
|
364
|
+
expect(subject.options[:opt]).to be(nil)
|
365
|
+
end
|
366
|
+
end
|
367
|
+
end
|
368
|
+
end
|
369
|
+
end
|
370
|
+
|
371
|
+
describe "#main" do
|
372
|
+
let(:command_class) { TestOptions::TestCommandWithOptionsAndArguments }
|
373
|
+
|
374
|
+
let(:argv) { %w[-a 42 -b foo.txt arg1 arg2] }
|
375
|
+
|
376
|
+
it "must parse options before validating the number of arguments" do
|
377
|
+
expect {
|
378
|
+
expect(subject.main(argv)).to eq(0)
|
379
|
+
}.to_not output.to_stderr
|
380
|
+
end
|
381
|
+
|
382
|
+
context "but the wrong number of arguments are given" do
|
383
|
+
let(:argv) { %w[-a 42 -b foo.txt] }
|
384
|
+
|
385
|
+
it "must still validate the number of arguments" do
|
386
|
+
expect {
|
387
|
+
expect(subject.main(argv)).to eq(1)
|
388
|
+
}.to output("#{subject.command_name}: insufficient number of arguments.#{$/}").to_stderr
|
389
|
+
end
|
390
|
+
end
|
391
|
+
end
|
392
|
+
|
393
|
+
describe "#help" do
|
394
|
+
let(:command_class) { TestOptions::TestCommandWithOptionsAndArguments }
|
395
|
+
|
396
|
+
let(:option1) { command_class.options[:option1] }
|
397
|
+
let(:option2) { command_class.options[:option2] }
|
398
|
+
let(:argument1) { command_class.arguments[:argument1] }
|
399
|
+
let(:argument2) { command_class.arguments[:argument2] }
|
400
|
+
|
401
|
+
it "must print the usage, options and arguments" do
|
402
|
+
expect { subject.help }.to output(
|
403
|
+
[
|
404
|
+
"Usage: #{subject.usage}",
|
405
|
+
'',
|
406
|
+
'Options:',
|
407
|
+
" #{option1.usage.join(', ').ljust(33 - 1)} #{option1.desc}",
|
408
|
+
" #{option2.usage.join(', ').ljust(33 - 1)} #{option2.desc}",
|
409
|
+
' -h, --help Print help information',
|
410
|
+
'',
|
411
|
+
"Arguments:",
|
412
|
+
" #{argument1.usage.ljust(33)}#{argument1.desc}",
|
413
|
+
" #{argument2.usage.ljust(33)}#{argument2.desc}",
|
414
|
+
''
|
415
|
+
].join($/)
|
416
|
+
).to_stdout
|
417
|
+
end
|
418
|
+
|
419
|
+
context "but when the options are have categories" do
|
420
|
+
module TestOptions
|
421
|
+
class TestCommandWithOptionsAndCategories
|
422
|
+
|
423
|
+
include CommandKit::Options
|
424
|
+
|
425
|
+
option :opt1, short: '-a',
|
426
|
+
desc: "Option 1"
|
427
|
+
option :opt2, short: '-b',
|
428
|
+
desc: "Option 2"
|
429
|
+
|
430
|
+
option :opt3, short: '-c',
|
431
|
+
desc: "Option 3",
|
432
|
+
category: 'Other Options'
|
433
|
+
option :opt4, short: '-d',
|
434
|
+
desc: "Option 4",
|
435
|
+
category: 'Other Options'
|
436
|
+
end
|
437
|
+
end
|
438
|
+
|
439
|
+
let(:command_class) { TestOptions::TestCommandWithOptionsAndCategories }
|
440
|
+
|
441
|
+
let(:option1) { command_class.options[:opt1] }
|
442
|
+
let(:option2) { command_class.options[:opt2] }
|
443
|
+
let(:option3) { command_class.options[:opt3] }
|
444
|
+
let(:option4) { command_class.options[:opt4] }
|
445
|
+
|
446
|
+
it "must group the options by category" do
|
447
|
+
expect { subject.help }.to output(
|
448
|
+
[
|
449
|
+
"Usage: #{subject.usage}",
|
450
|
+
'',
|
451
|
+
'Other Options:',
|
452
|
+
" #{option3.usage.join(', ').ljust(33 - 1)} #{option3.desc}",
|
453
|
+
" #{option4.usage.join(', ').ljust(33 - 1)} #{option4.desc}",
|
454
|
+
'',
|
455
|
+
'Options:',
|
456
|
+
" #{option1.usage.join(', ').ljust(33 - 1)} #{option1.desc}",
|
457
|
+
" #{option2.usage.join(', ').ljust(33 - 1)} #{option2.desc}",
|
458
|
+
' -h, --help Print help information',
|
459
|
+
''
|
460
|
+
].join($/)
|
461
|
+
).to_stdout
|
462
|
+
end
|
463
|
+
end
|
136
464
|
end
|
137
465
|
end
|