hammer_cli 2.5.0 → 3.1.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.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/bin/hammer +1 -1
  3. data/doc/commands_extension.md +8 -6
  4. data/doc/creating_commands.md +17 -0
  5. data/doc/release_notes.md +23 -0
  6. data/lib/hammer_cli/abstract.rb +75 -60
  7. data/lib/hammer_cli/apipie/command.rb +1 -1
  8. data/lib/hammer_cli/apipie/option_builder.rb +16 -11
  9. data/lib/hammer_cli/apipie/option_definition.rb +1 -8
  10. data/lib/hammer_cli/command_extensions.rb +47 -34
  11. data/lib/hammer_cli/help/builder.rb +10 -6
  12. data/lib/hammer_cli/options/normalizers.rb +126 -18
  13. data/lib/hammer_cli/options/option_definition.rb +17 -22
  14. data/lib/hammer_cli/options/option_family.rb +44 -8
  15. data/lib/hammer_cli/output/adapter/abstract.rb +6 -0
  16. data/lib/hammer_cli/output/adapter/base.rb +1 -1
  17. data/lib/hammer_cli/output/adapter/tree_structure.rb +1 -1
  18. data/lib/hammer_cli/output/definition.rb +1 -1
  19. data/lib/hammer_cli/output/field_filter.rb +2 -2
  20. data/lib/hammer_cli/utils.rb +6 -0
  21. data/lib/hammer_cli/version.rb +1 -1
  22. data/locale/ca/LC_MESSAGES/hammer-cli.mo +0 -0
  23. data/locale/de/LC_MESSAGES/hammer-cli.mo +0 -0
  24. data/locale/en/LC_MESSAGES/hammer-cli.mo +0 -0
  25. data/locale/en_GB/LC_MESSAGES/hammer-cli.mo +0 -0
  26. data/locale/es/LC_MESSAGES/hammer-cli.mo +0 -0
  27. data/locale/fr/LC_MESSAGES/hammer-cli.mo +0 -0
  28. data/locale/it/LC_MESSAGES/hammer-cli.mo +0 -0
  29. data/locale/ja/LC_MESSAGES/hammer-cli.mo +0 -0
  30. data/locale/ko/LC_MESSAGES/hammer-cli.mo +0 -0
  31. data/locale/pt_BR/LC_MESSAGES/hammer-cli.mo +0 -0
  32. data/locale/ru/LC_MESSAGES/hammer-cli.mo +0 -0
  33. data/locale/zh_CN/LC_MESSAGES/hammer-cli.mo +0 -0
  34. data/locale/zh_TW/LC_MESSAGES/hammer-cli.mo +0 -0
  35. data/man/hammer.1.gz +0 -0
  36. data/test/unit/abstract_test.rb +7 -0
  37. data/test/unit/apipie/option_builder_test.rb +8 -3
  38. data/test/unit/command_extensions_test.rb +10 -2
  39. data/test/unit/help/builder_test.rb +20 -2
  40. data/test/unit/options/option_definition_test.rb +12 -1
  41. data/test/unit/output/definition_test.rb +3 -3
  42. metadata +22 -22
@@ -29,7 +29,11 @@ module HammerCLI
29
29
 
30
30
  label_width = DEFAULT_LABEL_INDENT
31
31
  items.each do |item|
32
- label = item.help.first
32
+ label = if !HammerCLI.context[:full_help] && item.respond_to?(:family) && item.family && !item.child?
33
+ item.family.help.first
34
+ else
35
+ item.help.first
36
+ end
33
37
  label_width = label.size if label.size > label_width
34
38
  end
35
39
 
@@ -38,11 +42,11 @@ module HammerCLI
38
42
  next unless HammerCLI.context[:full_help]
39
43
  end
40
44
  label, description = if !HammerCLI.context[:full_help] && item.respond_to?(:family) && item.family
41
- [item.family.switch, item.family.description || item.help[1]]
42
- else
43
- item.help
44
- end
45
- description.gsub(/^(.)/) { Unicode::capitalize($1) }.each_line do |line|
45
+ item.family.help
46
+ else
47
+ item.help
48
+ end
49
+ description.gsub(/^(.)/) { Unicode.capitalize(Regexp.last_match(1)) }.wrap.each_line do |line|
46
50
  puts " %-#{label_width}s %s" % [label, line]
47
51
  label = ''
48
52
  end
@@ -4,8 +4,28 @@ require 'hammer_cli/csv_parser'
4
4
  module HammerCLI
5
5
  module Options
6
6
  module Normalizers
7
+ def self.available
8
+ AbstractNormalizer.available
9
+ end
7
10
 
8
11
  class AbstractNormalizer
12
+ class << self
13
+ attr_reader :available
14
+
15
+ def inherited(subclass)
16
+ @available ||= []
17
+ @available << subclass
18
+ end
19
+
20
+ def completion_type
21
+ :value
22
+ end
23
+
24
+ def common_description
25
+ _("Value described in the option's description. Mostly simple string")
26
+ end
27
+ end
28
+
9
29
  def description
10
30
  ""
11
31
  end
@@ -17,6 +37,10 @@ module HammerCLI
17
37
  def complete(val)
18
38
  []
19
39
  end
40
+
41
+ def completion_type
42
+ { type: self.class.completion_type }
43
+ end
20
44
  end
21
45
 
22
46
  class Default < AbstractNormalizer
@@ -30,9 +54,15 @@ module HammerCLI
30
54
  PAIR_RE = '([^,=]+)=([^,\{\[]+|[\{\[][^\{\}\[\]]*[\}\]])'
31
55
  FULL_RE = "^((%s)[,]?)+$" % PAIR_RE
32
56
 
33
- def description
34
- _("Comma-separated list of key=value.") + "\n" +
35
- _("JSON is acceptable and preferred way for complex parameters")
57
+ class << self
58
+ def completion_type
59
+ :key_value_list
60
+ end
61
+
62
+ def common_description
63
+ _('Comma-separated list of key=value.') + "\n" +
64
+ _('JSON is acceptable and preferred way for such parameters')
65
+ end
36
66
  end
37
67
 
38
68
  def format(val)
@@ -94,9 +124,16 @@ module HammerCLI
94
124
 
95
125
 
96
126
  class List < AbstractNormalizer
97
- def description
98
- _("Comma separated list of values. Values containing comma should be quoted or escaped with backslash.") + "\n" +
99
- _("JSON is acceptable and preferred way for complex parameters")
127
+ class << self
128
+ def completion_type
129
+ :list
130
+ end
131
+
132
+ def common_description
133
+ _('Comma separated list of values. Values containing comma should be quoted or escaped with backslash.') +
134
+ "\n" +
135
+ _('JSON is acceptable and preferred way for such parameters')
136
+ end
100
137
  end
101
138
 
102
139
  def format(val)
@@ -110,6 +147,18 @@ module HammerCLI
110
147
  end
111
148
 
112
149
  class ListNested < AbstractNormalizer
150
+ class << self
151
+ def completion_type
152
+ :schema
153
+ end
154
+
155
+ def common_description
156
+ _('Comma separated list of values defined by a schema.') +
157
+ "\n" +
158
+ _('JSON is acceptable and preferred way for such parameters')
159
+ end
160
+ end
161
+
113
162
  class Schema < Array
114
163
  def description(richtext: true)
115
164
  '"' + reduce([]) do |schema, nested_param|
@@ -135,11 +184,6 @@ module HammerCLI
135
184
  @schema = Schema.new(schema)
136
185
  end
137
186
 
138
- def description
139
- _("Comma separated list of values defined by a schema. See Option details section below.") + "\n" +
140
- _("JSON is acceptable and preferred way for complex parameters")
141
- end
142
-
143
187
  def format(val)
