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
@@ -54,16 +54,27 @@ describe CommandKit::Commands::AutoLoad do
|
|
54
54
|
end
|
55
55
|
|
56
56
|
module TestAutoLoad
|
57
|
-
class
|
57
|
+
class TestCommand
|
58
58
|
include CommandKit::Commands
|
59
59
|
include CommandKit::Commands::AutoLoad.new(
|
60
60
|
dir: File.expand_path('../fixtures/test_auto_load/cli/commands',__FILE__),
|
61
61
|
namespace: "#{self}::Commands"
|
62
62
|
)
|
63
63
|
end
|
64
|
+
|
65
|
+
class TestCommandWithBlock
|
66
|
+
include CommandKit::Commands
|
67
|
+
include(CommandKit::Commands::AutoLoad.new(
|
68
|
+
dir: File.expand_path('../fixtures/test_auto_load/cli/commands',__FILE__),
|
69
|
+
namespace: "#{self}::Commands"
|
70
|
+
) { |autoload|
|
71
|
+
autoload.command 'test-1', 'Test1', 'test1.rb', aliases: %w[test_1]
|
72
|
+
autoload.command 'test-2', 'Test2', 'test2.rb', aliases: %w[test_2]
|
73
|
+
})
|
74
|
+
end
|
64
75
|
end
|
65
76
|
|
66
|
-
let(:command_class) { TestAutoLoad::
|
77
|
+
let(:command_class) { TestAutoLoad::TestCommand }
|
67
78
|
let(:autoload_module) { command_class.included_modules.first }
|
68
79
|
|
69
80
|
describe "#included" do
|
@@ -76,6 +87,26 @@ describe CommandKit::Commands::AutoLoad do
|
|
76
87
|
it "must merge the module's #commands into the class'es #commands" do
|
77
88
|
expect(command_class.commands).to include(autoload_module.commands)
|
78
89
|
end
|
90
|
+
|
91
|
+
context "when CommandKit::Commands::AutoLoad has an explicit mapping" do
|
92
|
+
let(:command_class) { TestAutoLoad::TestCommandWithBlock }
|
93
|
+
|
94
|
+
it "must merge the module's #commands into the class'es #commands" do
|
95
|
+
expect(command_class.commands).to include(autoload_module.commands)
|
96
|
+
end
|
97
|
+
|
98
|
+
it "must also merge the any aliases into the class'es #command_aliases" do
|
99
|
+
expected_command_aliases = {}
|
100
|
+
|
101
|
+
autoload_module.commands.each do |name,subcommand|
|
102
|
+
subcommand.aliases.each do |alias_name|
|
103
|
+
expected_command_aliases[alias_name] = name
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
expect(command_class.command_aliases).to include(expected_command_aliases)
|
108
|
+
end
|
109
|
+
end
|
79
110
|
end
|
80
111
|
|
81
112
|
describe "#join" do
|
data/spec/commands_spec.rb
CHANGED
@@ -19,7 +19,6 @@ describe CommandKit::Commands do
|
|
19
19
|
class Test2 < CommandKit::Command
|
20
20
|
end
|
21
21
|
|
22
|
-
p method(:command).source_location
|
23
22
|
command Test1
|
24
23
|
command Test2
|
25
24
|
|
@@ -126,6 +125,32 @@ describe CommandKit::Commands do
|
|
126
125
|
command Test2
|
127
126
|
|
128
127
|
end
|
128
|
+
|
129
|
+
class TestCommandsWithCommandArguments
|
130
|
+
|
131
|
+
include CommandKit::Commands
|
132
|
+
|
133
|
+
class Test1 < CommandKit::Command
|
134
|
+
argument :arg1, required: false,
|
135
|
+
desc: 'Argument 1'
|
136
|
+
|
137
|
+
argument :arg2, required: false,
|
138
|
+
desc: 'Argument 2'
|
139
|
+
end
|
140
|
+
|
141
|
+
class Test2 < CommandKit::Command
|
142
|
+
argument :arg1, required: false,
|
143
|
+
desc: 'Argument 1'
|
144
|
+
|
145
|
+
argument :arg2, required: false,
|
146
|
+
desc: 'Argument 2'
|
147
|
+
end
|
148
|
+
|
149
|
+
command Test1
|
150
|
+
command Test2
|
151
|
+
|
152
|
+
end
|
153
|
+
|
129
154
|
end
|
130
155
|
|
131
156
|
let(:command_class) { TestCommands::TestCommands }
|
@@ -191,7 +216,7 @@ describe CommandKit::Commands do
|
|
191
216
|
it "must contain the mapping of aliases to command names" do
|
192
217
|
expect(subject.command_aliases).to eq({
|
193
218
|
't1' => 'test1',
|
194
|
-
't2' => 'test2'
|
219
|
+
't2' => 'test2'
|
195
220
|
})
|
196
221
|
end
|
197
222
|
end
|
@@ -569,7 +594,7 @@ describe CommandKit::Commands do
|
|
569
594
|
expect(subject).to receive(:exit).with(1)
|
570
595
|
|
571
596
|
expect { subject.command_not_found(unknown_command) }.to output(
|
572
|
-
"'#{unknown_command}' is not a #{subject.command_name} command. See `#{subject.command_name} help`" + $/
|
597
|
+
"#{subject.command_name}: '#{unknown_command}' is not a #{subject.command_name} command. See `#{subject.command_name} help`" + $/
|
573
598
|
).to_stderr
|
574
599
|
end
|
575
600
|
end
|
@@ -582,6 +607,44 @@ describe CommandKit::Commands do
|
|
582
607
|
end
|
583
608
|
end
|
584
609
|
|
610
|
+
describe "#option_parser" do
|
611
|
+
let(:command_name) { 'test1' }
|
612
|
+
let(:command_argv) { %w[foo bar baz] }
|
613
|
+
let(:argv) { [command_name, *command_argv] }
|
614
|
+
|
615
|
+
it "must stop before the first non-option argument" do
|
616
|
+
expect(subject.option_parser.parse(argv)).to eq(
|
617
|
+
[command_name, *command_argv]
|
618
|
+
)
|
619
|
+
end
|
620
|
+
|
621
|
+
context "when an unknown command name is given" do
|
622
|
+
let(:command_argv) { %w[bar baz] }
|
623
|
+
let(:argv) { ['foo', command_name, *command_argv] }
|
624
|
+
|
625
|
+
it "must stop before the first non-option argument" do
|
626
|
+
expect(subject.option_parser.parse(argv)).to eq(argv)
|
627
|
+
end
|
628
|
+
end
|
629
|
+
|
630
|
+
context "when additional global options are defined" do
|
631
|
+
let(:command_class) { TestCommands::TestCommandsWithGlobalOptions }
|
632
|
+
let(:bar) { '2' }
|
633
|
+
let(:argv) do
|
634
|
+
['--foo', '--bar', bar.to_s, command_name, *command_argv]
|
635
|
+
end
|
636
|
+
|
637
|
+
it "must parse the global options, but stop before the first non-option associated argument" do
|
638
|
+
expect(subject.option_parser.parse(argv)).to eq(
|
639
|
+
[command_name, *command_argv]
|
640
|
+
)
|
641
|
+
|
642
|
+
expect(subject.options[:foo]).to be(true)
|
643
|
+
expect(subject.options[:bar]).to eq(bar)
|
644
|
+
end
|
645
|
+
end
|
646
|
+
end
|
647
|
+
|
585
648
|
describe "#run" do
|
586
649
|
context "when a command name is the first argument" do
|
587
650
|
let(:command) { 'test1' }
|
@@ -607,48 +670,45 @@ describe CommandKit::Commands do
|
|
607
670
|
end
|
608
671
|
|
609
672
|
context "when given no arguments" do
|
610
|
-
|
673
|
+
let(:exit_status) { 1 }
|
674
|
+
|
675
|
+
it "must default to calling #help and exit with 1" do
|
611
676
|
expect(subject).to receive(:help)
|
677
|
+
expect(subject).to receive(:exit).with(exit_status)
|
612
678
|
|
613
679
|
subject.run()
|
614
680
|
end
|
615
681
|
end
|
616
682
|
end
|
617
683
|
|
618
|
-
describe "#
|
619
|
-
let(:
|
620
|
-
let(:command_argv) { %w[foo bar baz] }
|
621
|
-
let(:argv) { [command_name, *command_argv] }
|
684
|
+
describe "#main" do
|
685
|
+
let(:command_class) { TestCommands::TestCommandsWithCommandArguments }
|
622
686
|
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
687
|
+
context "when a command name is the first argument" do
|
688
|
+
let(:command) { 'test1' }
|
689
|
+
let(:argv) { [command] }
|
690
|
+
|
691
|
+
it "must return 0" do
|
692
|
+
expect(subject.main(argv)).to eq(0)
|
693
|
+
end
|
627
694
|
end
|
628
695
|
|
629
|
-
context "when
|
630
|
-
let(:
|
631
|
-
let(:argv) { ['foo', command_name, *command_argv] }
|
696
|
+
context "when given additional command arguments" do
|
697
|
+
let(:argv) { %w[test1 arg1 arg2] }
|
632
698
|
|
633
|
-
it "must
|
634
|
-
expect(subject.
|
699
|
+
it "must pass them to the command" do
|
700
|
+
expect(subject.main(argv)).to eq(0)
|
635
701
|
end
|
636
702
|
end
|
637
703
|
|
638
|
-
context "when
|
639
|
-
let(:
|
640
|
-
let(:
|
641
|
-
let(:argv) do
|
642
|
-
['--foo', '--bar', bar.to_s, command_name, *command_argv]
|
643
|
-
end
|
704
|
+
context "when given no arguments" do
|
705
|
+
let(:exit_status) { 1 }
|
706
|
+
let(:argv) { %w[] }
|
644
707
|
|
645
|
-
it "must
|
646
|
-
expect(subject
|
647
|
-
[command_name, *command_argv]
|
648
|
-
)
|
708
|
+
it "must call #help and return 1" do
|
709
|
+
expect(subject).to receive(:help)
|
649
710
|
|
650
|
-
expect(subject.
|
651
|
-
expect(subject.options[:bar]).to eq(bar)
|
711
|
+
expect(subject.main(argv)).to eq(exit_status)
|
652
712
|
end
|
653
713
|
end
|
654
714
|
end
|
@@ -711,6 +771,10 @@ describe CommandKit::Commands do
|
|
711
771
|
"Options:",
|
712
772
|
" -h, --help Print help information",
|
713
773
|
"",
|
774
|
+
"Arguments:",
|
775
|
+
" [COMMAND] The command name to run",
|
776
|
+
" [ARGS ...] Additional arguments for the command",
|
777
|
+
"",
|
714
778
|
"Commands:",
|
715
779
|
" help",
|
716
780
|
" test1",
|
@@ -731,6 +795,10 @@ describe CommandKit::Commands do
|
|
731
795
|
"Options:",
|
732
796
|
" -h, --help Print help information",
|
733
797
|
"",
|
798
|
+
"Arguments:",
|
799
|
+
" [COMMAND] The command name to run",
|
800
|
+
" [ARGS ...] Additional arguments for the command",
|
801
|
+
"",
|
734
802
|
"Commands:",
|
735
803
|
" help",
|
736
804
|
" test1, t1",
|
@@ -754,6 +822,10 @@ describe CommandKit::Commands do
|
|
754
822
|
" -b, --bar BAR Global --bar option",
|
755
823
|
" -h, --help Print help information",
|
756
824
|
"",
|
825
|
+
"Arguments:",
|
826
|
+
" [COMMAND] The command name to run",
|
827
|
+
" [ARGS ...] Additional arguments for the command",
|
828
|
+
"",
|
757
829
|
"Commands:",
|
758
830
|
" help",
|
759
831
|
" test1",
|
data/spec/env/path_spec.rb
CHANGED
@@ -13,6 +13,12 @@ describe CommandKit::Env::Path do
|
|
13
13
|
let(:command_class) { TestEnvPath::TestCommand }
|
14
14
|
subject { command_class.new }
|
15
15
|
|
16
|
+
describe ".included" do
|
17
|
+
it "must include CommandKit::Env" do
|
18
|
+
expect(command_class).to be_include(CommandKit::Env)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
16
22
|
describe "#initialize" do
|
17
23
|
it "must split ENV['PATH'] into an Array of directories" do
|
18
24
|
expect(subject.path_dirs).to eq(ENV['PATH'].split(File::PATH_SEPARATOR))
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'command_kit/file_utils'
|
3
|
+
require 'tempfile'
|
4
|
+
|
5
|
+
describe CommandKit::FileUtils do
|
6
|
+
module TestFileUtils
|
7
|
+
class Command
|
8
|
+
include CommandKit::FileUtils
|
9
|
+
|
10
|
+
attr_reader :var
|
11
|
+
|
12
|
+
def initialize(var: nil)
|
13
|
+
super()
|
14
|
+
|
15
|
+
@var = var
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_method
|
19
|
+
'some method'
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
let(:var) { 42 }
|
25
|
+
|
26
|
+
let(:command_class) { TestFileUtils::Command }
|
27
|
+
subject { command_class.new(var: var) }
|
28
|
+
|
29
|
+
let(:fixtures_dir) { File.expand_path(File.join(__dir__,'fixtures')) }
|
30
|
+
let(:template_path) { File.join(fixtures_dir,'template.erb') }
|
31
|
+
|
32
|
+
describe "#erb" do
|
33
|
+
let(:expected_result) do
|
34
|
+
[
|
35
|
+
"Raw text",
|
36
|
+
'',
|
37
|
+
"variable = #{var}",
|
38
|
+
'',
|
39
|
+
"method = #{subject.test_method}"
|
40
|
+
].join($/)
|
41
|
+
end
|
42
|
+
|
43
|
+
context "when only given a source file argument" do
|
44
|
+
it "must render the erb template and return the result" do
|
45
|
+
expect(subject.erb(template_path)).to eq(expected_result)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context "when given an additional destination file argument" do
|
50
|
+
let(:dest_path) { Tempfile.new.path }
|
51
|
+
|
52
|
+
before { subject.erb(template_path,dest_path) }
|
53
|
+
|
54
|
+
it "must render the erb template and write the result to the destination" do
|
55
|
+
expect(File.read(dest_path)).to eq(expected_result)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
data/spec/help/man_spec.rb
CHANGED
@@ -16,7 +16,13 @@ describe CommandKit::Help::Man do
|
|
16
16
|
man_page 'foo.1'
|
17
17
|
end
|
18
18
|
|
19
|
-
class
|
19
|
+
class TestCommandWithRelativeManDir
|
20
|
+
include CommandKit::Help::Man
|
21
|
+
|
22
|
+
man_dir File.join(__dir__,'..','..','..','man')
|
23
|
+
end
|
24
|
+
|
25
|
+
class TestCommandWithManDirNotSet
|
20
26
|
include CommandKit::Help::Man
|
21
27
|
end
|
22
28
|
end
|
@@ -41,7 +47,7 @@ describe CommandKit::Help::Man do
|
|
41
47
|
|
42
48
|
describe ".man_dir" do
|
43
49
|
context "when no man_dir have been set" do
|
44
|
-
subject { TestHelpMan::
|
50
|
+
subject { TestHelpMan::TestCommandWithManDirNotSet }
|
45
51
|
|
46
52
|
it "should default to nil" do
|
47
53
|
expect(subject.man_dir).to be_nil
|
@@ -52,7 +58,17 @@ describe CommandKit::Help::Man do
|
|
52
58
|
subject { TestHelpMan::TestCommand }
|
53
59
|
|
54
60
|
it "must return the explicitly set man_dir" do
|
55
|
-
expect(subject.man_dir).to eq(File.
|
61
|
+
expect(subject.man_dir).to eq(File.join(__dir__,'fixtures','man'))
|
62
|
+
end
|
63
|
+
|
64
|
+
context "but it's a relative path" do
|
65
|
+
subject { TestHelpMan::TestCommandWithRelativeManDir }
|
66
|
+
|
67
|
+
it "must expand the given man_dir path" do
|
68
|
+
expect(subject.man_dir).to eq(
|
69
|
+
File.expand_path(File.join(__dir__,'..','..','..','man'))
|
70
|
+
)
|
71
|
+
end
|
56
72
|
end
|
57
73
|
end
|
58
74
|
|
@@ -96,7 +112,7 @@ describe CommandKit::Help::Man do
|
|
96
112
|
end
|
97
113
|
|
98
114
|
it "must not change the superclass'es man_dir" do
|
99
|
-
expect(super_subject.man_dir).to eq('set/in/baseclass')
|
115
|
+
expect(super_subject.man_dir).to eq(File.expand_path('set/in/baseclass'))
|
100
116
|
end
|
101
117
|
end
|
102
118
|
|
@@ -115,7 +131,7 @@ describe CommandKit::Help::Man do
|
|
115
131
|
subject { TestHelpMan::ExplicitInheritedCmd }
|
116
132
|
|
117
133
|
it "must return the subclass'es man_dir" do
|
118
|
-
expect(subject.man_dir).to eq('set/in/subclass')
|
134
|
+
expect(subject.man_dir).to eq(File.expand_path('set/in/subclass'))
|
119
135
|
end
|
120
136
|
|
121
137
|
it "must not change the superclass'es man_dir" do
|
@@ -134,11 +150,11 @@ describe CommandKit::Help::Man do
|
|
134
150
|
subject { TestHelpMan::ExplicitOverridingInheritedCmd }
|
135
151
|
|
136
152
|
it "must return the subclass'es man_dir" do
|
137
|
-
expect(subject.man_dir).to eq('set/in/subclass')
|
153
|
+
expect(subject.man_dir).to eq(File.expand_path('set/in/subclass'))
|
138
154
|
end
|
139
155
|
|
140
156
|
it "must not change the superclass'es man_dir" do
|
141
|
-
expect(super_subject.man_dir).to eq('set/in/baseclass')
|
157
|
+
expect(super_subject.man_dir).to eq(File.expand_path('set/in/baseclass'))
|
142
158
|
end
|
143
159
|
end
|
144
160
|
end
|
@@ -234,48 +250,7 @@ describe CommandKit::Help::Man do
|
|
234
250
|
|
235
251
|
subject { command_class.new }
|
236
252
|
|
237
|
-
describe "#man" do
|
238
|
-
let(:man_page) { 'foo' }
|
239
|
-
|
240
|
-
it "must call system() with the given man page" do
|
241
|
-
expect(subject).to receive(:system).with('man',man_page)
|
242
|
-
|
243
|
-
subject.man(man_page)
|
244
|
-
end
|
245
|
-
|
246
|
-
context "when given a non-String man-page argument" do
|
247
|
-
let(:man_page_arg) { double(:non_string_arg) }
|
248
|
-
|
249
|
-
it "must call #to_s on the man-page argument" do
|
250
|
-
expect(man_page_arg).to receive(:to_s).and_return(man_page)
|
251
|
-
|
252
|
-
expect(subject).to receive(:system).with('man',man_page)
|
253
|
-
|
254
|
-
subject.man(man_page_arg)
|
255
|
-
end
|
256
|
-
end
|
257
|
-
|
258
|
-
context "when given the section: keyword argument" do
|
259
|
-
let(:section) { 7 }
|
260
|
-
|
261
|
-
it "must call system() with the given section number and man page" do
|
262
|
-
expect(subject).to receive(:system).with('man',section.to_s,man_page)
|
263
|
-
|
264
|
-
subject.man(man_page, section: section)
|
265
|
-
end
|
266
|
-
end
|
267
|
-
end
|
268
|
-
|
269
253
|
describe "#help_man" do
|
270
|
-
context "when .man_dir is not set" do
|
271
|
-
let(:command_class) { TestHelpMan::EmptyCommand }
|
272
|
-
subject { command_class.new }
|
273
|
-
|
274
|
-
it do
|
275
|
-
expect { subject.help_man }.to raise_error(NotImplementedError)
|
276
|
-
end
|
277
|
-
end
|
278
|
-
|
279
254
|
let(:man_page_path) do
|
280
255
|
File.join(subject.class.man_dir,subject.class.man_page)
|
281
256
|
end
|
@@ -296,6 +271,16 @@ describe CommandKit::Help::Man do
|
|
296
271
|
subject.help_man(man_page)
|
297
272
|
end
|
298
273
|
end
|
274
|
+
|
275
|
+
context "but the man_dir is not set" do
|
276
|
+
let(:command_class) { TestHelpMan::TestCommandWithManDirNotSet }
|
277
|
+
|
278
|
+
it "must call the super help() mehtod" do
|
279
|
+
expect {
|
280
|
+
subject.help_man
|
281
|
+
}.to raise_error(NotImplementedError,"man_dir was not set in #{command_class}")
|
282
|
+
end
|
283
|
+
end
|
299
284
|
end
|
300
285
|
|
301
286
|
describe "#help" do
|
@@ -318,21 +303,33 @@ describe CommandKit::Help::Man do
|
|
318
303
|
expect(subject.stdout).to receive(:tty?).and_return(true)
|
319
304
|
end
|
320
305
|
|
321
|
-
|
322
|
-
|
306
|
+
context "and man_dir is set" do
|
307
|
+
it "must open the command's man-page" do
|
308
|
+
expect(subject).to receive(:help_man).and_return(true)
|
323
309
|
|
324
|
-
|
325
|
-
|
310
|
+
subject.help
|
311
|
+
end
|
312
|
+
|
313
|
+
context "but when the man command is not installed" do
|
314
|
+
before do
|
315
|
+
expect(subject).to receive(:help_man).and_return(nil)
|
316
|
+
end
|
317
|
+
|
318
|
+
it "must call the super help() method" do
|
319
|
+
subject.help
|
326
320
|
|
327
|
-
|
328
|
-
|
329
|
-
expect(subject).to receive(:help_man).and_return(nil)
|
321
|
+
expect(subject.stdout.string).to eq(normal_help_output)
|
322
|
+
end
|
330
323
|
end
|
324
|
+
end
|
325
|
+
|
326
|
+
context "but the man_dir is not set" do
|
327
|
+
let(:command_class) { TestHelpMan::TestCommandWithManDirNotSet }
|
331
328
|
|
332
|
-
it "must call the super help()
|
329
|
+
it "must call the super help() mehtod" do
|
333
330
|
subject.help
|
334
331
|
|
335
|
-
expect(
|
332
|
+
expect(stdout.string).to eq(normal_help_output)
|
336
333
|
end
|
337
334
|
end
|
338
335
|
end
|
data/spec/inflector_spec.rb
CHANGED
@@ -28,6 +28,10 @@ describe CommandKit::Inflector do
|
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
|
+
ascii = (0..255).map(&:chr)
|
32
|
+
alpha = ('a'..'z').to_a + ('A'..'Z').to_a
|
33
|
+
numeric = ('0'..'9').to_a
|
34
|
+
|
31
35
|
describe ".underscore" do
|
32
36
|
it "must convert CamelCase to camel_case" do
|
33
37
|
expect(subject.underscore('CamelCase')).to eq('camel_case')
|
@@ -37,18 +41,48 @@ describe CommandKit::Inflector do
|
|
37
41
|
expect(subject.underscore('camelCase')).to eq('camel_case')
|
38
42
|
end
|
39
43
|
|
40
|
-
it "must convert
|
41
|
-
expect(subject.underscore('
|
44
|
+
it "must convert Camelcase to camelcase" do
|
45
|
+
expect(subject.underscore('Camelcase')).to eq('camelcase')
|
42
46
|
end
|
43
47
|
|
44
|
-
it "must convert
|
45
|
-
expect(subject.underscore('
|
48
|
+
it "must convert CAMELCASE to camelcase" do
|
49
|
+
expect(subject.underscore('CAMELCASE')).to eq('camelcase')
|
46
50
|
end
|
47
51
|
|
48
|
-
|
49
|
-
|
50
|
-
|
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')
|
52
86
|
end
|
53
87
|
|
54
88
|
context "when given a non-String" do
|
@@ -56,6 +90,20 @@ describe CommandKit::Inflector do
|
|
56
90
|
expect(subject.underscore(:CamelCase)).to eq('camel_case')
|
57
91
|
end
|
58
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
|
59
107
|
end
|
60
108
|
|
61
109
|
describe ".dasherize" do
|
@@ -100,5 +148,19 @@ describe CommandKit::Inflector do
|
|
100
148
|
expect(subject.camelize(:foo_bar)).to eq('FooBar')
|
101
149
|
end
|
102
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
|
103
165
|
end
|
104
166
|
end
|
data/spec/man_spec.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'command_kit/man'
|
3
|
+
|
4
|
+
describe CommandKit::Man do
|
5
|
+
module TestMan
|
6
|
+
class TestCommand
|
7
|
+
include CommandKit::Man
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
let(:command_class) { TestMan::TestCommand }
|
12
|
+
|
13
|
+
subject { command_class.new }
|
14
|
+
|
15
|
+
describe "#man" do
|
16
|
+
let(:man_page) { 'foo' }
|
17
|
+
|
18
|
+
it "must call system() with the given man page" do
|
19
|
+
expect(subject).to receive(:system).with('man',man_page)
|
20
|
+
|
21
|
+
subject.man(man_page)
|
22
|
+
end
|
23
|
+
|
24
|
+
context "when given a non-String man-page argument" do
|
25
|
+
let(:man_page_arg) { double(:non_string_arg) }
|
26
|
+
|
27
|
+
it "must call #to_s on the man-page argument" do
|
28
|
+
expect(man_page_arg).to receive(:to_s).and_return(man_page)
|
29
|
+
|
30
|
+
expect(subject).to receive(:system).with('man',man_page)
|
31
|
+
|
32
|
+
subject.man(man_page_arg)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context "when given the section: keyword argument" do
|
37
|
+
let(:section) { 7 }
|
38
|
+
|
39
|
+
it "must call system() with the given section number and man page" do
|
40
|
+
expect(subject).to receive(:system).with('man',section.to_s,man_page)
|
41
|
+
|
42
|
+
subject.man(man_page, section: section)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|