command_kit 0.2.0 → 0.2.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.
data/spec/options_spec.rb CHANGED
@@ -133,5 +133,287 @@ 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
136
418
  end
137
419
  end
@@ -83,70 +83,80 @@ describe CommandKit::OS::Linux do
83
83
  end
84
84
 
85
85
  describe "#redhat_linux?" do
86
+ subject { command_class.new(linux_distro: linux_distro) }
87
+
86
88
  context "when #linux_distro is :redhat" do
87
- subject { command_class.new(linux_distro: :redhat) }
89
+ let(:linux_distro) { :redhat }
88
90
 
89
91
  it { expect(subject.redhat_linux?).to be(true) }
90
92
  end
91
93
 
92
94
  context "when #linux_distro is not :redhat" do
93
- subject { command_class.new(linux_distro: :debian) }
95
+ let(:linux_distro) { :debian }
94
96
 
95
97
  it { expect(subject.redhat_linux?).to be(false) }
96
98
  end
97
99
  end
98
100
 
99
101
  describe "#fedora_linux?" do
102
+ subject { command_class.new(linux_distro: linux_distro) }
103
+
100
104
  context "when #linux_distro is :fedora" do
101
- subject { command_class.new(linux_distro: :fedora) }
105
+ let(:linux_distro) { :fedora }
102
106
 
103
107
  it { expect(subject.fedora_linux?).to be(true) }
104
108
  end
105
109
 
106
110
  context "when #linux_distro is not :fedora" do
107
- subject { command_class.new(linux_distro: :debian) }
111
+ let(:linux_distro) { :debian }
108
112
 
109
113
  it { expect(subject.fedora_linux?).to be(false) }
110
114
  end
111
115
  end
112
116
 
113
117
  describe "#debian_linux?" do
118
+ subject { command_class.new(linux_distro: linux_distro) }
119
+
114
120
  context "when #linux_distro is :debian" do
115
- subject { command_class.new(linux_distro: :debian) }
121
+ let(:linux_distro) { :debian }
116
122
 
117
123
  it { expect(subject.debian_linux?).to be(true) }
118
124
  end
119
125
 
120
126
  context "when #linux_distro is not :fedora" do
121
- subject { command_class.new(linux_distro: :redhat) }
127
+ let(:linux_distro) { :redhat }
122
128
 
123
129
  it { expect(subject.debian_linux?).to be(false) }
124
130
  end
125
131
  end
126
132
 
127
133
  describe "#suse_linux?" do
134
+ subject { command_class.new(linux_distro: linux_distro) }
135
+
128
136
  context "when #linux_distro is :suse" do
129
- subject { command_class.new(linux_distro: :suse) }
137
+ let(:linux_distro) { :suse }
130
138
 
131
139
  it { expect(subject.suse_linux?).to be(true) }
132
140
  end
133
141
 
134
142
  context "when #linux_distro is not :suse" do
135
- subject { command_class.new(linux_distro: :debian) }
143
+ let(:linux_distro) { :debian }
136
144
 
137
145
  it { expect(subject.suse_linux?).to be(false) }
138
146
  end
139
147
  end
140
148
 
141
149
  describe "#arch_linux?" do
150
+ subject { command_class.new(linux_distro: linux_distro) }
151
+
142
152
  context "when #linux_distro is :arch" do
143
- subject { command_class.new(linux_distro: :arch) }
153
+ let(:linux_distro) { :arch }
144
154
 
145
155
  it { expect(subject.arch_linux?).to be(true) }
146
156
  end
147
157
 
148
158
  context "when #linux_distro is not :arch" do
149
- subject { command_class.new(linux_distro: :debian) }
159
+ let(:linux_distro) { :debian }
150
160
 
151
161
  it { expect(subject.arch_linux?).to be(false) }
152
162
  end
data/spec/pager_spec.rb CHANGED
@@ -170,7 +170,7 @@ describe CommandKit::Pager do
170
170
 
171
171
  context "and when given a String and additional arguments" do
172
172
  let(:command) { 'find' }
173
- let(:arguments) { %[. -name *.md] }
173
+ let(:arguments) { %w[. -name *.md] }
174
174
 
