hammer_cli 0.19.2 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/hammer-complete +28 -0
- data/config/cli_config.template.yml +2 -0
- data/config/hammer.completion +5 -0
- data/doc/creating_commands.md +27 -0
- data/doc/installation.md +47 -4
- data/doc/release_notes.md +17 -9
- data/lib/hammer_cli.rb +1 -0
- data/lib/hammer_cli/abstract.rb +32 -2
- data/lib/hammer_cli/apipie/api_connection.rb +5 -1
- data/lib/hammer_cli/apipie/command.rb +3 -2
- data/lib/hammer_cli/bash.rb +2 -0
- data/lib/hammer_cli/bash/completion.rb +159 -0
- data/lib/hammer_cli/bash/prebuild_command.rb +21 -0
- data/lib/hammer_cli/connection.rb +4 -0
- data/lib/hammer_cli/exception_handler.rb +10 -1
- data/lib/hammer_cli/main.rb +5 -3
- data/lib/hammer_cli/options/normalizers.rb +7 -3
- data/lib/hammer_cli/options/option_definition.rb +22 -0
- data/lib/hammer_cli/output/adapter/abstract.rb +1 -5
- data/lib/hammer_cli/output/adapter/base.rb +1 -1
- data/lib/hammer_cli/output/adapter/csv.rb +3 -2
- data/lib/hammer_cli/output/adapter/json.rb +14 -3
- data/lib/hammer_cli/output/adapter/silent.rb +1 -1
- data/lib/hammer_cli/output/adapter/table.rb +26 -7
- data/lib/hammer_cli/output/adapter/yaml.rb +6 -3
- data/lib/hammer_cli/output/output.rb +2 -4
- data/lib/hammer_cli/settings.rb +2 -1
- data/lib/hammer_cli/utils.rb +5 -0
- data/lib/hammer_cli/version.rb +1 -1
- data/locale/ca/LC_MESSAGES/hammer-cli.mo +0 -0
- data/locale/de/LC_MESSAGES/hammer-cli.mo +0 -0
- data/locale/en/LC_MESSAGES/hammer-cli.mo +0 -0
- data/locale/en_GB/LC_MESSAGES/hammer-cli.mo +0 -0
- data/locale/es/LC_MESSAGES/hammer-cli.mo +0 -0
- data/locale/fr/LC_MESSAGES/hammer-cli.mo +0 -0
- data/locale/it/LC_MESSAGES/hammer-cli.mo +0 -0
- data/locale/ja/LC_MESSAGES/hammer-cli.mo +0 -0
- data/locale/ko/LC_MESSAGES/hammer-cli.mo +0 -0
- data/locale/pt_BR/LC_MESSAGES/hammer-cli.mo +0 -0
- data/locale/ru/LC_MESSAGES/hammer-cli.mo +0 -0
- data/locale/zh_CN/LC_MESSAGES/hammer-cli.mo +0 -0
- data/locale/zh_TW/LC_MESSAGES/hammer-cli.mo +0 -0
- data/man/hammer.1.gz +0 -0
- data/test/unit/apipie/api_connection_test.rb +1 -0
- data/test/unit/bash_test.rb +138 -0
- data/test/unit/exception_handler_test.rb +44 -0
- data/test/unit/output/adapter/base_test.rb +58 -0
- data/test/unit/output/adapter/csv_test.rb +63 -1
- data/test/unit/output/adapter/json_test.rb +61 -0
- data/test/unit/output/adapter/table_test.rb +70 -1
- data/test/unit/output/adapter/yaml_test.rb +59 -0
- data/test/unit/output/output_test.rb +3 -3
- metadata +75 -68
- data/hammer_cli_complete +0 -13
@@ -0,0 +1,21 @@
|
|
1
|
+
module HammerCLI
|
2
|
+
module Bash
|
3
|
+
class PrebuildCompletionCommand < HammerCLI::AbstractCommand
|
4
|
+
def execute
|
5
|
+
map = HammerCLI::MainCommand.completion_map
|
6
|
+
cache_file = HammerCLI::Settings.get(:completion_cache_file)
|
7
|
+
cache_dir = File.dirname(cache_file)
|
8
|
+
FileUtils.mkdir_p(cache_dir) unless File.directory?(cache_dir)
|
9
|
+
File.write(File.expand_path(cache_file), map.to_json)
|
10
|
+
|
11
|
+
HammerCLI::EX_OK
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
HammerCLI::MainCommand.subcommand(
|
17
|
+
'prebuild-bash-completion',
|
18
|
+
_('Prepare map of options and subcommands for Bash completion'),
|
19
|
+
HammerCLI::Bash::PrebuildCompletionCommand
|
20
|
+
)
|
21
|
+
end
|
@@ -138,7 +138,16 @@ module HammerCLI
|
|
138
138
|
end
|
139
139
|
|
140
140
|
def handle_apipie_missing_arguments_error(e)
|
141
|
-
|
141
|
+
params = e.params.map do |p|
|
142
|
+
param = p[/\[.+\]/]
|
143
|
+
param = if param.nil?
|
144
|
+
p.tr('_', '-')
|
145
|
+
else
|
146
|
+
p.scan(/\[[^\[\]]+\]/).first[1...-1].tr('_', '-')
|
147
|
+
end
|
148
|
+
"--#{param}"
|
149
|
+
end
|
150
|
+
message = _("Missing arguments for %s.") % "'#{params.uniq.join("', '")}'"
|
142
151
|
print_error message
|
143
152
|
log_full_error e, message
|
144
153
|
HammerCLI::EX_USAGE
|
data/lib/hammer_cli/main.rb
CHANGED
@@ -47,9 +47,11 @@ module HammerCLI
|
|
47
47
|
:context_target => :interactive
|
48
48
|
option ["--no-headers"], :flag, _("Hide headers from output")
|
49
49
|
option ["--csv"], :flag, _("Output as CSV (same as --output=csv)")
|
50
|
-
option [
|
51
|
-
format: HammerCLI::Options::Normalizers::Enum.new(
|
52
|
-
|
50
|
+
option ['--output'], 'ADAPTER', _('Set output format'),
|
51
|
+
format: HammerCLI::Options::Normalizers::Enum.new(
|
52
|
+
HammerCLI::Output::Output.adapters.keys.map(&:to_s)
|
53
|
+
),
|
54
|
+
context_target: :adapter
|
53
55
|
option ["--output-file"], "OUTPUT_FILE", _("Path to custom output file") do |filename|
|
54
56
|
begin
|
55
57
|
context[:output_file] = File.new(filename, 'w')
|
@@ -111,10 +111,10 @@ module HammerCLI
|
|
111
111
|
|
112
112
|
class ListNested < AbstractNormalizer
|
113
113
|
class Schema < Array
|
114
|
-
def description
|
114
|
+
def description(richtext: true)
|
115
115
|
'"' + reduce([]) do |schema, nested_param|
|
116
116
|
name = nested_param.name
|
117
|
-
name = HighLine.color(name, :bold) if nested_param.required?
|
117
|
+
name = HighLine.color(name, :bold) if nested_param.required? && richtext
|
118
118
|
values = nested_param.validator.scan(/<[^>]+>[\w]+<\/?[^>]+>/)
|
119
119
|
value_pattern = if values.empty?
|
120
120
|
"<#{nested_param.expected_type.downcase}>"
|
@@ -172,6 +172,9 @@ module HammerCLI
|
|
172
172
|
|
173
173
|
|
174
174
|
class Bool < AbstractNormalizer
|
175
|
+
def allowed_values
|
176
|
+
['yes', 'no', 'true', 'false', '1', '0']
|
177
|
+
end
|
175
178
|
|
176
179
|
def description
|
177
180
|
_('One of %s.') % ['true/false', 'yes/no', '1/0'].join(', ')
|
@@ -189,7 +192,7 @@ module HammerCLI
|
|
189
192
|
end
|
190
193
|
|
191
194
|
def complete(value)
|
192
|
-
|
195
|
+
allowed_values.map { |v| v + ' ' }
|
193
196
|
end
|
194
197
|
end
|
195
198
|
|
@@ -280,6 +283,7 @@ module HammerCLI
|
|
280
283
|
end
|
281
284
|
|
282
285
|
class EnumList < AbstractNormalizer
|
286
|
+
attr_reader :allowed_values
|
283
287
|
|
284
288
|
def initialize(allowed_values)
|
285
289
|
@allowed_values = allowed_values
|
@@ -138,6 +138,28 @@ module HammerCLI
|
|
138
138
|
end
|
139
139
|
end
|
140
140
|
|
141
|
+
def completion_type(formatter = nil)
|
142
|
+
return { type: :flag } if @type == :flag
|
143
|
+
|
144
|
+
formatter ||= value_formatter
|
145
|
+
completion_type = case formatter
|
146
|
+
when HammerCLI::Options::Normalizers::Bool,
|
147
|
+
HammerCLI::Options::Normalizers::Enum
|
148
|
+
{ type: :enum, values: value_formatter.allowed_values }
|
149
|
+
when HammerCLI::Options::Normalizers::EnumList
|
150
|
+
{ type: :multienum, values: value_formatter.allowed_values }
|
151
|
+
when HammerCLI::Options::Normalizers::ListNested
|
152
|
+
{ type: :schema, schema: value_formatter.schema.description(richtext: false) }
|
153
|
+
when HammerCLI::Options::Normalizers::List
|
154
|
+
{ type: :list }
|
155
|
+
when HammerCLI::Options::Normalizers::KeyValueList
|
156
|
+
{ type: :key_value_list }
|
157
|
+
when HammerCLI::Options::Normalizers::File
|
158
|
+
{ type: :file }
|
159
|
+
end
|
160
|
+
completion_type || { type: :value }
|
161
|
+
end
|
162
|
+
|
141
163
|
private
|
142
164
|
|
143
165
|
def format_deprecation_msg(option_desc, deprecation_msg)
|
@@ -44,14 +44,10 @@ module HammerCLI::Output::Adapter
|
|
44
44
|
raise NotImplementedError
|
45
45
|
end
|
46
46
|
|
47
|
-
def print_collection(fields, collection)
|
47
|
+
def print_collection(fields, collection, options = {})
|
48
48
|
raise NotImplementedError
|
49
49
|
end
|
50
50
|
|
51
|
-
def reset_context
|
52
|
-
@context.delete(:fields)
|
53
|
-
end
|
54
|
-
|
55
51
|
protected
|
56
52
|
|
57
53
|
def filter_fields(fields)
|
@@ -14,7 +14,7 @@ module HammerCLI::Output::Adapter
|
|
14
14
|
print_collection(fields, [record].flatten(1))
|
15
15
|
end
|
16
16
|
|
17
|
-
def print_collection(fields, collection)
|
17
|
+
def print_collection(fields, collection, options = {})
|
18
18
|
collection.each do |data|
|
19
19
|
output_stream.puts render_fields(fields, data)
|
20
20
|
output_stream.puts
|
@@ -149,7 +149,8 @@ module HammerCLI::Output::Adapter
|
|
149
149
|
print_collection(fields, [record].flatten(1))
|
150
150
|
end
|
151
151
|
|
152
|
-
def print_collection(fields, collection)
|
152
|
+
def print_collection(fields, collection, options = {})
|
153
|
+
current_chunk = options[:current_chunk] || :single
|
153
154
|
fields = filter_fields(fields).filter_by_classes
|
154
155
|
.filter_by_sets
|
155
156
|
.filter_by_data(collection.first,
|
@@ -161,7 +162,7 @@ module HammerCLI::Output::Adapter
|
|
161
162
|
# or use headers from output definition
|
162
163
|
headers ||= default_headers(fields)
|
163
164
|
csv_string = generate do |csv|
|
164
|
-
csv << headers if headers && !@context[:no_headers]
|
165
|
+
csv << headers if headers && !@context[:no_headers] && %i[first single].include?(current_chunk)
|
165
166
|
rows.each do |row|
|
166
167
|
csv << Cell.values(headers, row)
|
167
168
|
end
|
@@ -6,9 +6,20 @@ module HammerCLI::Output::Adapter
|
|
6
6
|
output_stream.puts JSON.pretty_generate(result.first)
|
7
7
|
end
|
8
8
|
|
9
|
-
def print_collection(fields, collection)
|
10
|
-
|
11
|
-
|
9
|
+
def print_collection(fields, collection, options = {})
|
10
|
+
current_chunk = options[:current_chunk] || :single
|
11
|
+
prepared = prepare_collection(fields, collection)
|
12
|
+
result = JSON.pretty_generate(prepared)
|
13
|
+
if current_chunk != :single
|
14
|
+
result = if current_chunk == :first
|
15
|
+
result[0...-2] + ','
|
16
|
+
elsif current_chunk == :last
|
17
|
+
result[2..-1]
|
18
|
+
else
|
19
|
+
result[2...-2] + ','
|
20
|
+
end
|
21
|
+
end
|
22
|
+
output_stream.puts result
|
12
23
|
end
|
13
24
|
|
14
25
|
def print_message(msg, msg_params={})
|
@@ -2,6 +2,11 @@ require File.join(File.dirname(__FILE__), 'wrapper_formatter')
|
|
2
2
|
|
3
3
|
module HammerCLI::Output::Adapter
|
4
4
|
class Table < Abstract
|
5
|
+
def initialize(context = {}, formatters = {}, filters = {})
|
6
|
+
super
|
7
|
+
@printed = 0
|
8
|
+
end
|
9
|
+
|
5
10
|
def features
|
6
11
|
return %i[rich_text serialized inline] if tags.empty?
|
7
12
|
|
@@ -12,7 +17,8 @@ module HammerCLI::Output::Adapter
|
|
12
17
|
print_collection(fields, [record].flatten(1))
|
13
18
|
end
|
14
19
|
|
15
|
-
def print_collection(all_fields, collection)
|
20
|
+
def print_collection(all_fields, collection, options = {})
|
21
|
+
current_chunk = options[:current_chunk] || :single
|
16
22
|
fields = filter_fields(all_fields).filter_by_classes
|
17
23
|
.filter_by_sets
|
18
24
|
.filter_by_data(collection.first,
|
@@ -27,13 +33,26 @@ module HammerCLI::Output::Adapter
|
|
27
33
|
table_gen = HammerCLI::Output::Generators::Table.new(
|
28
34
|
columns, formatted_collection, no_headers: @context[:no_headers]
|
29
35
|
)
|
30
|
-
output_stream.print(table_gen.result)
|
31
36
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
+
meta = collection.respond_to?(:meta) ? collection.meta : nil
|
38
|
+
|
39
|
+
output_stream.print(table_gen.header) if %i[first single].include?(current_chunk)
|
40
|
+
|
41
|
+
output_stream.print(table_gen.body)
|
42
|
+
|
43
|
+
@printed += collection.count
|
44
|
+
|
45
|
+
# print closing line only after the last chunk
|
46
|
+
output_stream.print(table_gen.footer) if %i[last single].include?(current_chunk)
|
47
|
+
|
48
|
+
return unless meta && meta.pagination_set?
|
49
|
+
|
50
|
+
leftovers = %i[last single].include?(current_chunk) && @printed < meta.subtotal
|
51
|
+
if @context[:verbosity] >= meta.pagination_verbosity &&
|
52
|
+
collection.count < meta.subtotal &&
|
53
|
+
leftovers
|
54
|
+
pages = (meta.subtotal.to_f / meta.per_page).ceil
|
55
|
+
puts _("Page %{page} of %{total} (use --page and --per-page for navigation).") % {:page => meta.page, :total => pages}
|
37
56
|
end
|
38
57
|
end
|
39
58
|
|
@@ -6,9 +6,12 @@ module HammerCLI::Output::Adapter
|
|
6
6
|
output_stream.puts YAML.dump(result.first)
|
7
7
|
end
|
8
8
|
|
9
|
-
def print_collection(fields, collection)
|
10
|
-
|
11
|
-
|
9
|
+
def print_collection(fields, collection, options = {})
|
10
|
+
current_chunk = options[:current_chunk] || :single
|
11
|
+
prepared = prepare_collection(fields, collection)
|
12
|
+
result = YAML.dump(prepared)
|
13
|
+
result = result[4..-1] unless %i[first single].include?(current_chunk)
|
14
|
+
output_stream.puts result
|
12
15
|
end
|
13
16
|
|
14
17
|
def print_message(msg, msg_params={})
|
@@ -25,15 +25,13 @@ module HammerCLI::Output
|
|
25
25
|
|
26
26
|
def print_record(definition, record)
|
27
27
|
adapter.print_record(definition.fields, record) if appropriate_verbosity?(:record)
|
28
|
-
adapter.reset_context
|
29
28
|
end
|
30
29
|
|
31
|
-
def print_collection(definition, collection)
|
30
|
+
def print_collection(definition, collection, options = {})
|
32
31
|
unless collection.class <= HammerCLI::Output::RecordCollection
|
33
32
|
collection = HammerCLI::Output::RecordCollection.new([collection].flatten(1))
|
34
33
|
end
|
35
|
-
adapter.print_collection(definition.fields, collection) if appropriate_verbosity?(:collection)
|
36
|
-
adapter.reset_context
|
34
|
+
adapter.print_collection(definition.fields, collection, options) if appropriate_verbosity?(:collection)
|
37
35
|
end
|
38
36
|
|
39
37
|
def adapter
|
data/lib/hammer_cli/settings.rb
CHANGED
data/lib/hammer_cli/utils.rb
CHANGED
@@ -60,6 +60,11 @@ module HammerCLI
|
|
60
60
|
STDOUT.tty?
|
61
61
|
end
|
62
62
|
|
63
|
+
def self.clear_cache
|
64
|
+
cache_file = File.expand_path(HammerCLI::Settings.get(:completion_cache_file))
|
65
|
+
File.delete(cache_file) if File.exist?(cache_file)
|
66
|
+
end
|
67
|
+
|
63
68
|
def self.interactive?
|
64
69
|
return HammerCLI::Settings.get(:_params, :interactive) unless HammerCLI::Settings.get(:_params, :interactive).nil?
|
65
70
|
HammerCLI::Settings.get(:ui, :interactive) != false
|
data/lib/hammer_cli/version.rb
CHANGED
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
data/man/hammer.1.gz
CHANGED
Binary file
|
@@ -30,6 +30,7 @@ describe HammerCLI::Apipie::ApiConnection do
|
|
30
30
|
it "logs message when logger is available" do
|
31
31
|
logger = stub()
|
32
32
|
logger.expects(:debug).with('Apipie cache was cleared')
|
33
|
+
logger.expects(:debug).with('Completion cache was cleared')
|
33
34
|
|
34
35
|
api_stub.expects(:clean_cache)
|
35
36
|
HammerCLI::Apipie::ApiConnection.new(empty_params, :reload_cache => true, :logger => logger)
|
@@ -0,0 +1,138 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
|
+
|
3
|
+
describe HammerCLI::Bash::Completion do
|
4
|
+
describe '#complete' do
|
5
|
+
let(:dict) do
|
6
|
+
{
|
7
|
+
'host' => {
|
8
|
+
'create' => {
|
9
|
+
'--installed-products-attributes' => { type: :schema, schema: '"product_id=string\,product_name=string\,arch=string\,version=string, ... "' },
|
10
|
+
'--help' => { type: :flag },
|
11
|
+
'--build' => { type: :flag },
|
12
|
+
'--managed' => { type: :enum, values: %w[yes no] },
|
13
|
+
'--volume' => { type: :multienum, values: %w[first second third] },
|
14
|
+
'--config-group-ids' => { type: :list },
|
15
|
+
'--params' => { type: :key_value_list },
|
16
|
+
'--log' => { type: :file, filter: '.*\.log$' },
|
17
|
+
'--pool' => { type: :directory },
|
18
|
+
'-t' => { type: :value },
|
19
|
+
:params => [{ type: :directory }, { type: :value }, { type: :file }]
|
20
|
+
},
|
21
|
+
'--dry' => { type: :flag },
|
22
|
+
'--help' => { type: :flag },
|
23
|
+
},
|
24
|
+
'--interactive' => { type: :enum, values: %w[yes no] },
|
25
|
+
'--help' => { type: :flag },
|
26
|
+
'-h' => { type: :flag }
|
27
|
+
}
|
28
|
+
end
|
29
|
+
|
30
|
+
subject do
|
31
|
+
HammerCLI::Bash::Completion.new(JSON.load(dict.to_json))
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'returns options when no input given' do
|
35
|
+
result = subject.complete('').sort
|
36
|
+
result.must_equal ['host ', '--interactive ', '--help ', '-h '].sort
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'returns filtered options when partial input is given' do
|
40
|
+
result = subject.complete('-').sort
|
41
|
+
result.must_equal ['--help ', '-h ', '--interactive '].sort
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'returns filtered options when partial input is given' do
|
45
|
+
result = subject.complete('host')
|
46
|
+
result.must_equal ['host ']
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'returns options when subcommand is given' do
|
50
|
+
result = subject.complete('host ').sort
|
51
|
+
result.must_equal ['create ', '--help ', '--dry '].sort
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'returns no options when subcommand is wrong' do
|
55
|
+
result = subject.complete('unknown -h')
|
56
|
+
result.must_equal []
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'returns no options when there are no other params allowed' do
|
60
|
+
result = subject.complete('host create /tmp some /tmp extra')
|
61
|
+
result.must_equal []
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'return hint for option-value pair without value' do
|
65
|
+
result = subject.complete('host create -t ')
|
66
|
+
result.must_equal ['--->', 'Add option <value>']
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'return no options for option-value pair without complete value' do
|
70
|
+
result = subject.complete('host create -t x')
|
71
|
+
result.must_equal []
|
72
|
+
end
|
73
|
+
|
74
|
+
# multiple options in one subcommand
|
75
|
+
it 'allows mutiple options of the same subcommand' do
|
76
|
+
result = subject.complete('host create --build --he')
|
77
|
+
result.must_equal ['--help ']
|
78
|
+
end
|
79
|
+
|
80
|
+
# multiple options with values in one subcommand
|
81
|
+
it 'allows mutiple options with values of the same subcommand' do
|
82
|
+
result = subject.complete('host create -t value --he')
|
83
|
+
result.must_equal ['--help ']
|
84
|
+
end
|
85
|
+
|
86
|
+
# subcommand after options
|
87
|
+
it 'allows subcommand after options' do
|
88
|
+
result = subject.complete('host --dry crea')
|
89
|
+
result.must_equal ['create ']
|
90
|
+
end
|
91
|
+
|
92
|
+
describe 'completion by type' do
|
93
|
+
it 'completes :value' do
|
94
|
+
result = subject.complete('host create -t ')
|
95
|
+
result.must_equal ['--->', 'Add option <value>']
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'completes :flag' do
|
99
|
+
result = subject.complete('host --h')
|
100
|
+
result.must_equal ['--help ']
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'completes :schema' do
|
104
|
+
result = subject.complete('host create --installed-products-attributes ')
|
105
|
+
result.must_equal ["--->", 'Add value by following schema: "product_id=string\,product_name=string\,arch=string\,version=string, ... "']
|
106
|
+
end
|
107
|
+
|
108
|
+
it 'completes :enum' do
|
109
|
+
result = subject.complete('host create --managed ')
|
110
|
+
result.must_equal ['yes ', 'no ']
|
111
|
+
end
|
112
|
+
|
113
|
+
it 'completes :multienum' do
|
114
|
+
result = subject.complete('host create --volume ')
|
115
|
+
result.must_equal ['first', 'second', 'third']
|
116
|
+
|
117
|
+
result = subject.complete('host create --volume fir')
|
118
|
+
result.must_equal ['first']
|
119
|
+
|
120
|
+
result = subject.complete('host create --volume first,')
|
121
|
+
result.must_equal ['second', 'third']
|
122
|
+
|
123
|
+
result = subject.complete('host create --volume first,se')
|
124
|
+
result.must_equal ['first,second']
|
125
|
+
end
|
126
|
+
|
127
|
+
it 'completes :list' do
|
128
|
+
result = subject.complete('host create --config-group-ids ')
|
129
|
+
result.must_equal ['--->', 'Add comma-separated list of values']
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'completes :key_value_list' do
|
133
|
+
result = subject.complete('host create --params ')
|
134
|
+
result.must_equal ['--->', 'Add comma-separated list of key=value']
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|