144
188
  return [] unless val.is_a?(String) && !val.empty?
145
189
  begin
@@ -152,9 +196,22 @@ module HammerCLI
152
196
  end
153
197
  end
154
198
  end
199
+
200
+ def completion_type
201
+ super.merge({ schema: schema.description(richtext: false) })
202
+ end
155
203
  end
156
204
 
157
205
  class Number < AbstractNormalizer
206
+ class << self
207
+ def completion_type
208
+ :number
209
+ end
210
+
211
+ def common_description
212
+ _('Numeric value. Integer')
213
+ end
214
+ end
158
215
 
159
216
  def format(val)
160
217
  if numeric?(val)
@@ -167,17 +224,22 @@ module HammerCLI
167
224
  def numeric?(val)
168
225
  Integer(val) != nil rescue false
169
226
  end
170
-
171
227
  end
172
228
 
173
229
 
174
230
  class Bool < AbstractNormalizer
175
- def allowed_values
176
- ['yes', 'no', 'true', 'false', '1', '0']
231
+ class << self
232
+ def completion_type
233
+ :boolean
234
+ end
235
+
236
+ def common_description
237
+ _('One of %s') % ['true/false', 'yes/no', '1/0'].join(', ')
238
+ end
177
239
  end
178
240
 
179
- def description
180
- _('One of %s.') % ['true/false', 'yes/no', '1/0'].join(', ')
241
+ def allowed_values
242
+ ['yes', 'no', 'true', 'false', '1', '0']
181
243
  end
182
244
 
183
245
  def format(bool)
@@ -194,10 +256,23 @@ module HammerCLI
194
256
  def complete(value)
195
257
  allowed_values.map { |v| v + ' ' }
196
258
  end
259
+
260
+ def completion_type
261
+ super.merge({ values: allowed_values })
262
+ end
197
263
  end
198
264
 
199
265
 
200
266
  class File < AbstractNormalizer
267
+ class << self
268
+ def completion_type
269
+ :file
270
+ end
271
+
272
+ def common_description
273
+ _('Path to a file')
274
+ end
275
+ end
201
276
 
202
277
  def format(path)
203
278
  ::File.read(::File.expand_path(path))
@@ -233,6 +308,16 @@ module HammerCLI
233
308
 
234
309
 
235
310
  class Enum < AbstractNormalizer
311
+ class << self
312
+ def completion_type
313
+ :enum
314
+ end
315
+
316
+ def common_description
317
+ _("Possible values are described in the option's description")
318
+ end
319
+ end
320
+
236
321
  attr_reader :allowed_values
237
322
 
238
323
  def initialize(allowed_values)
@@ -260,6 +345,10 @@ module HammerCLI
260
345
  Completer::finalize_completions(@allowed_values)
261
346
  end
262
347
 
348
+ def completion_type
349
+ super.merge({ values: allowed_values })
350
+ end
351
+
263
352
  private
264
353
 
265
354
  def quoted_values
@@ -269,9 +358,14 @@ module HammerCLI
269
358
 
270
359
 
271
360
  class DateTime < AbstractNormalizer
361
+ class << self
362
+ def completion_type
363
+ :datetime
364
+ end
272
365
 
273
- def description
274
- _("Date and time in YYYY-MM-DD HH:MM:SS or ISO 8601 format")
366
+ def common_description
367
+ _('Date and time in YYYY-MM-DD HH:MM:SS or ISO 8601 format')
368
+ end
275
369
  end
276
370
 
277
371
  def format(date)
@@ -283,6 +377,16 @@ module HammerCLI
283
377
  end
284
378
 
285
379
  class EnumList < AbstractNormalizer
380
+ class << self
381
+ def completion_type
382
+ :multienum
383
+ end
384
+
385
+ def common_description
386
+ _("Any combination of possible values described in the option's description")
387
+ end
388
+ end
389
+
286
390
  attr_reader :allowed_values
