hammer_cli 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +13 -5
  3. data/config/cli_config.template.yml +12 -3
  4. data/doc/creating_apipie_commands.md +53 -56
  5. data/doc/creating_commands.md +25 -19
  6. data/doc/developer_docs.md +3 -2
  7. data/doc/development_tips.md +3 -3
  8. data/doc/i18n.md +3 -3
  9. data/doc/installation.md +24 -207
  10. data/doc/installation_deb.md +48 -0
  11. data/doc/installation_gem.md +30 -0
  12. data/doc/installation_rpm.md +53 -0
  13. data/doc/installation_source.md +31 -0
  14. data/doc/option_builders.md +77 -0
  15. data/doc/option_normalizers.md +5 -5
  16. data/doc/writing_a_plugin.md +9 -9
  17. data/lib/hammer_cli.rb +1 -0
  18. data/lib/hammer_cli/abstract.rb +21 -8
  19. data/lib/hammer_cli/apipie.rb +1 -2
  20. data/lib/hammer_cli/apipie/command.rb +37 -64
  21. data/lib/hammer_cli/apipie/option_builder.rb +69 -0
  22. data/lib/hammer_cli/apipie/options.rb +1 -61
  23. data/lib/hammer_cli/clamp.rb +15 -0
  24. data/lib/hammer_cli/i18n.rb +14 -2
  25. data/lib/hammer_cli/logger.rb +1 -1
  26. data/lib/hammer_cli/option_builder.rb +43 -0
  27. data/lib/hammer_cli/options/option_definition.rb +6 -0
  28. data/lib/hammer_cli/output/adapter/abstract.rb +2 -2
  29. data/lib/hammer_cli/output/adapter/base.rb +6 -3
  30. data/lib/hammer_cli/output/adapter/table.rb +19 -2
  31. data/lib/hammer_cli/output/definition.rb +4 -0
  32. data/lib/hammer_cli/output/fields.rb +9 -0
  33. data/lib/hammer_cli/output/formatters.rb +20 -8
  34. data/lib/hammer_cli/utils.rb +1 -1
  35. data/lib/hammer_cli/version.rb +1 -1
  36. data/locale/hammer-cli.pot +103 -79
  37. data/test/unit/abstract_test.rb +62 -0
  38. data/test/unit/apipie/command_test.rb +12 -197
  39. data/test/unit/apipie/option_builder_test.rb +110 -0
  40. data/test/unit/i18n_test.rb +50 -0
  41. data/test/unit/option_builder_test.rb +33 -0
  42. data/test/unit/output/adapter/abstract_test.rb +26 -3
  43. data/test/unit/output/adapter/base_test.rb +20 -3
  44. data/test/unit/output/adapter/csv_test.rb +2 -2
  45. data/test/unit/output/adapter/table_test.rb +24 -1
  46. data/test/unit/output/definition_test.rb +13 -0
  47. data/test/unit/output/formatters_test.rb +17 -1
  48. data/test/unit/utils_test.rb +1 -1
  49. metadata +101 -88
  50. data/lib/hammer_cli/apipie/read_command.rb +0 -41
  51. data/lib/hammer_cli/apipie/write_command.rb +0 -49
  52. data/test/unit/apipie/read_command_test.rb +0 -37
  53. data/test/unit/apipie/write_command_test.rb +0 -41
@@ -267,6 +267,68 @@ describe HammerCLI::AbstractCommand do
267
267
 
268
268
  end
269
269
 
