hammer_cli 0.19.2 → 2.0.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/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
|