command_kit 0.1.0.pre1
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 +7 -0
- data/.document +3 -0
- data/.github/workflows/ruby.yml +29 -0
- data/.gitignore +7 -0
- data/.rspec +1 -0
- data/.yardopts +1 -0
- data/ChangeLog.md +29 -0
- data/Gemfile +14 -0
- data/LICENSE.txt +20 -0
- data/README.md +283 -0
- data/Rakefile +23 -0
- data/command_kit.gemspec +60 -0
- data/gemspec.yml +14 -0
- data/lib/command_kit.rb +1 -0
- data/lib/command_kit/arguments.rb +161 -0
- data/lib/command_kit/arguments/argument.rb +111 -0
- data/lib/command_kit/arguments/argument_value.rb +81 -0
- data/lib/command_kit/arguments/usage.rb +6 -0
- data/lib/command_kit/colors.rb +355 -0
- data/lib/command_kit/command.rb +42 -0
- data/lib/command_kit/command_name.rb +95 -0
- data/lib/command_kit/commands.rb +299 -0
- data/lib/command_kit/commands/auto_load.rb +153 -0
- data/lib/command_kit/commands/auto_load/subcommand.rb +90 -0
- data/lib/command_kit/commands/auto_require.rb +138 -0
- data/lib/command_kit/commands/command.rb +12 -0
- data/lib/command_kit/commands/help.rb +43 -0
- data/lib/command_kit/commands/parent_command.rb +21 -0
- data/lib/command_kit/commands/subcommand.rb +51 -0
- data/lib/command_kit/console.rb +141 -0
- data/lib/command_kit/description.rb +89 -0
- data/lib/command_kit/env.rb +43 -0
- data/lib/command_kit/env/home.rb +71 -0
- data/lib/command_kit/env/path.rb +71 -0
- data/lib/command_kit/examples.rb +99 -0
- data/lib/command_kit/exception_handler.rb +55 -0
- data/lib/command_kit/help.rb +62 -0
- data/lib/command_kit/help/man.rb +125 -0
- data/lib/command_kit/inflector.rb +84 -0
- data/lib/command_kit/main.rb +103 -0
- data/lib/command_kit/options.rb +179 -0
- data/lib/command_kit/options/option.rb +171 -0
- data/lib/command_kit/options/option_value.rb +90 -0
- data/lib/command_kit/options/parser.rb +227 -0
- data/lib/command_kit/options/quiet.rb +53 -0
- data/lib/command_kit/options/usage.rb +6 -0
- data/lib/command_kit/options/verbose.rb +55 -0
- data/lib/command_kit/options/version.rb +62 -0
- data/lib/command_kit/os.rb +47 -0
- data/lib/command_kit/pager.rb +115 -0
- data/lib/command_kit/printing.rb +32 -0
- data/lib/command_kit/printing/indent.rb +78 -0
- data/lib/command_kit/program_name.rb +57 -0
- data/lib/command_kit/stdio.rb +138 -0
- data/lib/command_kit/usage.rb +102 -0
- data/lib/command_kit/version.rb +4 -0
- data/lib/command_kit/xdg.rb +138 -0
- data/spec/arguments/argument_spec.rb +169 -0
- data/spec/arguments/argument_value_spec.rb +126 -0
- data/spec/arguments_spec.rb +213 -0
- data/spec/colors_spec.rb +470 -0
- data/spec/command_kit_spec.rb +8 -0
- data/spec/command_name_spec.rb +130 -0
- data/spec/command_spec.rb +49 -0
- data/spec/commands/auto_load/subcommand_spec.rb +82 -0
- data/spec/commands/auto_load_spec.rb +128 -0
- data/spec/commands/auto_require_spec.rb +142 -0
- data/spec/commands/fixtures/test_auto_load/cli/commands/test1.rb +10 -0
- data/spec/commands/fixtures/test_auto_load/cli/commands/test2.rb +10 -0
- data/spec/commands/fixtures/test_auto_require/lib/test_auto_require/cli/commands/test1.rb +10 -0
- data/spec/commands/help_spec.rb +66 -0
- data/spec/commands/parent_command_spec.rb +40 -0
- data/spec/commands/subcommand_spec.rb +99 -0
- data/spec/commands_spec.rb +767 -0
- data/spec/console_spec.rb +201 -0
- data/spec/description_spec.rb +203 -0
- data/spec/env/home_spec.rb +46 -0
- data/spec/env/path_spec.rb +78 -0
- data/spec/env_spec.rb +123 -0
- data/spec/examples_spec.rb +235 -0
- data/spec/exception_handler_spec.rb +103 -0
- data/spec/help_spec.rb +119 -0
- data/spec/inflector_spec.rb +104 -0
- data/spec/main_spec.rb +179 -0
- data/spec/options/option_spec.rb +258 -0
- data/spec/options/option_value_spec.rb +67 -0
- data/spec/options/parser_spec.rb +265 -0
- data/spec/options_spec.rb +137 -0
- data/spec/os_spec.rb +46 -0
- data/spec/pager_spec.rb +154 -0
- data/spec/printing/indent_spec.rb +130 -0
- data/spec/printing_spec.rb +76 -0
- data/spec/program_name_spec.rb +62 -0
- data/spec/spec_helper.rb +6 -0
- data/spec/stdio_spec.rb +264 -0
- data/spec/usage_spec.rb +237 -0
- data/spec/xdg_spec.rb +191 -0
- metadata +156 -0
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'command_kit/env/path'
|
|
3
|
+
|
|
4
|
+
describe Env::Path do
|
|
5
|
+
module TestEnvPath
|
|
6
|
+
class TestCommand
|
|
7
|
+
|
|
8
|
+
include CommandKit::Env::Path
|
|
9
|
+
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
let(:command_class) { TestEnvPath::TestCommand }
|
|
14
|
+
subject { command_class.new }
|
|
15
|
+
|
|
16
|
+
describe "#initialize" do
|
|
17
|
+
it "must split ENV['PATH'] into an Array of directories" do
|
|
18
|
+
expect(subject.path_dirs).to eq(ENV['PATH'].split(File::PATH_SEPARATOR))
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
context "when given a custom 'PATH variable" do
|
|
22
|
+
let(:path_dirs) { %w[/bin /usr/bin] }
|
|
23
|
+
let(:path) { path_dirs.join(File::PATH_SEPARATOR) }
|
|
24
|
+
|
|
25
|
+
subject { command_class.new(env: {'PATH' => path}) }
|
|
26
|
+
|
|
27
|
+
it "must split env['PATH'] into an Array of directories" do
|
|
28
|
+
expect(subject.path_dirs).to eq(path_dirs)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
context "when given an empty 'PATH' env variable" do
|
|
33
|
+
subject { command_class.new(env: {'PATH' => ''}) }
|
|
34
|
+
|
|
35
|
+
it "must set #path_dirs to []" do
|
|
36
|
+
expect(subject.path_dirs).to eq([])
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
describe "#find_command" do
|
|
42
|
+
context "when given a valid command name" do
|
|
43
|
+
it "must search #path_dirs for the command" do
|
|
44
|
+
command = subject.find_command('ruby')
|
|
45
|
+
|
|
46
|
+
expect(subject.path_dirs).to include(File.dirname(command))
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
it "must return the path to the command" do
|
|
50
|
+
command = subject.find_command('ruby')
|
|
51
|
+
|
|
52
|
+
expect(command).to_not be(nil)
|
|
53
|
+
expect(File.file?(command)).to be(true)
|
|
54
|
+
expect(File.executable?(command)).to be(true)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
context "when given an unknown command name" do
|
|
59
|
+
it "must return nil" do
|
|
60
|
+
expect(subject.find_command('does_not_exist')).to be(nil)
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
describe "#command_installed?" do
|
|
66
|
+
context "when given a valid command name" do
|
|
67
|
+
it do
|
|
68
|
+
expect(subject.command_installed?('ruby')).to be(true)
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
context "when given an unknown command name" do
|
|
73
|
+
it "must return nil" do
|
|
74
|
+
expect(subject.command_installed?('does_not_exist')).to be(false)
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
data/spec/env_spec.rb
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'command_kit/env'
|
|
3
|
+
|
|
4
|
+
describe CommandKit::Env do
|
|
5
|
+
module TestEnv
|
|
6
|
+
class TestCommand
|
|
7
|
+
include CommandKit::Env
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
let(:command_class) { TestEnv::TestCommand }
|
|
12
|
+
|
|
13
|
+
describe "#initialize" do
|
|
14
|
+
module TestEnv
|
|
15
|
+
class TestCommandWithInitialize
|
|
16
|
+
include CommandKit::Env
|
|
17
|
+
|
|
18
|
+
attr_reader :var
|
|
19
|
+
|
|
20
|
+
def initialize(**kwargs)
|
|
21
|
+
super(**kwargs)
|
|
22
|
+
|
|
23
|
+
@var = 'foo'
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
class TestCommandWithInitializeAndKeywordArgs
|
|
28
|
+
include CommandKit::Env
|
|
29
|
+
|
|
30
|
+
attr_reader :var
|
|
31
|
+
|
|
32
|
+
def initialize(var: "foo", **kwargs)
|
|
33
|
+
super(**kwargs)
|
|
34
|
+
|
|
35
|
+
@var = var
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
context "when given no arguments" do
|
|
41
|
+
subject { command_class.new() }
|
|
42
|
+
|
|
43
|
+
it "must initialize #env to ENV" do
|
|
44
|
+
expect(subject.env).to be(ENV)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
context "and the including class defines it's own #initialize method" do
|
|
48
|
+
let(:command_class) { TestEnv::TestCommandWithInitialize }
|
|
49
|
+
|
|
50
|
+
it "must initialize #env to ENV" do
|
|
51
|
+
expect(subject.env).to be(ENV)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
it "must also call the class'es #initialize method" do
|
|
55
|
+
expect(subject.var).to eq('foo')
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
context "and it accepts keyword arguments" do
|
|
59
|
+
let(:command_class) { TestEnv::TestCommandWithInitializeAndKeywordArgs }
|
|
60
|
+
let(:var) { 'custom value' }
|
|
61
|
+
|
|
62
|
+
subject { command_class.new(var: var) }
|
|
63
|
+
|
|
64
|
+
it "must initialize #env to ENV" do
|
|
65
|
+
expect(subject.env).to be(ENV)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
it "must also call the class'es #initialize method with any additional keyword arguments" do
|
|
69
|
+
expect(subject.var).to eq(var)
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
context "when given a custom env: value" do
|
|
76
|
+
let(:custom_env) { {'FOO' => 'bar'} }
|
|
77
|
+
|
|
78
|
+
subject { command_class.new(env: custom_env) }
|
|
79
|
+
|
|
80
|
+
it "must initialize #env to the env: value" do
|
|
81
|
+
expect(subject.env).to eq(custom_env)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
context "and the including class defines it's own #initialize method" do
|
|
85
|
+
let(:command_class) { TestEnv::TestCommandWithInitialize }
|
|
86
|
+
|
|
87
|
+
it "must initialize #env to the env: value" do
|
|
88
|
+
expect(subject.env).to eq(custom_env)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
it "must also call the class'es #initialize method" do
|
|
92
|
+
expect(subject.var).to eq('foo')
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
context "and it accepts keyword arguments" do
|
|
96
|
+
let(:command_class) { TestEnv::TestCommandWithInitializeAndKeywordArgs }
|
|
97
|
+
let(:var) { 'custom value' }
|
|
98
|
+
|
|
99
|
+
subject { command_class.new(env: custom_env, var: var) }
|
|
100
|
+
|
|
101
|
+
it "must initialize #env to the env: value" do
|
|
102
|
+
expect(subject.env).to eq(custom_env)
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
it "must also call the class'es #initialize method with any additional keyword arguments" do
|
|
106
|
+
expect(subject.var).to eq(var)
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
describe "#env" do
|
|
114
|
+
let(:command_class) { TestEnv::TestCommand }
|
|
115
|
+
let(:env) { {"FOO" => "bar" } }
|
|
116
|
+
|
|
117
|
+
subject { command_class.new(env: env) }
|
|
118
|
+
|
|
119
|
+
it "must return the initialized env: value" do
|
|
120
|
+
expect(subject.env).to eq(env)
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'command_kit/examples'
|
|
3
|
+
|
|
4
|
+
describe Examples do
|
|
5
|
+
module TestExamples
|
|
6
|
+
class ImplicitCmd
|
|
7
|
+
include CommandKit::Examples
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
let(:command_class) { TestExamples::ImplicitCmd }
|
|
12
|
+
|
|
13
|
+
describe ".examples" do
|
|
14
|
+
subject { TestExamples::ImplicitCmd }
|
|
15
|
+
|
|
16
|
+
context "when no examples have been set" do
|
|
17
|
+
it "should default to nil" do
|
|
18
|
+
expect(subject.examples).to be_nil
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
context "when a examples is explicitly set" do
|
|
23
|
+
module TestExamples
|
|
24
|
+
class ExplicitCmd
|
|
25
|
+
include CommandKit::Examples
|
|
26
|
+
examples [
|
|
27
|
+
'--example 1',
|
|
28
|
+
'--example 2'
|
|
29
|
+
]
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
subject { TestExamples::ExplicitCmd }
|
|
34
|
+
|
|
35
|
+
it "must return the explicitly set examples" do
|
|
36
|
+
expect(subject.examples).to eq([
|
|
37
|
+
'--example 1',
|
|
38
|
+
'--example 2'
|
|
39
|
+
])
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
context "when the command class inherites from another class" do
|
|
44
|
+
context "but no examples is set" do
|
|
45
|
+
module TestExamples
|
|
46
|
+
class BaseCmd
|
|
47
|
+
include CommandKit::Examples
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
class InheritedCmd < BaseCmd
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
subject { TestExamples::InheritedCmd }
|
|
55
|
+
|
|
56
|
+
it "must search each class then return nil "do
|
|
57
|
+
expect(subject.examples).to be_nil
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
module TestExamples
|
|
62
|
+
class ExplicitBaseCmd
|
|
63
|
+
include CommandKit::Examples
|
|
64
|
+
examples [
|
|
65
|
+
'--example 1',
|
|
66
|
+
'--example 2'
|
|
67
|
+
]
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
context "when the superclass defines an explicit examples" do
|
|
72
|
+
module TestExamples
|
|
73
|
+
class ImplicitInheritedCmd < ExplicitBaseCmd
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
let(:super_subject) { TestExamples::ExplicitBaseCmd }
|
|
78
|
+
subject { TestExamples::ImplicitInheritedCmd }
|
|
79
|
+
|
|
80
|
+
it "must inherit the superclass'es examples" do
|
|
81
|
+
expect(subject.examples).to eq(super_subject.examples)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
it "must not change the superclass'es examples" do
|
|
85
|
+
expect(super_subject.examples).to eq([
|
|
86
|
+
'--example 1',
|
|
87
|
+
'--example 2'
|
|
88
|
+
])
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
context "when the subclass defines an explicit examples" do
|
|
93
|
+
module TestExamples
|
|
94
|
+
class ImplicitBaseCmd
|
|
95
|
+
include CommandKit::Examples
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
class ExplicitInheritedCmd < ImplicitBaseCmd
|
|
99
|
+
examples [
|
|
100
|
+
'--example 1',
|
|
101
|
+
'--example 2'
|
|
102
|
+
]
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
let(:super_subject) { TestExamples::ImplicitBaseCmd }
|
|
107
|
+
subject { TestExamples::ExplicitInheritedCmd }
|
|
108
|
+
|
|
109
|
+
it "must return the subclass'es examples" do
|
|
110
|
+
expect(subject.examples).to eq([
|
|
111
|
+
'--example 1',
|
|
112
|
+
'--example 2'
|
|
113
|
+
])
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
it "must not change the superclass'es examples" do
|
|
117
|
+
expect(super_subject.examples).to be_nil
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
context "when both the subclass overrides the superclass's exampless" do
|
|
122
|
+
module TestExamples
|
|
123
|
+
class ExplicitOverridingInheritedCmd < ExplicitBaseCmd
|
|
124
|
+
examples [
|
|
125
|
+
'--example override'
|
|
126
|
+
]
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
let(:super_subject) { TestExamples::ExplicitBaseCmd }
|
|
131
|
+
subject { TestExamples::ExplicitOverridingInheritedCmd }
|
|
132
|
+
|
|
133
|
+
it "must return the subclass'es examples" do
|
|
134
|
+
expect(subject.examples).to eq([
|
|
135
|
+
'--example override'
|
|
136
|
+
])
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
it "must not change the superclass'es examples" do
|
|
140
|
+
expect(super_subject.examples).to eq([
|
|
141
|
+
'--example 1',
|
|
142
|
+
'--example 2'
|
|
143
|
+
])
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
subject { command_class.new }
|
|
150
|
+
|
|
151
|
+
describe "#examples" do
|
|
152
|
+
it "must be the same as .examples" do
|
|
153
|
+
expect(subject.examples).to eq(command_class.examples)
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
describe "#help_examples" do
|
|
158
|
+
context "when #examples returns nil" do
|
|
159
|
+
module TestExamples
|
|
160
|
+
class NoExamples
|
|
161
|
+
include CommandKit::Examples
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
let(:command_class) { TestExamples::NoExamples }
|
|
166
|
+
subject { command_class.new }
|
|
167
|
+
|
|
168
|
+
it "must print out the examples" do
|
|
169
|
+
expect { subject.help_examples }.to_not output.to_stdout
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
context "when #examples returns an Array" do
|
|
174
|
+
module TestExamples
|
|
175
|
+
class MultipleExamples
|
|
176
|
+
include CommandKit::Examples
|
|
177
|
+
|
|
178
|
+
examples [
|
|
179
|
+
'--example 1',
|
|
180
|
+
'--example 2',
|
|
181
|
+
'--example 3'
|
|
182
|
+
]
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
let(:command_class) { TestExamples::MultipleExamples }
|
|
187
|
+
subject { command_class.new }
|
|
188
|
+
|
|
189
|
+
it "must print out the 'Examples:' section header and the examples" do
|
|
190
|
+
expect { subject.help_examples }.to output(
|
|
191
|
+
[
|
|
192
|
+
'',
|
|
193
|
+
"Examples:",
|
|
194
|
+
" #{subject.command_name} #{subject.examples[0]}",
|
|
195
|
+
" #{subject.command_name} #{subject.examples[1]}",
|
|
196
|
+
" #{subject.command_name} #{subject.examples[2]}",
|
|
197
|
+
''
|
|
198
|
+
].join($/)
|
|
199
|
+
).to_stdout
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
describe "#help" do
|
|
205
|
+
it "must call #help_examples" do
|
|
206
|
+
expect(subject).to receive(:help_examples)
|
|
207
|
+
|
|
208
|
+
subject.help
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
context "when the superclass defines it's own #help method" do
|
|
212
|
+
module TestDescription
|
|
213
|
+
class SuperclassHelpMethod
|
|
214
|
+
def help
|
|
215
|
+
puts 'superclass'
|
|
216
|
+
end
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
class InheritedHelpMethod < SuperclassHelpMethod
|
|
220
|
+
include CommandKit::Examples
|
|
221
|
+
end
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
let(:super_command_class) { TestDescription::SuperclassHelpMethod }
|
|
225
|
+
let(:command_class) { TestDescription::InheritedHelpMethod }
|
|
226
|
+
|
|
227
|
+
it "must call the superclass'es #help method first" do
|
|
228
|
+
expect_any_instance_of(super_command_class).to receive(:help)
|
|
229
|
+
expect(subject).to receive(:help_examples)
|
|
230
|
+
|
|
231
|
+
subject.help
|
|
232
|
+
end
|
|
233
|
+
end
|
|
234
|
+
end
|
|
235
|
+
end
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'command_kit/exception_handler'
|
|
3
|
+
|
|
4
|
+
describe CommandKit::ExceptionHandler do
|
|
5
|
+
module TestExceptionHandler
|
|
6
|
+
class TestIncludedCmd
|
|
7
|
+
|
|
8
|
+
include CommandKit::Main
|
|
9
|
+
include CommandKit::ExceptionHandler
|
|
10
|
+
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
let(:command_class) { TestExceptionHandler::TestIncludedCmd }
|
|
15
|
+
subject { command_class.new }
|
|
16
|
+
|
|
17
|
+
describe ".included" do
|
|
18
|
+
it "must include CommandKit::Printing" do
|
|
19
|
+
expect(command_class).to be_include(CommandKit::Printing)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
describe "#main" do
|
|
24
|
+
context "when the #main method rescues an Interrupt" do
|
|
25
|
+
module TestExceptionHandler
|
|
26
|
+
class RaisesInterruptCmd
|
|
27
|
+
|
|
28
|
+
include CommandKit::Main
|
|
29
|
+
include CommandKit::ExceptionHandler
|
|
30
|
+
|
|
31
|
+
def run
|
|
32
|
+
raise(Interrupt.new)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
let(:command_class) { TestExceptionHandler::RaisesInterruptCmd }
|
|
39
|
+
subject { command_class.new }
|
|
40
|
+
|
|
41
|
+
it "must re-raise the Interrupt exception" do
|
|
42
|
+
expect { subject.main }.to raise_error(Interrupt)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
context "when the #main method raises an Errno::EPIPE" do
|
|
47
|
+
module TestExceptionHandler
|
|
48
|
+
class RaisesErrnoEPIPECmd
|
|
49
|
+
|
|
50
|
+
include CommandKit::Main
|
|
51
|
+
include CommandKit::ExceptionHandler
|
|
52
|
+
|
|
53
|
+
def run
|
|
54
|
+
raise(Errno::EPIPE.new)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
let(:command_class) { TestExceptionHandler::RaisesErrnoEPIPECmd }
|
|
61
|
+
subject { command_class.new }
|
|
62
|
+
|
|
63
|
+
it "must re-raise the Errno::EPIPE exception" do
|
|
64
|
+
expect { subject.main }.to raise_error(Errno::EPIPE)
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
context "when the #main method raises another Exception" do
|
|
69
|
+
module TestExceptionHandler
|
|
70
|
+
class RaisesExceptionCmd
|
|
71
|
+
|
|
72
|
+
include CommandKit::Main
|
|
73
|
+
include CommandKit::ExceptionHandler
|
|
74
|
+
|
|
75
|
+
def run
|
|
76
|
+
raise(RuntimeError.new("error"))
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
let(:command_class) { TestExceptionHandler::RaisesExceptionCmd }
|
|
83
|
+
subject { command_class.new }
|
|
84
|
+
|
|
85
|
+
it "must rescue the exception and call #on_exception" do
|
|
86
|
+
expect(subject).to receive(:on_exception).with(RuntimeError)
|
|
87
|
+
|
|
88
|
+
subject.main
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
describe "#on_exception" do
|
|
94
|
+
let(:error) { RuntimeError.new('error') }
|
|
95
|
+
|
|
96
|
+
it "must call #print_exception and exit with 1" do
|
|
97
|
+
expect(subject).to receive(:print_exception).with(error)
|
|
98
|
+
expect(subject).to receive(:exit).with(1)
|
|
99
|
+
|
|
100
|
+
subject.on_exception(error)
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|