270
+ describe "option builder" do
271
+
272
+ it "uses builder container as default" do
273
+ HammerCLI::AbstractCommand.option_builder.class.must_equal HammerCLI::OptionBuilderContainer
274
+ end
275
+
276
+ it "Default builder container is empty" do
277
+ HammerCLI::AbstractCommand.option_builder.builders.empty?.must_equal true
278
+ end
279
+
280
+ it "can be initialized with custom builder" do
281
+ cmd = Class.new(HammerCLI::AbstractCommand) do
282
+ def self.custom_option_builders
283
+ [:builder_1, :builder_2]
284
+ end
285
+ end
286
+
287
+ cmd.option_builder.builders.must_equal [:builder_1, :builder_2]
288
+ end
289
+
290
+ end
291
+
292
+ describe "build options" do
293
+
294
+ class TestOptionBuilder
295
+
296
+ def build(build_options={})
297
+ [
298
+ HammerCLI::Options::OptionDefinition.new(["--test"], "TEST", "test"),
299
+ HammerCLI::Options::OptionDefinition.new(["--test2"], "TEST2", "test2")
300
+ ]
301
+ end
302
+
303
+ end
304
+
305
+ class TestBuilderCmd < HammerCLI::AbstractCommand
306
+
307
+ def self.option_builder
308
+ TestOptionBuilder.new
309
+ end
310
+
311
+ end
312
+
313
+ before :each do
314
+ # define implicit options and clear them all
315
+ TestBuilderCmd.recognised_options
316
+ TestBuilderCmd.declared_options.clear
317
+ end
318
+
319
+ it "should use option builder" do
320
+ TestBuilderCmd.build_options
321
+ TestBuilderCmd.recognised_options.map(&:switches).flatten.sort.must_equal ["--test", "--test2"].sort
322
+ end
323
+
324
+ it "should skip options that already exist" do
325
+ TestBuilderCmd.option(["--test"], "TEST", "original_test")
326
+ TestBuilderCmd.build_options
327
+ TestBuilderCmd.recognised_options.map(&:description).flatten.sort.must_equal ["original_test", "test2"].sort
328
+ end
329
+
330
+ end
331
+
270
332
  it "should inherit command_name" do
271
333
  class CmdName1 < HammerCLI::AbstractCommand
272
334
  command_name 'cmd'
@@ -26,92 +26,12 @@ describe HammerCLI::Apipie::Command do
26
26
  let(:ctx) { { :adapter => :silent, :interactive => false } }
27
27
  let(:cmd_class) { TestCommand.dup }
28
28
  let(:cmd) { cmd_class.new("", ctx) }
29
+ let(:cmd_run) { cmd.run([]) }
29
30
 
30
31
  before :each do
31
32
  HammerCLI::Connection.drop_all
32
33
  end
33
34
 
34
- context "setting identifiers" do
35
-
36
- let(:option_switches) { cmd_class.declared_options.map(&:switches).sort }
37
- let(:option_attribute_names) { cmd_class.declared_options.map(&:attribute_name).sort }
38
-
39
- class Cmd1 < TestCommand
40
- identifiers :id, :name, :label
41
- apipie_options
42
- end
43
-
44
- class Cmd2 < Cmd1
45
- identifiers :id
46
- apipie_options
47
- end
48
-
49
- it "must not set any option by default" do
50
- cmd_class.apipie_options
51
- cmd_class.declared_options.must_equal []
52
- end
53
-
54
- it "can set option --id" do
55
- cmd_class.identifiers :id
56
- cmd_class.apipie_options
57
- option_switches.must_equal [["--id"]]
58
- option_attribute_names.must_equal [HammerCLI.option_accessor_name("id")]
59
- end
60
-
61
- it "can set option --name" do
62
- cmd_class.identifiers :name
63
- cmd_class.apipie_options
64
- option_switches.must_equal [["--name"]]
65
- option_attribute_names.must_equal [HammerCLI.option_accessor_name("name")]
66
- end
67
-
68
- it "can set option --label" do
69
- cmd_class.identifiers :label
70
- cmd_class.apipie_options
71
- option_switches.must_equal [["--label"]]
72
- option_attribute_names.must_equal [HammerCLI.option_accessor_name("label")]
73
- end
74
-
75
- it "can set multiple identifiers" do
76
- cmd_class.identifiers :id, :name, :label
77
- cmd_class.apipie_options
78
- option_switches.must_equal [["--id"], ["--label"], ["--name"]]
79
- option_attribute_names.must_equal HammerCLI.option_accessor_name("id", "label", "name")
80
- end
81
-
82
- it "can change option reader" do
83
- cmd_class.identifiers :name, :id => :option_id_read_method
84
- cmd_class.apipie_options
85
- option_switches.must_equal [["--id"], ["--name"]]
86
- option_attribute_names.must_equal HammerCLI.option_accessor_name("id_read_method", "name")
87
- end
88
-
89
- it "can override inentifiers in inherrited classes" do
90
- Cmd2.new("").class.declared_options.map(&:switches).must_equal [["--id"]]
91
- end
92
-
93
- context "require identifiers" do
94
-
95
- it "must require one of declared identifiers" do
96
- cmd_class.identifiers :id, :name
97
- cmd_class.apipie_options
98
- cmd.run(["--id=1"]).must_equal HammerCLI::EX_OK
99
- end
100
-
101
- it "must raise exception when no attribute is passed" do
102
- cmd_class.identifiers :id, :name
103
- cmd_class.apipie_options
104
- cmd.run([]).must_equal HammerCLI::EX_USAGE
105
- end
106
-
107
- it "must run without error when no identifiers are declared" do
108
- cmd.run([]).must_equal HammerCLI::EX_OK
109
- end
110
-
111
- end
112
-
113
- end
114
-
115
35
  context "setting resources" do
116
36
 
117
37
  it "should set resource and action together" do
@@ -164,126 +84,21 @@ describe HammerCLI::Apipie::Command do
164
84
  end
165
85
  end
166
86
 
167
- context "apipie generated options" do
168
-
169
- class DocumentedCommand < HammerCLI::Apipie::Command
170
- def self.resource_config
171
- { :apidoc_cache_dir => 'test/unit/fixtures/apipie', :apidoc_cache_name => 'documented' }
172
- end
173
- end
174
-
175
- let(:cmd_class) { DocumentedCommand.dup }
176
- let(:cmd) { cmd_class.new("", ctx) }
177
-
178
- context "with one simple param" do
179
-
180
- let(:option) { cmd_class.declared_options[0] }
181
-
182
- before :each do
183
- cmd_class.resource :documented, :index
184
- cmd_class.apipie_options
185
- end
186
-
187
- it "should create an option for the parameter" do
188
- cmd_class.declared_options.length.must_equal 1
189
- end
190
-
191
- it "should set correct switch" do
192
- option.switches.must_be :include?, '--se-arch-val-ue'
193
- end
194
-
195
- it "should set correct attribute name" do
196
- option.attribute_name.must_equal HammerCLI.option_accessor_name('se_arch_val_ue')
197
- end
198
-
199
- it "should set description with html tags stripped" do
200
- option.description.must_equal 'filter results'
201
- end
202
- end
203
-
204
- context "required options" do
205
- before :each do
206
- cmd_class.resource :documented, :create
207
- cmd_class.apipie_options
208
- end
209
-
210
- let(:required_options) { cmd_class.declared_options.reject{|opt| !opt.required?} }
211
-
212
- it "should set required flag for the required options" do
213
- required_options.map(&:attribute_name).sort.must_equal [HammerCLI.option_accessor_name("array_param")]
214
- end
215
- end
216
-
217
- context "with hash params" do
218
- before :each do
219
- cmd_class.resource :documented, :create
220
- cmd_class.apipie_options
221
- end
222
-
223
- it "should create options for all parameters except the hash" do
224
- cmd_class.declared_options.map(&:attribute_name).sort.must_equal HammerCLI.option_accessor_name("array_param", "name", "provider")
225
- end
226
-
227
- it "should name the options correctly" do
228
- cmd_class.declared_options.map(&:attribute_name).sort.must_equal HammerCLI.option_accessor_name("array_param", "name", "provider")
229
- end
230
- end
231
-
232
- context "array params" do
233
- before :each do
234
- cmd_class.resource :documented, :create
235
- cmd_class.apipie_options
236
- end
237
-
238
- let(:cmd) do
239
- cmd_class.new("").tap do |cmd|
240
- cmd.stubs(:execute).returns(0)
241
- end
242
- end
243
-
244
- it "should parse comma separated string to array" do
245
- cmd.run(["--array-param=valA,valB,valC"])
246
- cmd.get_option_value(:array_param).must_equal ['valA', 'valB', 'valC']
247
- end
248
-
249
- it "should parse string to array of length 1" do
250
- cmd.run(["--array-param=valA"])
251
- cmd.get_option_value(:array_param).must_equal ['valA']
252
- end
87
+ it "should raise exception when no action is defined" do
88
+ cmd.stubs(:handle_exception).returns(HammerCLI::EX_SOFTWARE)
89
+ cmd_run.must_equal HammerCLI::EX_SOFTWARE
90
+ end
253
91
 