287
391
 
288
392
  def initialize(allowed_values)
@@ -301,6 +405,10 @@ module HammerCLI
301
405
  Completer::finalize_completions(@allowed_values)
302
406
  end
303
407
 
408
+ def completion_type
409
+ super.merge({ values: allowed_values })
410
+ end
411
+
304
412
  private
305
413
 
306
414
  def quoted_values
@@ -22,12 +22,14 @@ module HammerCLI
22
22
 
23
23
  class OptionDefinition < Clamp::Option::Definition
24
24
 
25
- attr_accessor :value_formatter, :context_target, :deprecated_switches
25
+ attr_accessor :value_formatter, :context_target, :deprecated_switches,
26
+ :family
26
27
 
27
28
  def initialize(switches, type, description, options = {})
28
29
  @value_formatter = options[:format] || HammerCLI::Options::Normalizers::Default.new
29
30
  @context_target = options[:context_target]
30
31
  @deprecated_switches = options[:deprecated]
32
+ @family = options[:family]
31
33
  super
32
34
  end
33
35
 
@@ -36,7 +38,9 @@ module HammerCLI
36
38
  end
37
39
 
38
40
  def help_lhs
39
- super
41
+ lhs = switches.join(', ')
42
+ lhs += " #{completion_type[:type]}".upcase unless flag?
43
+ lhs
40
44
  end
41
45
 
42
46
  def help_rhs
@@ -50,14 +54,14 @@ module HammerCLI
50
54
  rhs.empty? ? " " : rhs
51
55
  end
52
56
 
53
- def handles?(switch)
57
+ def extract_value(switch, arguments)
54
58
  message = _("Warning: Option %{option} is deprecated. %{message}")
55
59
  if deprecated_switches.class <= String && switches.include?(switch)
56
- warn(message % { :option => switch, :message => deprecated_switches })
60
+ warn(message % { option: switch, message: deprecated_switches })
57
61
  elsif deprecated_switches.class <= Hash && deprecated_switches.keys.include?(switch)
58
- warn(message % { :option => switch, :message => deprecated_switches[switch] })
62
+ warn(message % { option: switch, message: deprecated_switches[switch] })
59
63
  end
60
- super(switch)
64
+ super(switch, arguments)
61
65
  end
62
66
 
63
67
  def deprecation_message(switch)
@@ -140,22 +144,13 @@ module HammerCLI
140
144
  return { type: :flag } if @type == :flag
141
145
 
142
146
  formatter ||= value_formatter
143
- completion_type = case formatter
144
- when HammerCLI::Options::Normalizers::Bool,
145
- HammerCLI::Options::Normalizers::Enum
146
- { type: :enum, values: value_formatter.allowed_values }
147
- when HammerCLI::Options::Normalizers::EnumList
148
- { type: :multienum, values: value_formatter.allowed_values }
149
- when HammerCLI::Options::Normalizers::ListNested
150
- { type: :schema, schema: value_formatter.schema.description(richtext: false) }
151
- when HammerCLI::Options::Normalizers::List
152
- { type: :list }
153
- when HammerCLI::Options::Normalizers::KeyValueList
154
- { type: :key_value_list }
155
- when HammerCLI::Options::Normalizers::File
156
- { type: :file }
157
- end
158
- completion_type || { type: :value }
147
+ formatter.completion_type
148
+ end
149
+
150
+ def child?
151
+ return unless @family
152
+
153
+ @family.children.include?(self)
159
154
  end
160
155
 
161
156
  private
@@ -2,25 +2,33 @@
2
2
 
3
3
  module HammerCLI
4
4
  module Options
5
+ class OptionFamilyRegistry < Array
6
+ # rubocop:disable Style/Alias
7
+ alias_method :register, :push
8
+ alias_method :unregister, :delete
9
+ # rubocop:enable Style/Alias
10
+ end
11
+
5
12
  class OptionFamily
6
13
  attr_reader :children
7
14
 
8
- IDS_REGEX = /(\A[Ii][Dd][s]?)|\s([Ii][Dd][s]?)\W|([Ii][Dd][s]?\Z)/
15
+ IDS_REGEX = /(\A[Ii][Dd][s]?)|\s([Ii][Dd][s]?)\W|([Ii][Dd][s]?\Z)|(numeric identifier|identifier)/.freeze
9
16
 
10
17
  def initialize(options = {})
11
18
  @all = []
12
19
  @children = []
13
20
  @options = options
14
- @creator = options[:creator] || Class.new(HammerCLI::Apipie::Command)
21
+ @creator = options[:creator] || self
15
22
  @prefix = options[:prefix]
16
23
  @root = options[:root] || options[:aliased_resource] || options[:referenced_resource]
24
+ @creator.family_registry.register(self) if @creator != self
17
25
  end
18
26
 
19
27
  def description
20
28
  types = all.map(&:type).map { |s| s.split('_').last.to_s }
21
29
  .map(&:downcase).join('/')
22
- parent_desc = @parent.help[1].gsub(IDS_REGEX) { |w| w.gsub(/\w+/, types) }
23
- desc = parent_desc.strip.empty? ? @options[:description] : parent_desc
30
+ parent_desc = @parent.help[1].gsub(IDS_REGEX) { |w| w.gsub(/\b.+\b/, types) }
31
+ desc = @options[:description] || parent_desc.strip.empty? ? @options[:description] : parent_desc
24
32
  if @options[:deprecation].class <= String
25
33
  format_deprecation_msg(desc, _('Deprecated: %{deprecated_msg}') % { deprecated_msg: @options[:deprecation] })
26
34
  elsif @options[:deprecation].class <= Hash
@@ -33,6 +41,21 @@ module HammerCLI
33
41
  end
34
42
  end
35
43
 
44
+ def help
45
+ [help_lhs, help_rhs]
46
+ end
47
+
48
+ def help_lhs
49
+ return @parent&.help_lhs if @children.empty?
50
+
51
+ types = all.map(&:value_formatter).map { |f| f.completion_type[:type].to_s.upcase }
52
+ switch + ' ' + types.uniq.join('/')
53
+ end
54
+
55
+ def help_rhs
56
+ description || @parent.help[1]
57
+ end
58
+
36
59
  def formats
37
60
  return [@options[:format].class] if @options[:format]
38
61
 
@@ -41,7 +64,7 @@ module HammerCLI
41
64
 
42
65
  def switch
43
66
  return if @parent.nil? && @children.empty?
44
- return @parent.help_lhs.strip if @children.empty?
67
+ return @parent.switches.join(', ').strip if @children.empty?
45
68
 
46
69
  switch_start = main_switch.each_char
47
70
  .zip(*all.map(&:switches).flatten.map(&:each_char))
@@ -68,6 +91,8 @@ module HammerCLI
68
91
 
69
92
  def child(switches, type, description, opts = {}, &block)
70
93
  child = new_member(switches, type, description, opts, &block)
94
+ return unless child
95
+
71
96
  @children << child
72
97
  child
73
98
  end
@@ -80,6 +105,18 @@ module HammerCLI
80
105
  @children << child
81
106
  end
82
107
 
108
+ def root
109
+ @root || @parent&.aliased_resource || @parent&.referenced_resource || common_root
110
+ end
111
+
112
+ def option(*args)
113
+ HammerCLI::Apipie::OptionDefinition.new(*args)
114
+ end
115
+
116
+ def find_option(switch)
117
+ all.find { |m| m.handles?(switch) }
118
+ end
119
+
83
120
  private
84
121
 
85
122
  def format_deprecation_msg(option_desc, deprecation_msg)
@@ -90,18 +127,17 @@ module HammerCLI
90
127
  opts = opts.merge(@options)
