command_kit 0.4.1 → 0.5.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.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/ChangeLog.md +6 -0
  3. data/README.md +3 -0
  4. data/command_kit.gemspec +7 -2
  5. data/lib/command_kit/completion/install.rb +276 -0
  6. data/lib/command_kit/env/prefix.rb +41 -0
  7. data/lib/command_kit/env/shell.rb +58 -0
  8. data/lib/command_kit/version.rb +1 -1
  9. metadata +4 -64
  10. data/spec/arguments/argument_spec.rb +0 -133
  11. data/spec/arguments/argument_value_spec.rb +0 -66
  12. data/spec/arguments_spec.rb +0 -279
  13. data/spec/bug_report_spec.rb +0 -266
  14. data/spec/colors_spec.rb +0 -771
  15. data/spec/command_kit_spec.rb +0 -8
  16. data/spec/command_name_spec.rb +0 -130
  17. data/spec/command_spec.rb +0 -123
  18. data/spec/commands/auto_load/subcommand_spec.rb +0 -82
  19. data/spec/commands/auto_load_spec.rb +0 -159
  20. data/spec/commands/auto_require_spec.rb +0 -142
  21. data/spec/commands/fixtures/test_auto_load/cli/commands/test1.rb +0 -10
  22. data/spec/commands/fixtures/test_auto_load/cli/commands/test2.rb +0 -10
  23. data/spec/commands/fixtures/test_auto_require/lib/test_auto_require/cli/commands/test1.rb +0 -10
  24. data/spec/commands/help_spec.rb +0 -66
  25. data/spec/commands/parent_command_spec.rb +0 -40
  26. data/spec/commands/subcommand_spec.rb +0 -99
  27. data/spec/commands_spec.rb +0 -865
  28. data/spec/description_spec.rb +0 -179
  29. data/spec/edit_spec.rb +0 -72
  30. data/spec/env/home_spec.rb +0 -46
  31. data/spec/env/path_spec.rb +0 -84
  32. data/spec/env_spec.rb +0 -123
  33. data/spec/examples_spec.rb +0 -211
  34. data/spec/exception_handler_spec.rb +0 -103
  35. data/spec/file_utils_spec.rb +0 -59
  36. data/spec/fixtures/template.erb +0 -5
  37. data/spec/help/man_spec.rb +0 -345
  38. data/spec/help_spec.rb +0 -94
  39. data/spec/inflector_spec.rb +0 -166
  40. data/spec/interactive_spec.rb +0 -415
  41. data/spec/main_spec.rb +0 -179
  42. data/spec/man_spec.rb +0 -46
  43. data/spec/open_app_spec.rb +0 -85
  44. data/spec/options/option_spec.rb +0 -343
  45. data/spec/options/option_value_spec.rb +0 -171
  46. data/spec/options/parser_spec.rb +0 -274
  47. data/spec/options/quiet_spec.rb +0 -51
  48. data/spec/options/verbose_spec.rb +0 -51
  49. data/spec/options/version_spec.rb +0 -146
  50. data/spec/options_spec.rb +0 -465
  51. data/spec/os/linux_spec.rb +0 -164
  52. data/spec/os_spec.rb +0 -233
  53. data/spec/package_manager_spec.rb +0 -806
  54. data/spec/pager_spec.rb +0 -217
  55. data/spec/printing/fields_spec.rb +0 -167
  56. data/spec/printing/indent_spec.rb +0 -132
  57. data/spec/printing/lists_spec.rb +0 -99
  58. data/spec/printing/tables/border_style.rb +0 -43
  59. data/spec/printing/tables/cell_builer_spec.rb +0 -135
  60. data/spec/printing/tables/row_builder_spec.rb +0 -165
  61. data/spec/printing/tables/style_spec.rb +0 -377
  62. data/spec/printing/tables/table_builder_spec.rb +0 -252
  63. data/spec/printing/tables/table_formatter_spec.rb +0 -1190
  64. data/spec/printing/tables_spec.rb +0 -1069
  65. data/spec/printing_spec.rb +0 -106
  66. data/spec/program_name_spec.rb +0 -70
  67. data/spec/spec_helper.rb +0 -3
  68. data/spec/stdio_spec.rb +0 -264
  69. data/spec/sudo_spec.rb +0 -51
  70. data/spec/terminal_spec.rb +0 -231
  71. data/spec/usage_spec.rb +0 -237
  72. data/spec/xdg_spec.rb +0 -191
@@ -1,166 +0,0 @@
1
- require 'spec_helper'
2
- require 'command_kit/inflector'
3
-
4
- describe CommandKit::Inflector do
5
- describe ".demodularize" do
6
- context "when given a single class or module name" do
7
- let(:name) { 'Foo' }
8
-
9
- it "must return the class or module name unchanged" do
10
- expect(subject.demodularize(name)).to eq(name)
11
- end
12
- end
13
-
14
- context "when given a class or module name with a leading namespace" do
15
- let(:namespace) { 'Foo::Bar' }
16
- let(:constant) { "Baz" }
17
- let(:name) { "#{namespace}::#{constant}" }
18
-
19
- it "must return the constant name, without the leading namespace" do
20
- expect(subject.demodularize(name)).to eq(constant)
21
- end
22
- end
23
-
24
- context "when given a non-String" do
25
- it "must convert it to a String" do
26
- expect(subject.demodularize(:"Foo::Bar")).to eq('Bar')
27
- end
28
- end
29
- end
30
-
31
- ascii = (0..255).map(&:chr)
32
- alpha = ('a'..'z').to_a + ('A'..'Z').to_a
33
- numeric = ('0'..'9').to_a
34
-
35
- describe ".underscore" do
36
- it "must convert CamelCase to camel_case" do
37
- expect(subject.underscore('CamelCase')).to eq('camel_case')
38
- end
39
-
40
- it "must convert camelCase to camel_case" do
41
- expect(subject.underscore('camelCase')).to eq('camel_case')
42
- end
43
-
44
- it "must convert Camelcase to camelcase" do
45
- expect(subject.underscore('Camelcase')).to eq('camelcase')
46
- end
47
-
48
- it "must convert CAMELCASE to camelcase" do
49
- expect(subject.underscore('CAMELCASE')).to eq('camelcase')
50
- end
51
-
52
- it "must convert CAMELCase to camel_case" do
53
- expect(subject.underscore('CAMELCase')).to eq('camel_case')
54
- end
55
-
56
- it "must convert CamelCASE to camel_case" do
57
- expect(subject.underscore('CAMELCase')).to eq('camel_case')
58
- end
59
-
60
- it "must convert FooBARBaz to foo_bar_baz" do
61
- expect(subject.underscore('FooBARBaz')).to eq('foo_bar_baz')
62
- end
63
-
64
- it "must convert foo_bar_baz to foo_bar_baz" do
65
- expect(subject.underscore('foo_bar_baz')).to eq('foo_bar_baz')
66
- end
67
-
68
- it "must convert foo___bar___baz to foo___bar___baz" do
69
- expect(subject.underscore('foo___bar___baz')).to eq('foo___bar___baz')
70
- end
71
-
72
- it "must convert foo-bar-baz to foo_bar_baz" do
73
- expect(subject.underscore('foo-bar-baz')).to eq('foo_bar_baz')
74
- end
75
-
76
- it "must convert foo---bar---baz to foo___bar___baz" do
77
- expect(subject.underscore('foo---bar---baz')).to eq('foo___bar___baz')
78
- end
79
-
80
- it "must convert foo_BAR_baz to foo_bar_baz" do
81
- expect(subject.underscore('foo_BAR_baz')).to eq('foo_bar_baz')
82
- end
83
-
84
- it "must convert foo-BAR-baz to foo_bar_baz" do
85
- expect(subject.underscore('foo-BAR-baz')).to eq('foo_bar_baz')
86
- end
87
-
88
- context "when given a non-String" do
89
- it "must convert it to a String" do
90
- expect(subject.underscore(:CamelCase)).to eq('camel_case')
91
- end
92
- end
93
-
94
- separators = %w[_ -]
95
-
96
- (ascii - alpha - numeric - separators).each do |char|
97
- context "when the given String contains a #{char.inspect} character" do
98
- let(:string) { "Foo#{char}Bar" }
99
-
100
- it do
101
- expect {
102
- subject.underscore(string)
103
- }.to raise_error(ArgumentError,"cannot convert string to underscored: #{string.inspect}")
104
- end
105
- end
106
- end
107
- end
108
-
109
- describe ".dasherize" do
110
- it "must replace all underscores with dashes" do
111
- expect(subject.dasherize("foo_bar")).to eq('foo-bar')
112
- end
113
-
114
- context "when given a non-String" do
115
- it "must convert it to a String" do
116
- expect(subject.dasherize(:foo_bar)).to eq('foo-bar')
117
- end
118
- end
119
- end
120
-
121
- describe ".camelize" do
122
- context "when given a string with no underscores" do
123
- it "must capitalize the string" do
124
- expect(subject.camelize('foo')).to eq('Foo')
125
- end
126
- end
127
-
128
- context "when given a string with underscores" do
129
- it "must capitalize each word and remove all underscores" do
130
- expect(subject.camelize('foo_bar')).to eq('FooBar')
131
- end
132
- end
133
-
134
- context "when given a string with dashes" do
135
- it "must capitalize each word and remove all dashes" do
136
- expect(subject.camelize('foo-bar')).to eq('FooBar')
137
- end
138
- end
139
-
140
- context "when given a string containing '/' characters" do
141
- it "must replace the '/' characters with '::' strings" do
142
- expect(subject.camelize('foo_bar/baz_quox')).to eq('FooBar::BazQuox')
143
- end
144
- end
145
-
146
- context "when given a non-String" do
147
- it "must convert it to a String" do
148
- expect(subject.camelize(:foo_bar)).to eq('FooBar')
149
- end
150
- end
151
-
152
- separators = %w[_ - /]
153
-
154
- (ascii - alpha - numeric - separators).each do |char|
155
- context "when the given String contains a #{char.inspect} character" do
156
- let(:string) { "foo#{char}bar" }
157
-
158
- it do
159
- expect {
160
- subject.camelize(string)
161
- }.to raise_error(ArgumentError,"cannot convert string to CamelCase: #{string.inspect}")
162
- end
163
- end
164
- end
165
- end
166
- end
@@ -1,415 +0,0 @@
1
- require 'spec_helper'
2
- require 'command_kit/interactive'
3
-
4
- describe CommandKit::Interactive do
5
- module TestInteractive
6
- class TestCommand
7
- include CommandKit::Interactive
8
- end
9
- end
10
-
11
- let(:command_class) { TestInteractive::TestCommand }
12
-
13
- describe "#included" do
14
- subject { command_class }
15
-
16
- it { expect(subject).to include(CommandKit::Stdio) }
17
- end
18
-
19
- let(:stdout) { StringIO.new }
20
- let(:stdin) { StringIO.new }
21
- let(:stderr) { StringIO.new }
22
-
23
- subject do
24
- command_class.new(stdout: stdout, stdin: stdin, stderr: stderr)
25
- end
26
-
27
- let(:prompt) { 'Prompt' }
28
-
29
- describe "#ask" do
30
- let(:input) { 'foo' }
31
-
32
- it "must print a prompt, read input, and return the input" do
33
- expect(stdout).to receive(:print).with("#{prompt}: ")
34
- expect(stdin).to receive(:gets).and_return(input)
35
-
36
- expect(subject.ask(prompt)).to eq(input)
37
- end
38
-
39
- it "must accept empty user input by default" do
40
- expect(stdin).to receive(:gets).and_return("")
41
-
42
- expect(subject.ask(prompt)).to eq("")
43
- end
44
-
45
- context "when Ctrl^C is entered" do
46
- it "must return \"\"" do
47
- expect(stdin).to receive(:gets).and_return(nil) # simulate Ctrl^C
48
-
49
- expect(subject.ask(prompt)).to eq("")
50
- end
51
- end
52
-
53
- context "when default: is given" do
54
- let(:default) { 'bar' }
55
-
56
- it "must include the default: value in the prompt" do
57
- expect(stdout).to receive(:print).with("#{prompt} [#{default}]: ")
58
- expect(stdin).to receive(:gets).and_return(input)
59
-
60
- expect(subject.ask(prompt, default: default)).to eq(input)
61
- end
62
-
63
- context "and non-empty user input is given" do
64
- it "must return the non-empty user input" do
65
- expect(stdin).to receive(:gets).and_return(input)
66
-
67
- expect(subject.ask(prompt, default: default)).to eq(input)
68
- end
69
- end
70
-
71
- context "and empty user input is given" do
72
- it "must return the default value" do
73
- expect(stdin).to receive(:gets).and_return("")
74
-
75
- expect(subject.ask(prompt, default: default)).to eq(default)
76
- end
77
- end
78
- end
79
-
80
- context "when required: is given" do
81
- context "and empty user input is given" do
82
- it "must ask for input again, until non-empty input is given" do
83
- expect(stdin).to receive(:gets).and_return("")
84
- expect(stdin).to receive(:gets).and_return("")
85
- expect(stdin).to receive(:gets).and_return(input)
86
-
87
- expect(subject.ask(prompt, required: true)).to eq(input)
88
- end
89
- end
90
-
91
- context "and non-empty user input is given" do
92
- it "must return the non-empty user input" do
93
- expect(stdin).to receive(:gets).and_return(input)
94
-
95
- expect(subject.ask(prompt, required: true)).to eq(input)
96
- end
97
- end
98
- end
99
- end
100
-
101
- describe "#ask_yes_or_no" do
102
- let(:input) { 'Y' }
103
-
104
- it "must print a prompt indicating Y/N, and then accept input" do
105
- expect(stdout).to receive(:print).with("#{prompt} (Y/N): ")
106
- expect(stdin).to receive(:gets).and_return(input)
107
-
108
- subject.ask_yes_or_no(prompt)
109
- end
110
-
111
- context "when 'Y' is entered" do
112
- let(:input) { 'Y' }
113
-
114
- it "must return true" do
115
- expect(stdin).to receive(:gets).and_return(input)
116
-
117
- expect(subject.ask_yes_or_no(prompt)).to eq(true)
118
- end
119
- end
120
-
121
- context "when 'y' is entered" do
122
- let(:input) { 'y' }
123
-
124
- it "must return true" do
125
- expect(stdin).to receive(:gets).and_return(input)
126
-
127
- expect(subject.ask_yes_or_no(prompt)).to eq(true)
128
- end
129
- end
130
-
131
- context "when 'YES' is entered" do
132
- let(:input) { 'YES' }
133
-
134
- it "must return true" do
135
- expect(stdin).to receive(:gets).and_return(input)
136
-
137
- expect(subject.ask_yes_or_no(prompt)).to eq(true)
138
- end
139
- end
140
-
141
- context "when 'Yes' is entered" do
142
- let(:input) { 'Yes' }
143
-
144
- it "must return true" do
145
- expect(stdin).to receive(:gets).and_return(input)
146
-
147
- expect(subject.ask_yes_or_no(prompt)).to eq(true)
148
- end
149
- end
150
-
151
- context "when 'yes' is entered" do
152
- let(:input) { 'yes' }
153
-
154
- it "must return true" do
155
- expect(stdin).to receive(:gets).and_return(input)
156
-
157
- expect(subject.ask_yes_or_no(prompt)).to eq(true)
158
- end
159
- end
160
-
161
- context "when 'N' is entered" do
162
- let(:input) { 'N' }
163
-
164
- it "must return false" do
165
- expect(stdin).to receive(:gets).and_return(input)
166
-
167
- expect(subject.ask_yes_or_no(prompt)).to eq(false)
168
- end
169
- end
170
-
171
- context "when 'n' is entered" do
172
- let(:input) { 'n' }
173
-
174
- it "must return false" do
175
- expect(stdin).to receive(:gets).and_return(input)
176
-
177
- expect(subject.ask_yes_or_no(prompt)).to eq(false)
178
- end
179
- end
180
-
181
- context "when 'NO' is entered" do
182
- let(:input) { 'NO' }
183
-
184
- it "must return false" do
185
- expect(stdin).to receive(:gets).and_return(input)
186
-
187
- expect(subject.ask_yes_or_no(prompt)).to eq(false)
188
- end
189
- end
190
-
191
- context "when 'No' is entered" do
192
- let(:input) { 'No' }
193
-
194
- it "must return false" do
195
- expect(stdin).to receive(:gets).and_return(input)
196
-
197
- expect(subject.ask_yes_or_no(prompt)).to eq(false)
198
- end
199
- end
200
-
201
- context "when 'no' is entered" do
202
- let(:input) { 'no' }
203
-
204
- it "must return false" do
205
- expect(stdin).to receive(:gets).and_return(input)
206
-
207
- expect(subject.ask_yes_or_no(prompt)).to eq(false)
208
- end
209
- end
210
-
211
- context "when input besides y/n/yes/no is entered" do
212
- let(:input) { 'jflksjfls' }
213
-
214
- it "must return false" do
215
- expect(stdin).to receive(:gets).and_return(input)
216
-
217
- expect(subject.ask_yes_or_no(prompt)).to eq(false)
218
- end
219
- end
220
-
221
- context "when defualt: is given" do
222
- context "and is true" do
223
- let(:default) { true }
224
-
225
- it "must include [Y] in the prompt" do
226
- expect(stdout).to receive(:print).with("#{prompt} (Y/N) [Y]: ")
227
- expect(stdin).to receive(:gets).and_return(input)
228
-
229
- subject.ask_yes_or_no(prompt, default: default)
230
- end
231
-
232
- context "and empty user-input is given" do
233
- let(:input) { "" }
234
-
235
- it "must return true" do
236
- expect(stdout).to receive(:print).with("#{prompt} (Y/N) [Y]: ")
237
- expect(stdin).to receive(:gets).and_return(input)
238
-
239
- expect(subject.ask_yes_or_no(prompt, default: default)).to eq(default)
240
- end
241
- end
242
- end
243
-
244
- context "and is false" do
245
- let(:default) { false }
246
-
247
- it "must include [N] in the prompt" do
248
- expect(stdout).to receive(:print).with("#{prompt} (Y/N) [N]: ")
249
- expect(stdin).to receive(:gets).and_return(input)
250
-
251
- subject.ask_yes_or_no(prompt, default: default)
252
- end
253
-
254
- context "and empty user-input is given" do
255
- let(:input) { "" }
256
-
257
- it "must return false" do
258
- expect(stdout).to receive(:print).with("#{prompt} (Y/N) [N]: ")
259
- expect(stdin).to receive(:gets).and_return(input)
260
-
261
- expect(subject.ask_yes_or_no(prompt, default: default)).to eq(default)
262
- end
263
- end
264
- end
265
- end
266
- end
267
-
268
- describe "#ask_multiple_choice" do
269
- context "when given an Array" do
270
- let(:choices) do
271
- [
272
- "foo",
273
- "bar",
274
- "baz"
275
- ]
276
- end
277
-
278
- let(:input) { "2" }
279
-
280
- it "must print the numbered choices, a prompt with the choices, read input, and return the choice" do
281
- expect(stdout).to receive(:puts).with(" 1) #{choices[0]}")
282
- expect(stdout).to receive(:puts).with(" 2) #{choices[1]}")
283
- expect(stdout).to receive(:puts).with(" 3) #{choices[2]}")
284
- expect(stdout).to receive(:puts).with(no_args)
285
- expect(stdout).to receive(:print).with("#{prompt} (1, 2, 3): ")
286
- expect(stdin).to receive(:gets).and_return(input)
287
-
288
- expect(subject.ask_multiple_choice(prompt,choices)).to eq(choices[input.to_i - 1])
289
- end
290
-
291
- context "when empty user-input is given" do
292
- it "must ask for input again, until non-empty input is given" do
293
- expect(stdin).to receive(:gets).and_return("")
294
- expect(stdin).to receive(:gets).and_return("")
295
- expect(stdin).to receive(:gets).and_return(input)
296
-
297
- expect(subject.ask_multiple_choice(prompt,choices)).to eq(choices[input.to_i - 1])
298
- end
299
- end
300
-
301
- context "and default: is given" do
302
- let(:default) { '3' }
303
-
304
- it "must include the default: choice in the prompt" do
305
- expect(stdout).to receive(:print).with("#{prompt} (1, 2, 3) [#{default}]: ")
306
- expect(stdin).to receive(:gets).and_return(input)
307
-
308
- subject.ask_multiple_choice(prompt,choices, default: default)
309
- end
310
-
311
- context "and empty user-input is given" do
312
- it "must return the value for the default choice" do
313
- expect(stdin).to receive(:gets).and_return("")
314
-
315
- expect(subject.ask_multiple_choice(prompt,choices, default: default)).to eq(choices[default.to_i - 1])
316
- end
317
- end
318
- end
319
- end
320
-
321
- context "when given a Hash" do
322
- let(:choices) do
323
- {
324
- "A" => "foo",
325
- "B" => "bar",
326
- "C" => "baz"
327
- }
328
- end
329
-
330
- let(:input) { "B" }
331
-
332
- it "must print the labeled choices, a prompt with the choices, read input, and return the choice" do
333
- expect(stdout).to receive(:puts).with(" #{choices.keys[0]}) #{choices.values[0]}")
334
- expect(stdout).to receive(:puts).with(" #{choices.keys[1]}) #{choices.values[1]}")
335
- expect(stdout).to receive(:puts).with(" #{choices.keys[2]}) #{choices.values[2]}")
336
- expect(stdout).to receive(:puts).with(no_args)
337
- expect(stdout).to receive(:print).with("#{prompt} (#{choices.keys[0]}, #{choices.keys[1]}, #{choices.keys[2]}): ")
338
- expect(stdin).to receive(:gets).and_return(input)
339
-
340
- expect(subject.ask_multiple_choice(prompt,choices)).to eq(choices[input])
341
- end
342
-
343
- context "when empty user-input is given" do
344
- it "must ask for input again, until non-empty input is given" do
345
- expect(stdin).to receive(:gets).and_return("")
346
- expect(stdin).to receive(:gets).and_return("")
347
- expect(stdin).to receive(:gets).and_return(input)
348
-
349
- expect(subject.ask_multiple_choice(prompt,choices)).to eq(choices[input])
350
- end
351
- end
352
-
353
- context "and default: is given" do
354
- let(:default) { 'C' }
355
-
356
- it "must include the default: choice in the prompt" do
357
- expect(stdout).to receive(:print).with("#{prompt} (#{choices.keys[0]}, #{choices.keys[1]}, #{choices.keys[2]}) [#{default}]: ")
358
- expect(stdin).to receive(:gets).and_return(input)
359
-
360
- subject.ask_multiple_choice(prompt,choices, default: default)
361
- end
362
-
363
- context "and empty user-input is given" do
364
- it "must return the value for the default choice" do
365
- expect(stdin).to receive(:gets).and_return("")
366
-
367
- expect(subject.ask_multiple_choice(prompt,choices, default: default)).to eq(choices[default])
368
- end
369
- end
370
- end
371
- end
372
- end
373
-
374
- describe "#ask_secret" do
375
- let(:input) { 's3cr3t' }
376
-
377
- context "when stdin supports to #noecho" do
378
- it "must call #noecho, read input, then return the input" do
379
- allow(stdin).to receive(:noecho).and_yield
380
- expect(stdin).to receive(:gets).and_return(input)
381
-
382
- expect(subject.ask_secret(prompt)).to eq(input)
383
- end
384
- end
385
-
386
- context "when stdin does not support #noecho" do
387
- it "must fallback to reading input" do
388
- expect(stdin).to receive(:gets).and_return(input)
389
-
390
- expect(subject.ask_secret(prompt)).to eq(input)
391
- end
392
- end
393
-
394
- context "when empty user-input is given" do
395
- it "must ask for input again, until non-empty input is given" do
396
- expect(stdin).to receive(:gets).and_return("")
397
- expect(stdin).to receive(:gets).and_return("")
398
- expect(stdin).to receive(:gets).and_return("")
399
- expect(stdin).to receive(:gets).and_return(input)
400
-
401
- expect(subject.ask_secret(prompt)).to eq(input)
402
- end
403
- end
404
-
405
- context "when required: is false" do
406
- context "and empty user-input is given" do
407
- it "must return the empty user-input" do
408
- expect(stdin).to receive(:gets).and_return("")
409
-
410
- expect(subject.ask_secret(prompt, required: false)).to eq("")
411
- end
412
- end
413
- end
414
- end
415
- end