hammer_cli 0.0.14 → 0.0.15

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: dc846bf971738baff5d9a47ba375a4faa698ddff
4
- data.tar.gz: ec7445b7048131184372d9d6aabfa00c2bc27d77
3
+ metadata.gz: ec98bfd08b8af7d5ec4dd2a7e7b215e1c3d348e4
4
+ data.tar.gz: 51fc2a97810bd8c8fed855eaee2b3b438b495a18
5
5
  SHA512:
6
- metadata.gz: 49c74f5aad4024fd6074135d1d779e2bcf6b9debafddb2879672e938c1c0da0901c88719b70a9872145539d878c3d8660777bb535017436095790c6b2ea4662e
7
- data.tar.gz: e84343ad493a84d1fb21e8e1cf7e36ffd63b6737fa4179b531b132a3ca3e2f050e969e40b905ad672f2c2f145e111754431fda7f89f3edb17df3b773b6490be2
6
+ metadata.gz: 6ea9c6240e80c754ee6391cb6be396527a720c7cf85e21b09d618e7cc35f9fdadd0765eac52f48656c819d60e03a3a46a0be7fc0b5cda538cd93c42db46c70f8
7
+ data.tar.gz: 176c84972b1b107252f2d93828596ff693f1b7156d8d920e5b58ec363cab85bee0e8fa777603a6b4fb4ed005b3cece2321cce25165d0b65a10ba006459ac47d5
@@ -97,7 +97,9 @@ for the full list of available exit codes.
97
97
  Our new command has only one option so far. It's `-h` which is built in for every command by default.
98
98
  Option declaration is the same as in clamp so please read it's