91
128
  opts[:family] = self
92
129
  if opts[:deprecated]
93
- handles = [switches].flatten
130
+ handles = Array(switches)
94
131
  opts[:deprecated] = opts[:deprecated].select do |switch, _msg|
95
132
  handles.include?(switch)
96
133
  end
97
134
  end
98
135
  @creator.instance_eval do
99
- option(switches, type, description, opts, &block)
136
+ option(switches, type, description, opts, &block) unless Array(switches).any? { |s| find_option(s) }
100
137
  end
101
138
  end
102
139
 
103
140
  def main_switch
104
- root = @root || @parent.aliased_resource || @parent.referenced_resource || common_root
105
141
  "--#{@prefix}#{root}".tr('_', '-')
106
142
  end
107
143
 
@@ -97,6 +97,12 @@ module HammerCLI::Output::Adapter
97
97
  @context[:fields] || ['DEFAULT']
98
98
  end
99
99
 
100
+ def context_for_fields
101
+ {
102
+ show_ids: @context[:show_ids]
103
+ }
104
+ end
105
+
100
106
  private
101
107
 
102
108
  def filter_formatters(formatters_map)
@@ -76,7 +76,7 @@ module HammerCLI::Output::Adapter
76
76
  def render_value(field, data)
77
77
  formatter = @formatters.formatter_for_type(field.class)
78
78
  parameters = field.parameters
79
- parameters[:context] = @context
79
+ parameters[:context] = context_for_fields
80
80
  data = formatter.format(data, field.parameters) if formatter
81
81
  data.to_s
82
82
  end
@@ -55,7 +55,7 @@ module HammerCLI::Output::Adapter
55
55
  else
56
56
  formatter = @formatters.formatter_for_type(field.class)
57
57
  parameters = field.parameters
58
- parameters[:context] = @context
58
+ parameters[:context] = context_for_fields
59
59
  if formatter
60
60
  data = formatter.format(data, field.parameters)
61
61
  end
@@ -73,7 +73,7 @@ module HammerCLI::Output
73
73
 
74
74
  data << sets.each_with_object({}) do |set, res|
75
75
  mark = field.sets.include?(set) ? 'x' : ''
76
- value = set == sets.first ? field.full_label : mark
76
+ value = set == sets.first ? field.full_label.capitalize : mark
77
77
  res.update(set => value)
78
78
  end
79
79
  end
@@ -11,7 +11,7 @@ module HammerCLI::Output
11
11
 
12
12
  def fields=(fields)
13
13
  @fields = fields || []
14
- @filtered_fields = @fields.dup
14
+ @filtered_fields = Marshal.load(Marshal.dump(@fields))
15
15
  end
16
16
 
17
17
  def filter_by_classes(classes = nil)
@@ -66,7 +66,7 @@ module HammerCLI::Output
66
66
 
67
67
  def include_by_label?(labels, label)
68
68
  labels.any? do |l|