175
175
  let(:escaped_command) do
176
176
  Shellwords.shelljoin([command,*arguments])
@@ -192,7 +192,7 @@ describe CommandKit::Pager do
192
192
  end
193
193
 
194
194
  let(:command) { 'find' }
195
- let(:arguments) { %[. -name *.md] }
195
+ let(:arguments) { %w[. -name *.md] }
196
196
 
197
197
  it "must pass the command and any additional arguments to #system" do
198
198
  expect(subject).to receive(:system).with(command,*arguments)
@@ -12,14 +12,16 @@ describe CommandKit::Printing::Indent do
12
12
  subject { command_class.new }
13
13
 
14
14
  describe "#initialize" do
15
- it "must initialize @indent to 0" do
16
- expect(subject.instance_variable_get('@indent')).to eq(0)
15
+ it "must initialize #indent to 0" do
16
+ expect(subject.indent).to eq(0)
17
17
  end
18
18
 
19
19
  context "when the class has a superclass" do
20
20
  module TestIndent
21
21
  class TestSuperCommand
22
22
 
23
+ attr_reader :var
24
+
23
25
  def initialize(var: 'default')
24
26
  @var = var
25
27
  end
@@ -36,11 +38,11 @@ describe CommandKit::Printing::Indent do
36
38
  let(:command_class) { TestIndent::TestSubCommand }
37
39
 
38
40
  it "must initialize @indent to 0" do
39
- expect(subject.instance_variable_get('@indent')).to eq(0)
41
+ expect(subject.indent).to eq(0)
40
42
  end
41
43
 
42
44
  it "must call super()" do
43
- expect(subject.instance_variable_get('@var')).to eq('default')
45
+ expect(subject.var).to eq('default')
44
46
  end
45
47
 
46
48
  context "and additional keyword arguments are given" do
@@ -49,7 +51,7 @@ describe CommandKit::Printing::Indent do
49
51
  subject { command_class.new(var: var) }
50
52
 
51
53
  it "must call super() with the additional keyword arguments" do
52
- expect(subject.instance_variable_get('@var')).to eq(var)
54
+ expect(subject.var).to eq(var)
53
55
  end
54
56
  end
55
57
  end
@@ -1,5 +1,6 @@
1
1
  require 'spec_helper'
2
2
  require 'command_kit/printing'
3
+ require 'command_kit/command_name'
3
4
 
4
5
  require 'stringio'
5
6
 
@@ -34,11 +35,32 @@ describe CommandKit::Printing do
34
35
  describe "#print_error" do
35
36
  let(:message) { "oh no!" }
36
37
 
37
- it "must print a line to stderr" do
38
+ it "must print the error message to stderr" do
38
39
  expect {
39
40
  subject.print_error(message)
40
41
  }.to output("#{message}#{nl}").to_stderr
41
42
  end
43
+
44
+ context "and when CommandKit::CommandName is included" do
45
+ module TestPrinting
46
+ class TestCmdWithCommandName
47
+
48
+ include CommandKit::CommandName
49
+ include CommandKit::Printing
50
+
51
+ command_name 'foo'
52
+
53
+ end
54
+ end
55
+
56
+ let(:command_class) { TestPrinting::TestCmdWithCommandName }
57
+
58
+ it "must print the command_name and the error message" do
59
+ expect {
60
+ subject.print_error(message)
61
+ }.to output("#{subject.command_name}: #{message}#{nl}").to_stderr
62
+ end
63
+ end
42
64
  end
43
65
 
44
66
  describe "#print_exception" do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: command_kit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Postmodern
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-08-31 00:00:00.000000000 Z
11
+ date: 2021-11-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -153,6 +153,7 @@ metadata:
153
153
  source_code_uri: https://github.com/postmodern/command_kit.rb
154
154
  bug_tracker_uri: https://github.com/postmodern/command_kit.rb/issues
155
155
  changelog_uri: https://github.com/postmodern/command_kit.rb/blob/main/ChangeLog.md
156
+ rubygems_mfa_required: 'true'
156
157
  post_install_message:
157
158
  rdoc_options: []
158
159
  require_paths: