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,67 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'command_kit/options/option_value'
|
|
3
|
+
|
|
4
|
+
describe Options::OptionValue do
|
|
5
|
+
let(:type) { Integer }
|
|
6
|
+
let(:usage) { 'COUNT' }
|
|
7
|
+
let(:required) { true }
|
|
8
|
+
let(:default) { 1 }
|
|
9
|
+
|
|
10
|
+
describe "#initialize" do
|
|
11
|
+
context "when the type: keyword is given" do
|
|
12
|
+
let(:type) { Integer }
|
|
13
|
+
|
|
14
|
+
subject { described_class.new(type: type) }
|
|
15
|
+
|
|
16
|
+
it "must default #type to String" do
|
|
17
|
+
expect(subject.type).to eq(type)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
context "when the type: keyword is not given" do
|
|
22
|
+
subject { described_class.new }
|
|
23
|
+
|
|
24
|
+
it "must default #type to String" do
|
|
25
|
+
expect(subject.type).to eq(String)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
context "when the usage: keyword is given" do
|
|
30
|
+
let(:usage) { 'FOO' }
|
|
31
|
+
|
|
32
|
+
subject { described_class.new(usage: usage) }
|
|
33
|
+
|
|
34
|
+
it "must default #usage to String" do
|
|
35
|
+
expect(subject.usage).to eq(usage)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
context "when the usage: keyword is not given" do
|
|
40
|
+
subject { described_class.new }
|
|
41
|
+
|
|
42
|
+
it "must default #usage based on #type" do
|
|
43
|
+
expect(subject.usage).to eq(described_class.default_usage(subject.type))
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
describe "#usage" do
|
|
49
|
+
let(:usage) { 'FOO' }
|
|
50
|
+
|
|
51
|
+
context "when #optional? is true" do
|
|
52
|
+
subject { described_class.new(usage: usage, required: false) }
|
|
53
|
+
|
|
54
|
+
it "must wrap the usage within [ ] brackets" do
|
|
55
|
+
expect(subject.usage).to eq("[#{usage}]")
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
context "when #optional? is false" do
|
|
60
|
+
subject { described_class.new(usage: usage, required: true) }
|
|
61
|
+
|
|
62
|
+
it "should return the usage string unchanged" do
|
|
63
|
+
expect(subject.usage).to eq(usage)
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'command_kit/options/parser'
|
|
3
|
+
|
|
4
|
+
describe CommandKit::Options::Parser do
|
|
5
|
+
module TestOptionsParser
|
|
6
|
+
class TestCommand
|
|
7
|
+
include CommandKit::Options::Parser
|
|
8
|
+
|
|
9
|
+
command_name 'cmd'
|
|
10
|
+
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
let(:command_class) { TestOptionsParser::TestCommand }
|
|
15
|
+
|
|
16
|
+
describe ".included" do
|
|
17
|
+
subject { command_class }
|
|
18
|
+
|
|
19
|
+
it { expect(subject).to include(CommandKit::Main) }
|
|
20
|
+
it { expect(subject).to include(CommandKit::Usage) }
|
|
21
|
+
it { expect(subject.usage).to eq('[options]') }
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
subject { command_class.new }
|
|
25
|
+
|
|
26
|
+
describe "#initialize" do
|
|
27
|
+
it "must initialize #option_parser" do
|
|
28
|
+
expect(subject.option_parser).to be_kind_of(OptionParser)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
describe "#option_parser" do
|
|
33
|
+
it "must have a default #banner" do
|
|
34
|
+
expect(subject.option_parser.banner).to eq("Usage: #{subject.usage}")
|
|
35
|
+
end
|
|
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
|
+
it "must define a default --help option" do
|
|
48
|
+
expect(subject.option_parser.to_s).to include(
|
|
49
|
+
[
|
|
50
|
+
'',
|
|
51
|
+
' -h, --help Print help information',
|
|
52
|
+
''
|
|
53
|
+
].join($/)
|
|
54
|
+
)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
module TestOptionsParser
|
|
59
|
+
class CommandWithOptions
|
|
60
|
+
|
|
61
|
+
include CommandKit::Options::Parser
|
|
62
|
+
|
|
63
|
+
command_name 'cmd'
|
|
64
|
+
|
|
65
|
+
attr_reader :foo
|
|
66
|
+
|
|
67
|
+
attr_reader :bar
|
|
68
|
+
|
|
69
|
+
attr_reader :argv
|
|
70
|
+
|
|
71
|
+
def initialize(**kwargs)
|
|
72
|
+
super(**kwargs)
|
|
73
|
+
|
|
74
|
+
@option_parser.on('-f','--foo','Foo option') do
|
|
75
|
+
@foo = true
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
@option_parser.on('-b','--bar BAR',Integer,'Bar option') do |bar|
|
|
79
|
+
@bar = bar
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def run(*argv)
|
|
84
|
+
@argv = argv
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
let(:command_class) { TestOptionsParser::CommandWithOptions }
|
|
91
|
+
subject { command_class.new }
|
|
92
|
+
|
|
93
|
+
describe "#option_parser" do
|
|
94
|
+
it { expect(subject.option_parser).to be_kind_of(OptionParser) }
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
describe "#main" do
|
|
98
|
+
context "when --help is given as an argument" do
|
|
99
|
+
it "must call #help" do
|
|
100
|
+
expect(subject).to receive(:help)
|
|
101
|
+
|
|
102
|
+
subject.main(['--help'])
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
it "must return 0" do
|
|
106
|
+
allow(subject).to receive(:help)
|
|
107
|
+
|
|
108
|
+
expect(subject.main(['--help'])).to eq(0)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
it "must stop parsing options" do
|
|
112
|
+
allow(subject).to receive(:help)
|
|
113
|
+
subject.main(['--help', '--foo', '1'])
|
|
114
|
+
|
|
115
|
+
expect(subject.foo).to be(nil)
|
|
116
|
+
expect(subject.argv).to be(nil)
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
describe "#parse_options" do
|
|
122
|
+
it "must parse options and return any additional arguments" do
|
|
123
|
+
additional_args = %w[arg1 arg2]
|
|
124
|
+
bar = 2
|
|
125
|
+
argv = ['--foo', '--bar', bar.to_s, *additional_args]
|
|
126
|
+
|
|
127
|
+
expect(subject.parse_options(argv)).to eq(additional_args)
|
|
128
|
+
expect(subject.foo).to eq(true)
|
|
129
|
+
expect(subject.bar).to eq(bar)
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
context "when -h,--help is passed" do
|
|
133
|
+
it "must call #help and exit with 0" do
|
|
134
|
+
expect(subject).to receive(:help)
|
|
135
|
+
expect(subject).to receive(:exit).with(0)
|
|
136
|
+
|
|
137
|
+
subject.parse_options(['--help'])
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
context "when an invalid option is given" do
|
|
142
|
+
it "must call #on_invalid_option" do
|
|
143
|
+
expect(subject).to receive(:on_invalid_option).with(OptionParser::InvalidOption)
|
|
144
|
+
|
|
145
|
+
subject.parse_options(['--xxx'])
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
context "when an invalid argument is given" do
|
|
150
|
+
it "must call #on_invalid_argument" do
|
|
151
|
+
expect(subject).to receive(:on_invalid_argument).with(OptionParser::InvalidArgument)
|
|
152
|
+
|
|
153
|
+
subject.parse_options(['--bar', 'xxx'])
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
context "when a required argument is missing" do
|
|
158
|
+
it "must call #on_missing_argument" do
|
|
159
|
+
expect(subject).to receive(:on_missing_argument).with(OptionParser::MissingArgument)
|
|
160
|
+
|
|
161
|
+
subject.parse_options(['--bar'])
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
context "when a needless argument is given" do
|
|
166
|
+
it "must call #on_needless_argument" do
|
|
167
|
+
expect(subject).to receive(:on_needless_argument).with(OptionParser::NeedlessArgument)
|
|
168
|
+
|
|
169
|
+
subject.parse_options(['--foo=xxx'])
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
describe "#on_parse_error" do
|
|
175
|
+
let(:error) { OptionParser::InvalidOption.new("--xxx") }
|
|
176
|
+
|
|
177
|
+
it "must print an error message and exit with 1" do
|
|
178
|
+
expect(subject).to receive(:exit).with(1)
|
|
179
|
+
|
|
180
|
+
expect { subject.on_parse_error(error) }.to output(
|
|
181
|
+
[
|
|
182
|
+
"#{subject.command_name}: #{error.message}",
|
|
183
|
+
"Try '#{subject.command_name} --help' for more information.",
|
|
184
|
+
''
|
|
185
|
+
].join($/)
|
|
186
|
+
).to_stderr
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
describe "#on_invalid_option" do
|
|
191
|
+
let(:error) { OptionParser::InvalidOption.new('--xxx') }
|
|
192
|
+
|
|
193
|
+
it "must call #on_parse_error by default" do
|
|
194
|
+
expect(subject).to receive(:on_parse_error).with(error)
|
|
195
|
+
|
|
196
|
+
subject.on_invalid_option(error)
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
describe "#on_ambiguous_option" do
|
|
201
|
+
let(:error) { OptionParser::AmbiguousOption.new('--xxx') }
|
|
202
|
+
|
|
203
|
+
it "must call #on_parse_error by default" do
|
|
204
|
+
expect(subject).to receive(:on_parse_error).with(error)
|
|
205
|
+
|
|
206
|
+
subject.on_ambiguous_option(error)
|
|
207
|
+
end
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
describe "#on_invalid_argument" do
|
|
211
|
+
let(:error) { OptionParser::InvalidArgument.new('--xxx') }
|
|
212
|
+
|
|
213
|
+
it "must call #on_parse_error by default" do
|
|
214
|
+
expect(subject).to receive(:on_parse_error).with(error)
|
|
215
|
+
|
|
216
|
+
subject.on_invalid_argument(error)
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
describe "#on_missing_argument" do
|
|
221
|
+
let(:error) { OptionParser::MissingArgument.new('--xxx') }
|
|
222
|
+
|
|
223
|
+
it "must call #on_parse_error by default" do
|
|
224
|
+
expect(subject).to receive(:on_parse_error).with(error)
|
|
225
|
+
|
|
226
|
+
subject.on_missing_argument(error)
|
|
227
|
+
end
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
describe "#on_needless_argument" do
|
|
231
|
+
let(:error) { OptionParser::NeedlessArgument.new('--xxx') }
|
|
232
|
+
|
|
233
|
+
it "must call #on_parse_error by default" do
|
|
234
|
+
expect(subject).to receive(:on_parse_error).with(error)
|
|
235
|
+
|
|
236
|
+
subject.on_needless_argument(error)
|
|
237
|
+
end
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
describe "#on_ambiguous_argument" do
|
|
241
|
+
let(:error) { OptionParser::AmbiguousArgument.new('--xxx') }
|
|
242
|
+
|
|
243
|
+
it "must call #on_parse_error by default" do
|
|
244
|
+
expect(subject).to receive(:on_parse_error).with(error)
|
|
245
|
+
|
|
246
|
+
subject.on_ambiguous_argument(error)
|
|
247
|
+
end
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
describe "#help_options" do
|
|
251
|
+
it "must print the #option_parser" do
|
|
252
|
+
expect { subject.help_options }.to output(
|
|
253
|
+
subject.option_parser.to_s
|
|
254
|
+
).to_stdout
|
|
255
|
+
end
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
describe "#help" do
|
|
259
|
+
it "must call #help_options" do
|
|
260
|
+
expect(subject).to receive(:help_options)
|
|
261
|
+
|
|
262
|
+
subject.help
|
|
263
|
+
end
|
|
264
|
+
end
|
|
265
|
+
end
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'command_kit/options'
|
|
3
|
+
|
|
4
|
+
describe Options do
|
|
5
|
+
module TestOptions
|
|
6
|
+
class ImplicitCmd
|
|
7
|
+
include CommandKit::Options
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
let(:command_class) { TestOptions::ImplicitCmd }
|
|
12
|
+
subject { command_class.new }
|
|
13
|
+
|
|
14
|
+
describe ".options" do
|
|
15
|
+
subject { TestOptions::ImplicitCmd }
|
|
16
|
+
|
|
17
|
+
context "when no options have been defined" do
|
|
18
|
+
it "should default to {}" do
|
|
19
|
+
expect(subject.options).to eq({})
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
context "when a options is explicitly set" do
|
|
24
|
+
module TestOptions
|
|
25
|
+
class ExplicitCmd
|
|
26
|
+
include CommandKit::Options
|
|
27
|
+
option :foo, desc: 'Foo option'
|
|
28
|
+
option :bar, desc: 'Bar option'
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
subject { TestOptions::ExplicitCmd }
|
|
33
|
+
|
|
34
|
+
it "must return the explicitly set options" do
|
|
35
|
+
expect(subject.options.keys).to eq([:foo, :bar])
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
context "when the command class inherites from another class" do
|
|
40
|
+
context "but no options are defined" do
|
|
41
|
+
module TestOptions
|
|
42
|
+
class BaseCmd
|
|
43
|
+
include CommandKit::Options
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
class InheritedCmd < BaseCmd
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
subject { TestOptions::InheritedCmd }
|
|
51
|
+
|
|
52
|
+
it "must search each class then return {}"do
|
|
53
|
+
expect(subject.options).to eq({})
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
module TestOptions
|
|
58
|
+
class ExplicitBaseCmd
|
|
59
|
+
include CommandKit::Options
|
|
60
|
+
option :foo, desc: 'Foo option'
|
|
61
|
+
option :bar, desc: 'Bar option'
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
context "when the superclass defines options" do
|
|
66
|
+
module TestOptions
|
|
67
|
+
class ImplicitInheritedCmd < ExplicitBaseCmd
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
let(:super_subject) { TestOptions::ExplicitBaseCmd }
|
|
72
|
+
subject { TestOptions::ImplicitInheritedCmd }
|
|
73
|
+
|
|
74
|
+
it "must inherit the superclass'es options" do
|
|
75
|
+
expect(subject.options).to eq(super_subject.options)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
it "must not change the superclass'es options" do
|
|
79
|
+
expect(super_subject.options.keys).to eq([:foo, :bar])
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
context "when the subclass defines options" do
|
|
84
|
+
module TestOptions
|
|
85
|
+
class ImplicitBaseCmd
|
|
86
|
+
include CommandKit::Options
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
class ExplicitInheritedCmd < ImplicitBaseCmd
|
|
90
|
+
option :baz, desc: 'Baz option'
|
|
91
|
+
option :qux, desc: 'Qux option'
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
let(:super_subject) { TestOptions::ImplicitBaseCmd }
|
|
96
|
+
subject { TestOptions::ExplicitInheritedCmd }
|
|
97
|
+
|
|
98
|
+
it "must return the subclass'es options" do
|
|
99
|
+
expect(subject.options.keys).to eq([:baz, :qux])
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
it "must not change the superclass'es options" do
|
|
103
|
+
expect(super_subject.options).to eq({})
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
context "when subclass overrides the superclass's optionss" do
|
|
108
|
+
module TestOptions
|
|
109
|
+
class ExplicitOverridingInheritedCmd < ExplicitBaseCmd
|
|
110
|
+
option :foo, desc: "Overriden foo option"
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
let(:super_subject) { TestOptions::ExplicitBaseCmd }
|
|
115
|
+
subject { TestOptions::ExplicitOverridingInheritedCmd }
|
|
116
|
+
|
|
117
|
+
it "must combine the superclass'es options with the subclass'es" do
|
|
118
|
+
expect(subject.options.keys).to eq([:foo, :bar])
|
|
119
|
+
expect(subject.options[:foo].desc).to eq("Overriden foo option")
|
|
120
|
+
expect(subject.options[:bar].desc).to eq("Bar option")
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
it "must not change the superclass'es options" do
|
|
124
|
+
expect(super_subject.options.keys).to eq([:foo, :bar])
|
|
125
|
+
expect(super_subject.options[:foo].desc).to eq("Foo option")
|
|
126
|
+
expect(super_subject.options[:bar].desc).to eq("Bar option")
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
describe "#initialize" do
|
|
133
|
+
it "must initialize #options" do
|
|
134
|
+
expect(subject.options).to eq({})
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
end
|