254
- it "should parse empty string to empty array" do
255
- cmd.run(['--array-param='])
256
- cmd.get_option_value(:array_param).must_equal []
257
- end
92
+ context "resource defined" do
258
93
 
94
+ before :each do
95
+ HammerCLI::Connection.drop_all
96
+ ApipieBindings::API.any_instance.stubs(:call).returns([])
97
+ cmd.class.resource :architectures, :index
259
98
  end
260
99
 
261
-
262
- context "filtering options" do
263
- before :each do
264
- cmd_class.resource :documented, :create
265
- end
266
-
267
- it "should skip filtered options" do
268
- cmd_class.apipie_options :without => ["provider", "name"]
269
- cmd_class.declared_options.map(&:attribute_name).sort.must_equal [HammerCLI.option_accessor_name("array_param")]
270
- end
271
-
272
- it "should skip filtered options defined as symbols" do
273
- cmd_class.apipie_options :without => [:provider, :name]
274
- cmd_class.declared_options.map(&:attribute_name).sort.must_equal [HammerCLI.option_accessor_name("array_param")]
275
- end
276
-
277
- it "should skip single filtered option in array" do
278
- cmd_class.apipie_options :without => ["provider"]
279
- cmd_class.declared_options.map(&:attribute_name).sort.must_equal HammerCLI.option_accessor_name("array_param", "name")
280
- end
281
-
282
- it "should skip single filtered option" do
283
- cmd_class.apipie_options :without => "provider"
284
- cmd_class.declared_options.map(&:attribute_name).sort.must_equal HammerCLI.option_accessor_name("array_param", "name")
285
- end
286
-
100
+ it "should perform a call to api when resource is defined" do
101
+ cmd_run.must_equal 0
287
102
  end
288
103
 
289
104
  end