99
99
  [documentation](https://github.com/mdub/clamp/#declaring-options)
100
- on that topic.
100
+ on that topic. However unlike in Clamp, the option accessors in Hammer are created with prefix 'option_', to avoid
101
+ conflict with methods of the commands. So to access value of an `--name` option you have to call `option_name()`
102
+
101
103
 
102
104
  Example option usage could go like this:
103
105
  ```ruby
@@ -106,7 +108,7 @@ class HelloCommand < HammerCLI::AbstractCommand
106
108
  option '--name', "NAME", "Name of the person you want to greet"
107
109
 
108
110
  def execute
109
- print_message "Hello %s!" % (name || "World")
111
+ print_message "Hello %s!" % (option_name || "World")
110
112
  HammerCLI::EX_OK
111
113
  end
112
114
  end
@@ -135,20 +137,20 @@ Hammer provides extended functionality for validating options.
135
137
  First of all there is a dsl for validating combinations of options:
136
138
  ```ruby
137
139
  validate_options do
138
- all(:name, :surname).required # requires all the options
139
- option(:age).required # requires a single option,
140
+ all(:option_name, :option_surname).required # requires all the options
141
+ option(:option_age).required # requires a single option,
140
142
  # equivalent of :required => true in option declaration
141
- any(:email, :phone).required # requires at least one of the options
143
+ any(:option_email, :option_phone).required # requires at least one of the options
142
144
 
143
145
  # Tt is possible to create more complicated constructs.
144
146
  # This example requires either the full address or nothing
145
- if any(:street, :city, :zip).exist?
146
- all(:street, :city, :zip).required
147
+ if any(:option_street, :option_city, :option_zip).exist?
148
+ all(:option_street, :option_city, :option_zip).required
147
149
  end
148
150
 
149
151
  # Here you can reject all address related option when --no-address is passed
150
- if option(:no_address).exist?
151
- all(:street, :city, :zip).rejected
152
+ if option(:option_no_address).exist?
153
+ all(:option_street, :option_city, :option_zip).rejected
152
154
  end
153
155
  end
154
156
 
@@ -159,6 +161,8 @@ Another option-related feature is a set of normalizers for specific option types
159
161
  option values. Each normalizer has a description of the format it accepts. This description is printed
160
162
  in commands' help.
161
163
 
164
+ See [our tutorial](option_normalizers.md#option-normalizers) if you want to create your custom normalizer.
165
+
162
166
  ##### _List_
163
167
 
164
168
  Parses comma separated strings to a list of values.
@@ -220,7 +224,7 @@ module HammerCLIHello
220
224
  option '--name', "NAME", "Name of the person you want to greet"
221
225
 
222
226
  def execute
223
- print_message "Hello %s!" % (name || "World")
227
+ print_message "Hello %s!" % (option_ name || "World")
224
228
  HammerCLI::EX_OK
225
229
  end
226
230
  end
@@ -303,7 +307,7 @@ a message in a log for debugging purposes.
303
307
 
304
308
 
305
309
  ### Removing subcommands
306
- If your plugin needs to disable existing subcommand, you can use `remove_subcommand` for this.
310
+ If your plugin needs to disable existing subcommand, you can use `remove_subcommand` for this.
307
311
 
308
312
  ```ruby
309
313
  HammerCLI::MainCommand.remove_subcommand 'say'
@@ -10,3 +10,4 @@ Contents:
10
10
  - [Creating commands](creating_commands.md#create-your-first-command)
11
11
  - [Creating ApiPie commands](creating_apipie_commands.md#creating-commands-for-restful-api-with-apipie)
12
12
  - [Development tips](development_tips.md#development-tips)
13
+ - [Option normalizers](option_normalizers.md#option-normalizers)
@@ -0,0 +1,96 @@
1
+ Option normalizers
2
+ ------------------
3
+
4
+ The goal of option normalizers is to:
5
+ - provide description of valid option values
6
+ - check format and preprocess values passed by users
7
+ - offer value completion
8
+
9
+ Every normalizer must be descendant of `HammerCLI::Options::Normalizers::AbstractNormalizer`.
10
+
11
+ Example usage:
12
+ ```ruby
13
+ option "--enabled", "ENABLED", "Should the host be enabled?",
14
+ :format => HammerCLI::Options::Normalizers::Bool.new
15
+ ```
16
+
17
+ #### Description of valid values
18
+ There is method `description` that should return a help string. It's value is used in output of `-h`,
19
+ which can then look for example like this:
20
+
21
+ ```
22
+ --enabled ENABLED Should the host be enabled?
23
+ One of true/false, yes/no, 1/0.
24
+ ```
25
+
26
+ Abstract normalizer returns empty string by default.
27
+
28
+
29
+ #### Check and format passed values
30
+
31
+ Normalizer's method `format` is used for such checks. The method behaves as a filter taking
32
+ string value as it's input and returning value of any type.
33
+
34
+ If the value is not valid `ArgumentError` with an appropriate message should be risen.
35
+ Implementation in `Bool` normalizer is a good example of such functionality:
36
+
37
+ ```ruby
38
+ def format(bool)
39
+ bool = bool.to_s
40
+ if bool.downcase.match(/^(true|t|yes|y|1)$/i)
41
+ return true
42
+ elsif bool.downcase.match(/^(false|f|no|n|0)$/i)
43
+ return false
44
+ else
45
+ raise ArgumentError, "value must be one of true/false, yes/no, 1/0"
46
+ end
47
+ end
48
+ ```
49
+
50
+
51
+ #### Value completion
52
+
53
+ Normalizers can also provide completion of option values via method `complete`. It takes one argument - current option value at the time the completion was requested. In the simplest cases the method returns array of all possible values. More complex completions can use the current value argument for building the return values.
54
+
55
+ We distinguish two types of offered completion strings:
56
+
57
+ **Terminal completions**
58
+ - used in most cases
59
+ - the value is terminal and the completion finishes when it is selected
60
+ - terminal strings have to end with a blank space
61
+
62
+ **Partial complations**
63
+ - used to offer completion pieces, eg. directory names when completing file path
64
+ - the completion continues until a terminal string is selected
65
+ - the values have to end with any character but blank space
66
+
67
+ Completing file paths demonstrate the difference nicely:
68
+ ```ruby
69
+ # "hammer some command --file /etc/f"
70
+ file_normalizer.complete("/etc/f")
71
+ [
72
+ "/etc/foreman/", # partial completion, can continue with the directory contents
73
+ "/etc/foo/", # -- || --
74
+ "/etc/foo.conf " # terminal, the completion can't continue
75
+ ]
76
+ ```
77
+ Example of a simple completion method for boolean values:
78
+ ```ruby
79
+ def complete(value)
80
+ ["yes ", "no "]
81
+ end
82
+ ```
83
+ Example of a method completing file paths:
84
+ ```ruby
85
+ def complete(value)
86
+ Dir[value.to_s+'*'].collect do |file|
87
+ if ::File.directory?(file)
88
+ file+'/'
89
+ else
90
+ file+' '
91
+ end
92
+ end
93
+ end
94
+ ```
95
+
96
+ See more examples in [normalizers.rb](../lib/hammer_cli/options/normalizers.rb).
@@ -240,6 +240,5 @@ module HammerCLI
240
240
  def options
241
241
  all_options.reject {|key, value| value.nil? }
242
242
  end
243
-
244
243
  end
245
244
  end
@@ -1,3 +1,4 @@
1
+ require File.join(File.dirname(__FILE__), '../abstract')
1
2
  require File.join(File.dirname(__FILE__), 'options')
2
3
  require File.join(File.dirname(__FILE__), 'resource')
3
4
 
@@ -8,24 +9,13 @@ module HammerCLI::Apipie
8
9
  include HammerCLI::Apipie::Resource
9
10
  include HammerCLI::Apipie::Options
10
11
 
11
- def initialize(*args)
12
- super
13
- setup_identifier_options
14
- end
15
-
16
- def setup_identifier_options
17
- self.class.identifier_option(:id, "resource id")
18
- self.class.identifier_option(:name, "resource name")
19
- self.class.identifier_option(:label, "resource label")
20
- end
21
-
22
12
  def self.identifiers(*keys)
23
13
  @identifiers ||= {}
24
14
  keys.each do |key|
25
15
  if key.is_a? Hash
26
16
  @identifiers.merge!(key)
27
17
  else
28
- @identifiers.update(key => key)
18
+ @identifiers.update(key => HammerCLI.option_accessor_name(key))
29
19
  end
30
20
  end
31
21
  end
@@ -74,6 +64,12 @@ module HammerCLI::Apipie
74
64
 
75
65
  private
76
66
 
67
+ def self.setup_identifier_options
68
+ identifier_option(:id, "resource id")
69
+ identifier_option(:name, "resource name")
70
+ identifier_option(:label, "resource label")
71
+ end
72
+
77
73
  def self.identifier_option(name, desc)
78
74
  attr_name = declared_identifiers[name]
79
75
  option "--"+name.to_s, name.to_s.upcase, desc, :attribute_name => attr_name if self.identifier? name
@@ -19,25 +19,33 @@ module HammerCLI::Apipie
19
19
  params.each do |p|
20
20
  if p["expected_type"] == "hash"
21
21
  opts[p["name"]] = method_options_for_params(p["params"], include_nil)
22
- elsif respond_to?(p["name"], true)
23
- opts[p["name"]] = send(p["name"])
24
22
  else
25
- opts[p["name"]] = nil
23
+ opts[p["name"]] = get_option_value(p["name"])
26
24
  end
27
25
  end
28
26
  opts.reject! {|key, value| value.nil? } unless include_nil
29
27
  opts
30
28
  end
31
29
 
30
+ def get_option_value(opt_name)
31
+ if respond_to?(HammerCLI.option_accessor_name(opt_name), true)
32
+ send(HammerCLI.option_accessor_name(opt_name))
33
+ else
34
+ nil
35
+ end
36
+ end
37
+
32
38
  module ClassMethods
33
39
 
34
40
  def apipie_options(options={})
35
- raise "Specify apipie resource first." unless resource_defined?
41
+ setup_identifier_options
42
+ if resource_defined?
43
+ filter = options[:without] || []
44
+ filter = Array(filter)
45
+ filter += declared_identifiers.keys
36
46
 
37
- filter = options[:without] || []
38
- filter = Array(filter)
39
-
40
- options_for_params(resource.docs_for(action)["params"], filter)
47
+ options_for_params(resource.docs_for(action)["params"], filter)
48
+ end
41
49
  end
42
50
 
43
51
  protected
@@ -33,9 +33,9 @@ module HammerCLI::Apipie
33
33
  self.new(definition.resource_class, config)
34
34
  end
35
35
 
36
- def call(method_name, params=nil)
36
+ def call(method_name, params=nil, headers=nil)
37
37
  Logging.logger[resource_class.name].debug "Calling '#{method_name}' with params #{params.ai}" if HammerCLI::Settings.get(:log_api_calls)
38
- result = instance.send(method_name, params)
38
+ result = instance.send(method_name, params, headers)
39
39
  Logging.logger[resource_class.name].debug "Method '#{method_name}' responded with #{result[0].ai}" if HammerCLI::Settings.get(:log_api_calls)
40
40
  result
41
41
  end
@@ -83,6 +83,7 @@ module HammerCLI::Apipie
83
83
  end
84
84
 
85
85
  def module_resource
86
+ return nil unless self.name
86
87
  enclosing_module = self.name.split("::")[0..-2].inject(Object) { |mod, cls| mod.const_get cls }
87
88
 
88
89
  if enclosing_module.respond_to? :resource
@@ -27,7 +27,7 @@ module HammerCLI
27
27
  :format => HammerCLI::Options::Normalizers::Bool.new,
28
28
  :context_target => :interactive
29
29
 
30
- option ["--csv"], :flag, "Output as CSV (same as --adapter=csv)"
30
+ option ["--csv"], :flag, "Output as CSV (same as --output=csv)"
31
31
  option ["--output"], "ADAPTER", "Set output format. One of [%s]" %
32
32
  HammerCLI::Output::Output.adapters.keys.join(', '),
33
33
  :context_target => :adapter
@@ -44,7 +44,7 @@ module HammerCLI
44
44
  exit(HammerCLI::EX_OK)
45
45
  end
46
46
 
47
- def csv=(csv)
47
+ def option_csv=(csv)
48
48
  context[:adapter] = :csv
49
49
  end
50
50
 
@@ -19,16 +19,28 @@ module HammerCLI
19
19
  return nil
20
20
  end
21
21
 
22
- def self.load(name)
22
+ def self.load!(name)
23
23
  begin
24
24
  require_module(name)
25
+ rescue LoadError => e
26
+ logger.error "Module #{name} not found"
27
+ raise e
25
28
  rescue Exception => e
26
29
  logger.error "Error while loading module #{name}"
30
+ logger.error e
31
+ puts "Warning: An error occured while loading module #{name}"
27
32
  raise e
28
33
  end
29
34
 
30
35
  version = find_by_name(name).version
31
36
  logger.info "Extension module #{name} (#{version}) loaded"
37
+ true
38
+ end
39
+
40
+ def self.load(name)
41
+ load! name
42
+ rescue Exception => e
43
+ false
32
44
  end
33
45
 
34
46
  def self.require_module(name)
@@ -1,6 +1,19 @@
1
1
  require 'clamp'
2
2
 
3
3
  module HammerCLI
4
+
5
+ def self.option_accessor_name(*name)
6
+ if name.length > 1
7
+ name.map { |n| _option_accessor_name(n) }
8
+ else
9
+ _option_accessor_name(name.first)
10
+ end
11
+ end
12
+
13
+ def self._option_accessor_name(name)
14
+ "option_#{name.to_s}".gsub('-', '_')
15
+ end
16
+
4
17
  module Options
5
18
 
6
19
  class OptionDefinition < Clamp::Option::Definition
@@ -71,6 +84,12 @@ module HammerCLI
71
84
  end
72
85
  end
73
86
 
87
+ private
88
+
89
+ def infer_attribute_name
90
+ HammerCLI.option_accessor_name(super)
91
+ end
92
+
74
93
  end
75
94
 
76
95
  end
@@ -1,12 +1,12 @@
1
1
  module HammerCLI::Output
2
2
  module Formatters
3
3
 
4
- # Registry for formatters
4
+ # Registry for formatters
5
5
  class FormatterLibrary
6
6
  def initialize(formatter_map={})
7
7
 
8
8
  @_formatters = {}
9
- formatter_map.each do |type, formatters|
9
+ formatter_map.each do |type, formatters|
10
10
  register_formatter(type, *Array(formatters))
11
11
  end
12
12
  end
@@ -14,7 +14,7 @@ module HammerCLI::Output
14
14
  def register_formatter(type, *formatters)
15
15
  if @_formatters[type].nil?
16
16
  @_formatters[type] = FormatterContainer.new *formatters
17
- else
17
+ else
18
18
  formatters.each { |f| @_formatters[type].add_formatter(f) }
19
19
  end
20
20
  end
@@ -30,7 +30,7 @@ module HammerCLI::Output
30
30
  # as we expect them to serialize the value.
31
31
  #
32
32
  # - by format: :flat x :data
33
- # - by output: :file X :screen
33
+ # - by output: :file X :screen
34
34
 
35
35
  # abstract formatter
36
36
  class FieldFormatter
@@ -99,7 +99,13 @@ module HammerCLI::Output
99
99
  end
100
100
 
101
101
  def format(list)
102
- list.join(", ") if list
102
+ if list.is_a? Array
103
+ list.join(", ")
104
+ elsif list
105
+ list.to_s
106
+ else
107
+ ""
108
+ end
103
109
  end
104
110
  end
105
111
 
@@ -94,7 +94,7 @@ module HammerCLI
94
94
  end
95
95
 
96
96
  def all(*to_check)
97
- AllConstraint.new(@options, to_check)
97
+ AllConstraint.new(@options, to_check.flatten(1))
98
98
  end
99
99
 
100
100
  def option(to_check)
@@ -102,7 +102,7 @@ module HammerCLI
102
102
  end
103
103
 
104
104
  def any(*to_check)
105
- AnyConstraint.new(@options, to_check)
105
+ AnyConstraint.new(@options, to_check.flatten(1))
106
106
  end
107
107
 
108
108
  def run(&block)
@@ -1,5 +1,5 @@
1
1
  module HammerCLI
2
2
  def self.version
3
- @version ||= Gem::Version.new '0.0.14'
3
+ @version ||= Gem::Version.new '0.0.15'
4
4
  end
5
5
  end
@@ -101,7 +101,7 @@ describe HammerCLI::AbstractCommand do
101
101
  test_command_class.option(['--password'], 'PASSWORD', 'Password')
102
102
  test_command = test_command_class.new("")
103
103
  test_command.run ['--password=pass']
104
- @log_output.readline.strip.must_equal "INFO HammerCLI::AbstractCommand : Called with options: {\"password\"=>\"***\"}"
104
+ @log_output.readline.strip.must_equal "INFO HammerCLI::AbstractCommand : Called with options: {\"option_password\"=>\"***\"}"
105
105
  end
106
106
 
107
107
  class TestLogCmd < HammerCLI::AbstractCommand
@@ -282,7 +282,7 @@ describe HammerCLI::AbstractCommand do
282
282
  class CmdOD1 < HammerCLI::AbstractCommand
283
283
  output do
284
284
  label 'Label' do
285
- end
285
+ end
286
286
  end
287
287
  end
288
288
 
@@ -30,50 +30,52 @@ describe HammerCLI::Apipie::Command do
30
30
 
31
31
  class Cmd1 < HammerCLI::Apipie::Command
32
32
  identifiers :id, :name, :label
33
+ apipie_options
33
34
  end
34
35
 
35
36
  class Cmd2 < Cmd1
36
37
  identifiers :id
38
+ apipie_options
37
39
  end
38
40
 
39
41
  it "must not set any option by default" do
40
- cmd
42
+ cmd_class.apipie_options
41
43
  cmd_class.declared_options.must_equal []
42
44
  end
43
45
 
44
46
  it "can set option --id" do
45
47
  cmd_class.identifiers :id
46
- cmd
48
+ cmd_class.apipie_options
47
49
  option_switches.must_equal [["--id"]]
48
- option_attribute_names.must_equal ["id"]
50
+ option_attribute_names.must_equal [HammerCLI.option_accessor_name("id")]
49
51
  end
50
52
 
51
53
  it "can set option --name" do
52
54
  cmd_class.identifiers :name
53
- cmd
55
+ cmd_class.apipie_options
54
56
  option_switches.must_equal [["--name"]]
55
- option_attribute_names.must_equal ["name"]
57
+ option_attribute_names.must_equal [HammerCLI.option_accessor_name("name")]
56
58
  end
57
59
 
58
60
  it "can set option --label" do
59
61
  cmd_class.identifiers :label
60
- cmd
62
+ cmd_class.apipie_options
61
63
  option_switches.must_equal [["--label"]]
62
- option_attribute_names.must_equal ["label"]
64
+ option_attribute_names.must_equal [HammerCLI.option_accessor_name("label")]
63
65
  end
64
66
 
65
67
  it "can set multiple identifiers" do
66
68
  cmd_class.identifiers :id, :name, :label
67
- cmd
69
+ cmd_class.apipie_options
68
70
  option_switches.must_equal [["--id"], ["--label"], ["--name"]]
69
- option_attribute_names.must_equal ["id", "label", "name"]
71
+ option_attribute_names.must_equal HammerCLI.option_accessor_name("id", "label", "name")
70
72
  end
71
73
 
72
74
  it "can change option reader" do
73
- cmd_class.identifiers :name, :id => :id_read_method
74
- cmd
75
+ cmd_class.identifiers :name, :id => :option_id_read_method
76
+ cmd_class.apipie_options
75
77
  option_switches.must_equal [["--id"], ["--name"]]
76
- option_attribute_names.must_equal ["id_read_method", "name"]
78
+ option_attribute_names.must_equal HammerCLI.option_accessor_name("id_read_method", "name")
77
79
  end
78
80
 
79
81
  it "can override inentifiers in inherrited classes" do
@@ -84,11 +86,13 @@ describe HammerCLI::Apipie::Command do
84
86
 
85
87
  it "must require one of declared identifiers" do
86
88
  cmd_class.identifiers :id, :name
89
+ cmd_class.apipie_options
87
90
  cmd.run(["--id=1"]).must_equal HammerCLI::EX_OK
88
91
  end
89
92
 
90
93
  it "must raise exception when no attribute is passed" do
91
94
  cmd_class.identifiers :id, :name
95
+ cmd_class.apipie_options
92
96
  cmd.run([]).must_equal HammerCLI::EX_USAGE
93
97
  end
94
98
 
@@ -172,7 +176,7 @@ describe HammerCLI::Apipie::Command do
172
176
  end
173
177
 
174
178
  it "should set correct attribute name" do
175
- option.attribute_name.must_equal 'se_arch_val_ue'
179
+ option.attribute_name.must_equal HammerCLI.option_accessor_name('se_arch_val_ue')
176
180
  end
177
181
 
178
182
  it "should set description with html tags stripped" do
@@ -189,7 +193,7 @@ describe HammerCLI::Apipie::Command do
189
193
  let(:required_options) { cmd_class.declared_options.reject{|opt| !opt.required?} }
190
194
 
191
195
  it "should set required flag for the required options" do
192
- required_options.map(&:attribute_name).sort.must_equal ["array_param"]
196
+ required_options.map(&:attribute_name).sort.must_equal [HammerCLI.option_accessor_name("array_param")]
193
197
  end
194
198
  end
195
199
 
@@ -200,11 +204,11 @@ describe HammerCLI::Apipie::Command do
200
204
  end
201
205
 
202
206
  it "should create options for all parameters except the hash" do
203
- cmd_class.declared_options.map(&:attribute_name).sort.must_equal ["array_param", "name", "provider"]
207
+ cmd_class.declared_options.map(&:attribute_name).sort.must_equal HammerCLI.option_accessor_name("array_param", "name", "provider")
204
208
  end
205
209
 
206
210
  it "should name the options correctly" do
207
- cmd_class.declared_options.map(&:attribute_name).sort.must_equal ["array_param", "name", "provider"]
211
+ cmd_class.declared_options.map(&:attribute_name).sort.must_equal HammerCLI.option_accessor_name("array_param", "name", "provider")
208
212
  end
209
213
  end
210
214
 
@@ -222,17 +226,17 @@ describe HammerCLI::Apipie::Command do
222
226
 
223
227
  it "should parse comma separated string to array" do
224
228
  cmd.run(["--array-param=valA,valB,valC"])
225
- cmd.array_param.must_equal ['valA', 'valB', 'valC']
229
+ cmd.get_option_value(:array_param).must_equal ['valA', 'valB', 'valC']
226
230
  end
227
231
 
228
232
  it "should parse string to array of length 1" do
229
233
  cmd.run(["--array-param=valA"])
230
- cmd.array_param.must_equal ['valA']
234
+ cmd.get_option_value(:array_param).must_equal ['valA']
231
235
  end
232
236
 
233
237
  it "should parse empty string to empty array" do
234
238
  cmd.run(['--array-param='])
235
- cmd.array_param.must_equal []
239
+ cmd.get_option_value(:array_param).must_equal []
236
240
  end
237
241
 
238
242
  end
@@ -245,22 +249,22 @@ describe HammerCLI::Apipie::Command do
245
249
 
246
250
  it "should skip filtered options" do
247
251
  cmd_class.apipie_options :without => ["provider", "name"]
248
- cmd_class.declared_options.map(&:attribute_name).sort.must_equal ["array_param"]
252
+ cmd_class.declared_options.map(&:attribute_name).sort.must_equal [HammerCLI.option_accessor_name("array_param")]
249
253
  end
250
254
 
251
255
  it "should skip filtered options defined as symbols" do
252
256
  cmd_class.apipie_options :without => [:provider, :name]
253
- cmd_class.declared_options.map(&:attribute_name).sort.must_equal ["array_param"]
257
+ cmd_class.declared_options.map(&:attribute_name).sort.must_equal [HammerCLI.option_accessor_name("array_param")]
254
258
  end
255
259
 
256
260
  it "should skip single filtered option in array" do
257
261
  cmd_class.apipie_options :without => ["provider"]
258
- cmd_class.declared_options.map(&:attribute_name).sort.must_equal ["array_param", "name"]
262
+ cmd_class.declared_options.map(&:attribute_name).sort.must_equal HammerCLI.option_accessor_name("array_param", "name")
259
263
  end
260
264
 
261
265
  it "should skip single filtered option" do
262
266
  cmd_class.apipie_options :without => "provider"
263
- cmd_class.declared_options.map(&:attribute_name).sort.must_equal ["array_param", "name"]
267
+ cmd_class.declared_options.map(&:attribute_name).sort.must_equal HammerCLI.option_accessor_name("array_param", "name")
264
268
  end
265
269
 
266
270
  end
@@ -61,22 +61,83 @@ describe HammerCLI::Modules do
61
61
  end
62
62
 
63
63
  describe "load a module" do
64
- it "must require a module" do
65
- HammerCLI::Modules.expects(:require_module).with("hammer_cli_tom")
66
- HammerCLI::Modules.load("hammer_cli_tom")
64
+ describe "success" do
65
+ before :each do
66
+ HammerCLI::Modules.stubs(:require_module)
67
+ end
68
+
69
+ it "must require a module" do
70
+ HammerCLI::Modules.expects(:require_module).with("hammer_cli_tom")
71
+ HammerCLI::Modules.load("hammer_cli_tom")
72
+ end
73
+
74
+ it "must log module's name and version" do
75
+ HammerCLI::Modules.expects(:require_module).with("hammer_cli_tom")
76
+ HammerCLI::Modules.load("hammer_cli_tom")
77
+ @log_output.readline.strip.must_equal "INFO Modules : Extension module hammer_cli_tom (0.0.1) loaded"
78
+ end
79
+
80
+ it "must return true when load succeeds" do
81
+ HammerCLI::Modules.load("hammer_cli_tom").must_equal true
82
+ end
83
+
84
+ it "must return true when load! succeeds" do
85
+ HammerCLI::Modules.load!("hammer_cli_tom").must_equal true
86
+ end
67
87
  end
68
88
 
69
- it "must log module's name and version" do
70
- HammerCLI::Modules.expects(:require_module).with("hammer_cli_tom")
71
- HammerCLI::Modules.load("hammer_cli_tom")
72
- @log_output.readline.strip.must_equal "INFO Modules : Extension module hammer_cli_tom (0.0.1) loaded"
89
+ describe "module not found" do
90
+ before :each do
91
+ HammerCLI::Modules.stubs(:require_module).raises(LoadError)
92
+ @error_msg = "ERROR Modules : Module hammer_cli_tom not found"
93
+ end
94
+
95
+ it "must log an error if the load! fails" do
96
+ proc { HammerCLI::Modules.load!("hammer_cli_tom") }.must_raise LoadError
97
+ @log_output.readline.strip.must_equal @error_msg
98
+ end
99
+
100
+ it "must log an error if the load fails" do
101
+ HammerCLI::Modules.load("hammer_cli_tom")
102
+ @log_output.readline.strip.must_equal @error_msg
103
+ end
104
+
105
+ it "must return false when load fails" do
106
+ HammerCLI::Modules.load("hammer_cli_tom").must_equal false
107
+ end
73
108
  end
74
- end
75
109
 
76
- it "must log an error if the load fails" do
77
- proc { HammerCLI::Modules.load("hammer_cli_tom") }.must_raise LoadError
78
- @log_output.readline.strip.must_equal "ERROR Modules : Error while loading module hammer_cli_tom"
110
+ describe "module runtime exception" do
111
+ before :each do
112
+ HammerCLI::Modules.stubs(:require_module).raises(RuntimeError)
113
+ @error_msg = "ERROR Modules : Error while loading module hammer_cli_tom"
114
+ @warning_msg = "Warning: An error occured while loading module hammer_cli_tom"
115
+ end
116
+
117
+ it "must log an error if the load! fails" do
118
+ proc {
119
+ proc {
120
+ HammerCLI::Modules.load!("hammer_cli_tom")
121
+ }.must_output("#{@warning_msg}\n", "")
122
+ }.must_raise RuntimeError
123
+ @log_output.readline.strip.must_equal @error_msg
124
+ end
125
+
126
+ it "must log an error if the load fails" do
127
+ proc {
128
+ HammerCLI::Modules.load("hammer_cli_tom")
129
+ }.must_output("#{@warning_msg}\n", "")
130
+ @log_output.readline.strip.must_equal @error_msg
131
+ end
132
+
133
+ it "must return false when load fails" do
134
+ proc {
135
+ HammerCLI::Modules.load("hammer_cli_tom").must_equal false
136
+ }.must_output("#{@warning_msg}\n", "")
137
+ end
79
138
  end
80
139
 
140
+ end
141
+
81
142
  end
82
143
 
@@ -43,7 +43,7 @@ describe HammerCLI::Output::Formatters::FormatterContainer do
43
43
  container = HammerCLI::Output::Formatters::FormatterContainer.new(TestFormatter.new)
44
44
  container.format('').must_equal '.'
45
45
  end
46
-
46
+
47
47
  it "has format method" do
48
48
  container = HammerCLI::Output::Formatters::FormatterContainer.new
49
49
  container.respond_to?(:format).must_equal true
@@ -72,7 +72,7 @@ describe HammerCLI::Output::Formatters::DateFormatter do
72
72
  it "returns empty string on wrong value" do
73
73
  formatter = HammerCLI::Output::Formatters::DateFormatter.new
74
74
  formatter.format('wrong value').must_equal ""
75
- end
75
+ end
76
76
  end
77
77
 
78
78
  describe HammerCLI::Output::Formatters::ListFormatter do
@@ -80,4 +80,14 @@ describe HammerCLI::Output::Formatters::ListFormatter do
80
80
  formatter = HammerCLI::Output::Formatters::ListFormatter.new
81
81
  formatter.format([1, 2]).must_equal '1, 2'
82
82
  end
83
+
84
+ it "returns empty string when the input is nil" do
85
+ formatter = HammerCLI::Output::Formatters::ListFormatter.new
86
+ formatter.format(nil).must_equal ''
87
+ end
88
+
89
+ it "returns string value when the input is not a list" do
90
+ formatter = HammerCLI::Output::Formatters::ListFormatter.new
91
+ formatter.format('some string').must_equal 'some string'
92
+ end
83
93
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hammer_cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.14
4
+ version: 0.0.15
5
5
  platform: ruby
6
6
  authors:
7
7
  - Martin Bačovský
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-12-19 00:00:00.000000000 Z
12
+ date: 2014-01-21 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: clamp
@@ -134,6 +134,7 @@ extra_rdoc_files:
134
134
  - doc/development_tips.md
135
135
  - doc/developer_docs.md
136
136
  - doc/creating_commands.md
137
+ - doc/option_normalizers.md
137
138
  - doc/design.png
138
139
  - doc/design.uml
139
140
  - doc/writing_a_plugin.md
@@ -206,6 +207,7 @@ files:
206
207
  - doc/development_tips.md
207
208
  - doc/developer_docs.md
208
209
  - doc/creating_commands.md
210
+ - doc/option_normalizers.md
209
211
  - doc/design.png
210
212
  - doc/design.uml
211
213
  - doc/writing_a_plugin.md