69
- l.start_with?("#{label}/") || label.match(%r{^#{l.gsub(/\*/, '.*')}(|\/.*)$})
69
+ l.start_with?("#{label}/") || label.match(%r{^#{l.gsub(/\*/, '.*')}(|\/.*)$}) || l == label
70
70
  end
71
71
  end
72
72
 
@@ -40,6 +40,12 @@ class String
40
40
  HammerCLI.constant_path(self)[-1]
41
41
  end
42
42
 
43
+ # Rails implementation: https://github.com/rails/rails/blob/main/actionview/lib/action_view/helpers/text_helper.rb#L260
44
+ def wrap(line_width: 80, break_sequence: "\n")
45
+ split("\n").collect! do |line|
46
+ line.length > line_width ? line.gsub(/(.{1,#{line_width}})(\s+|$)/, "\\1#{break_sequence}").strip : line
47
+ end * break_sequence
48
+ end
43
49
  end
44
50
 
45
51
  class Hash
@@ -1,5 +1,5 @@
1
1
  module HammerCLI
2
2
  def self.version
3
- @version ||= Gem::Version.new "2.5.0"
3
+ @version ||= Gem::Version.new "3.1.0"
4
4
  end
5
5
  end
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
@@ -308,6 +308,13 @@ describe HammerCLI::AbstractCommand do
308
308
  opt = TestOptionCmd.find_option('--fields')
309
309
  opt.is_a?(HammerCLI::Options::OptionDefinition).must_equal true
310
310
  end
311
+
312
+ it 'should add option type and accepted value' do
313
+ help_str = TestOptionCmd.help('')
314
+ help_str.must_match(
315
+ /LIST Comma separated list of values. Values containing comma should be quoted or escaped with backslash./
316
+ )
317
+ end
311
318
  end
312
319
 
313
320
  describe "#options" do
@@ -17,7 +17,7 @@ describe HammerCLI::Apipie::OptionBuilder do
17
17
  let(:resource) {api.resource(:documented)}
18
18
  let(:action) {resource.action(:index)}
19
19
  let(:builder) { HammerCLI::Apipie::OptionBuilder.new(resource, action) }
20
- let(:builder_options) { {} }
20
+ let(:builder_options) { { command: Class.new(HammerCLI::Apipie::Command) } }
21
21
  let(:options) { builder.build(builder_options) }
22
22
 
23
23
  context "with one simple param" do
@@ -51,7 +51,7 @@ describe HammerCLI::Apipie::OptionBuilder do
51
51
  context "required options" do
52
52
 
53
53
  let(:action) {resource.action(:create)}
54
- let(:required_options) { builder.build.reject{|opt| !opt.required?} }
54
+ let(:required_options) { builder.build(builder_options).reject{|opt| !opt.required?} }
55
55
 
56
56
  it "should set required flag for the required options" do
57
57
  required_options.map(&:attribute_name).sort.must_equal [HammerCLI.option_accessor_name("array_param")]
@@ -146,7 +146,12 @@ describe HammerCLI::Apipie::OptionBuilder do
146
146
 
147
147
  context "aliasing resources" do
148
148
  let(:action) {resource.action(:action_with_ids)}
149
- let(:builder_options) { {:resource_mapping => {:organization => 'company', 'compute_resource' => :compute_provider}} }
149
+ let(:builder_options) do
150
+ {
151
+ resource_mapping: { organization: 'company', 'compute_resource' => :compute_provider },
152
+ command: Class.new(HammerCLI::Apipie::Command)
153
+ }
154
+ end
150
155
 
151
156
  it "renames options" do
152
157
  # builder_options[:resource_mapping] = {:organization => 'company', 'compute_resource' => :compute_provider}
@@ -118,7 +118,7 @@ describe HammerCLI::CommandExtensions do
118
118
  it 'should extend option family only' do
119
119
  cmd.extend_with(CmdExtensions.new(only: :option_family))
120
120
  cmd.output_definition.empty?.must_equal true
121
- cmd.recognised_options.map(&:switches).flatten.must_equal ['--test-one', '--test-two', '-h', '--help']
121
+ cmd.recognised_options.map(&:switches).flatten.must_equal ['-h', '--help', '--test-one', '--test-two']
122
122
  end
123
123
  end
124
124
 
@@ -203,5 +203,13 @@ describe HammerCLI::CommandExtensions do
203
203
  end
204
204
  end
205
205
 
206
-
206
+ context 'associate family' do
207
+ it 'should associate option family' do
208
+ cmd.extend_with(CmdExtensions.new(only: :option_family))
209
+ cmd.option_family associate: 'test' do
210
+ child '--test-three', '', ''
211
+ end
212
+ cmd.recognised_options.map(&:switches).flatten.must_equal ['-h', '--help', '--test-one', '--test-two', '--test-three']
213
+ end
214
+ end
207
215
  end