@@ -0,0 +1,110 @@
1
+ require File.join(File.dirname(__FILE__), '../test_helper')
2
+
3
+
4
+ describe HammerCLI::OptionBuilderContainer do
5
+
6
+ end
7
+
8
+ describe HammerCLI::Apipie::OptionBuilder do
9
+
10
+ let(:api) do
11
+ ApipieBindings::API.new({
12
+ :apidoc_cache_dir => 'test/unit/fixtures/apipie',
13
+ :apidoc_cache_name => 'documented'
14
+ })
15
+ end
16
+
17
+ before :each do
18
+ HammerCLI::I18n.clear
19
+ end
20
+
21
+ let(:action) {api.resource(:documented).action(:index)}
22
+ let(:builder) { HammerCLI::Apipie::OptionBuilder.new(action) }
23
+ let(:builder_options) { {} }
24
+ let(:options) { builder.build(builder_options) }
25
+
26
+ context "with one simple param" do
27
+
28
+ it "should create an option for the parameter" do
29
+ options.length.must_equal 1
30
+ end
31
+
32
+ it "should set correct switch" do
33
+ options[0].switches.must_be :include?, '--se-arch-val-ue'
34
+ end
35
+
36
+ it "should set correct attribute name" do
37
+ options[0].attribute_name.must_equal HammerCLI.option_accessor_name('se_arch_val_ue')
38
+ end
39
+
40
+ it "should set description with html tags stripped" do
41
+ options[0].description.must_equal 'filter results'
42
+ end
43
+ end
44
+
45
+
46
+ context "required options" do
47
+
48
+ let(:action) {api.resource(:documented).action(:create)}
49
+ let(:required_options) { builder.build.reject{|opt| !opt.required?} }
50
+
51
+ it "should set required flag for the required options" do
52
+ required_options.map(&:attribute_name).sort.must_equal [HammerCLI.option_accessor_name("array_param")]
53
+ end
54
+
55
+ it "should not require any option when requirements are disabled" do
56
+ builder.require_options = false
57
+ required_options.map(&:attribute_name).sort.must_equal []
58
+ end
59
+ end
60
+
61
+
62
+ context "with hash params" do
63
+ let(:action) {api.resource(:documented).action(:create)}
64
+
65
+ it "should create options for all parameters except the hash" do
66
+ options.map(&:attribute_name).sort.must_equal HammerCLI.option_accessor_name("array_param", "name", "provider")
67
+ end
68
+
69
+ it "should name the options correctly" do
70
+ options.map(&:attribute_name).sort.must_equal HammerCLI.option_accessor_name("array_param", "name", "provider")
71
+ end
72
+ end
73
+
74
+ context "setting correct normalizers" do
75
+ let(:action) {api.resource(:documented).action(:create)}
76
+
77
+ it "should set array normalizer" do
78
+ array_option = options.find {|o| o.attribute_name == HammerCLI.option_accessor_name("array_param") }
79
+ array_option.value_formatter.class.must_equal HammerCLI::Options::Normalizers::List
80
+ end
81
+
82
+ end
83
+
84
+
85
+ context "filtering options" do
86
+ let(:action) {api.resource(:documented).action(:create)}
87
+
88
+ it "should skip filtered options" do
89
+ builder_options[:without] = ["provider", "name"]
90
+ options.map(&:attribute_name).sort.must_equal [HammerCLI.option_accessor_name("array_param")]
91
+ end
92
+
93
+ it "should skip filtered options defined as symbols" do
94
+ builder_options[:without] = [:provider, :name]
95
+ options.map(&:attribute_name).sort.must_equal [HammerCLI.option_accessor_name("array_param")]
96
+ end
97
+
98
+ it "should skip single filtered option in array" do
99
+ builder_options[:without] = ["provider"]
100
+ options.map(&:attribute_name).sort.must_equal HammerCLI.option_accessor_name("array_param", "name")
101
+ end
102
+
103
+ it "should skip single filtered option" do
104
+ builder_options[:without] = "provider"
105
+ options.map(&:attribute_name).sort.must_equal HammerCLI.option_accessor_name("array_param", "name")
106
+ end
107
+
108
+ end
109
+ end
110
+
@@ -0,0 +1,50 @@
1
+ require File.join(File.dirname(__FILE__), 'test_helper')
2
+
3
+
4
+ describe HammerCLI::I18n do
5
+
6
+ class TestLocaleDomain < HammerCLI::I18n::AbstractLocaleDomain
7
+
8
+ def initialize(name, available)
9
+ @name = name
10
+ @available = available
11
+ end
12
+
13
+ def locale_dir
14
+ File.dirname(__FILE__)
15
+ end
16
+
17
+ def domain_name
18
+ @name
19
+ end
20
+
21
+ def available?
22
+ @available
23
+ end
24
+ end
25
+
26
+ before :each do
27
+ HammerCLI::I18n.clear
28
+ end
29
+
30
+ let(:domain1) { TestLocaleDomain.new('domain1', true) }
31
+ let(:domain2) { TestLocaleDomain.new('domain2', true) }
32
+ let(:unavailable_domain) { TestLocaleDomain.new('domain3', false) }
33
+
34
+ it "registers available domains at gettext" do
35
+ FastGettext.expects(:add_text_domain).with do |name, options|
36
+ (name == domain1.domain_name) && (options[:path] == domain1.locale_dir) && (options[:type] == domain1.type)
37
+ end
38
+ HammerCLI::I18n.add_domain(domain1)
39
+ end
40
+
41
+ it "skips registering domains that are not available" do
42
+ HammerCLI::I18n.add_domain(domain1)
43
+ HammerCLI::I18n.add_domain(domain2)
44
+ HammerCLI::I18n.add_domain(unavailable_domain)
45
+ HammerCLI::I18n.domains.must_equal [domain1, domain2]
46
+ end
47
+
48
+
49
+ end
50
+