hammer_cli 0.0.18 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +3 -314
- data/bin/hammer +45 -6
- data/config/cli.modules.d/module_config_template.yml +4 -0
- data/config/cli_config.template.yml +9 -11
- data/doc/developer_docs.md +1 -0
- data/doc/i18n.md +85 -0
- data/doc/installation.md +321 -0
- data/lib/hammer_cli.rb +3 -0
- data/lib/hammer_cli/abstract.rb +15 -24
- data/lib/hammer_cli/apipie/command.rb +13 -7
- data/lib/hammer_cli/apipie/options.rb +14 -16
- data/lib/hammer_cli/apipie/read_command.rb +6 -1
- data/lib/hammer_cli/apipie/resource.rb +48 -58
- data/lib/hammer_cli/apipie/write_command.rb +5 -1
- data/lib/hammer_cli/completer.rb +77 -21
- data/lib/hammer_cli/connection.rb +44 -0
- data/lib/hammer_cli/exception_handler.rb +15 -4
- data/lib/hammer_cli/exceptions.rb +6 -0
- data/lib/hammer_cli/i18n.rb +95 -0
- data/lib/hammer_cli/logger.rb +3 -3
- data/lib/hammer_cli/main.rb +12 -11
- data/lib/hammer_cli/modules.rb +19 -6
- data/lib/hammer_cli/options/normalizers.rb +42 -7
- data/lib/hammer_cli/options/option_definition.rb +2 -2
- data/lib/hammer_cli/output.rb +1 -0
- data/lib/hammer_cli/output/adapter/abstract.rb +20 -0
- data/lib/hammer_cli/output/adapter/base.rb +49 -78
- data/lib/hammer_cli/output/adapter/csv.rb +5 -5
- data/lib/hammer_cli/output/adapter/table.rb +41 -10
- data/lib/hammer_cli/output/dsl.rb +1 -1
- data/lib/hammer_cli/output/field_filter.rb +21 -0
- data/lib/hammer_cli/output/fields.rb +44 -78
- data/lib/hammer_cli/output/formatters.rb +38 -0
- data/lib/hammer_cli/settings.rb +28 -6
- data/lib/hammer_cli/shell.rb +58 -57
- data/lib/hammer_cli/utils.rb +14 -0
- data/lib/hammer_cli/validator.rb +5 -5
- data/lib/hammer_cli/version.rb +1 -1
- data/locale/Makefile +64 -0
- data/locale/hammer-cli.pot +203 -0
- data/locale/zanata.xml +29 -0
- data/test/unit/apipie/command_test.rb +42 -25
- data/test/unit/apipie/read_command_test.rb +10 -7
- data/test/unit/apipie/write_command_test.rb +9 -8
- data/test/unit/completer_test.rb +206 -21
- data/test/unit/connection_test.rb +68 -0
- data/test/unit/fixtures/apipie/architectures.json +153 -0
- data/test/unit/fixtures/apipie/documented.json +79 -0
- data/test/unit/fixtures/json_input/invalid.json +12 -0
- data/test/unit/fixtures/json_input/valid.json +12 -0
- data/test/unit/history_test.rb +71 -0
- data/test/unit/main_test.rb +9 -0
- data/test/unit/modules_test.rb +22 -6
- data/test/unit/options/field_filter_test.rb +27 -0
- data/test/unit/options/normalizers_test.rb +53 -0
- data/test/unit/output/adapter/base_test.rb +162 -10
- data/test/unit/output/adapter/csv_test.rb +16 -3
- data/test/unit/output/adapter/table_test.rb +97 -13
- data/test/unit/output/dsl_test.rb +74 -6
- data/test/unit/output/fields_test.rb +93 -62
- data/test/unit/output/formatters_test.rb +47 -0
- data/test/unit/settings_test.rb +35 -4
- data/test/unit/utils_test.rb +45 -0
- metadata +85 -4
- data/test/unit/apipie/fake_api.rb +0 -101
@@ -20,15 +20,15 @@ describe HammerCLI::Output::Dsl do
|
|
20
20
|
dsl.fields.length.must_equal 0
|
21
21
|
end
|
22
22
|
|
23
|
-
|
24
|
-
it "should create
|
23
|
+
describe "fields" do
|
24
|
+
it "should create Field as default field type" do
|
25
25
|
dsl.build do
|
26
26
|
field :f, "F"
|
27
27
|
end
|
28
|
-
first_field.class.must_equal Fields::
|
28
|
+
first_field.class.must_equal Fields::Field
|
29
29
|
end
|
30
30
|
|
31
|
-
it "should create
|
31
|
+
it "should create field of desired type" do
|
32
32
|
dsl.build do
|
33
33
|
field :f, "F", CustomFieldType
|
34
34
|
end
|
@@ -56,7 +56,7 @@ describe HammerCLI::Output::Dsl do
|
|
56
56
|
end
|
57
57
|
end
|
58
58
|
|
59
|
-
|
59
|
+
describe "custom fields" do
|
60
60
|
|
61
61
|
let(:options) {{:a => 1, :b => 2}}
|
62
62
|
|
@@ -76,7 +76,7 @@ describe HammerCLI::Output::Dsl do
|
|
76
76
|
|
77
77
|
end
|
78
78
|
|
79
|
-
|
79
|
+
describe "path definition" do
|
80
80
|
|
81
81
|
it "from appends to path" do
|
82
82
|
dsl.build do
|
@@ -114,6 +114,74 @@ describe HammerCLI::Output::Dsl do
|
|
114
114
|
end
|
115
115
|
|
116
116
|
|
117
|
+
describe "label" do
|
118
|
+
|
119
|
+
it "creates field of type Label" do
|
120
|
+
dsl.build do
|
121
|
+
label "Label"
|
122
|
+
end
|
123
|
+
first_field.class.must_equal Fields::Label
|
124
|
+
end
|
125
|
+
|
126
|
+
it "allows to define subfields with dsl" do
|
127
|
+
dsl.build do
|
128
|
+
label "Label" do
|
129
|
+
field :a, "A"
|
130
|
+
field :b, "B"
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
first_field.fields.map(&:label).must_equal ["A", "B"]
|
135
|
+
end
|
136
|
+
|
137
|
+
it "sets correct path to subfields" do
|
138
|
+
dsl.build do
|
139
|
+
from :nest do
|
140
|
+
label "Label" do
|
141
|
+
field :a, "A"
|
142
|
+
field :b, "B"
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
first_field.fields.map(&:path).must_equal [[:a], [:b]]
|
148
|
+
end
|
149
|
+
|
150
|
+
end
|
151
|
+
|
152
|
+
|
153
|
+
describe "collection" do
|
154
|
+
|
155
|
+
it "creates field of type Collection" do
|
156
|
+
dsl.build do
|
157
|
+
collection :f, "F"
|
158
|
+
end
|
159
|
+
first_field.class.must_equal Fields::Collection
|
160
|
+
end
|
161
|
+
|
162
|
+
it "allows to define subfields with dsl" do
|
163
|
+
dsl.build do
|
164
|
+
collection :nest, "Label" do
|
165
|
+
field :a, "A"
|
166
|
+
field :b, "B"
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
first_field.fields.map(&:label).must_equal ["A", "B"]
|
171
|
+
end
|
172
|
+
|
173
|
+
it "sets correct path to subfields" do
|
174
|
+
dsl.build do
|
175
|
+
collection :nest, "Label" do
|
176
|
+
field :a, "A"
|
177
|
+
field :b, "B"
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
first_field.fields.map(&:path).must_equal [[:a], [:b]]
|
182
|
+
end
|
183
|
+
|
184
|
+
end
|
117
185
|
|
118
186
|
end
|
119
187
|
|
@@ -1,97 +1,128 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), '../test_helper')
|
2
2
|
|
3
3
|
|
4
|
+
|
4
5
|
describe Fields::Field do
|
5
6
|
|
6
|
-
let(:
|
7
|
+
let(:label) { "Some Label" }
|
8
|
+
let(:path) { [:address, :city, :name] }
|
9
|
+
let(:field) { Fields::Field.new :label => label, :path => path, :some => :parameter }
|
10
|
+
let(:blank_field) { Fields::Field.new :label => label, :path => path, :hide_blank => true }
|
7
11
|
|
8
|
-
describe "get_value" do
|
9
|
-
it "should exist" do
|
10
|
-
assert field.respond_to? :get_value
|
11
|
-
end
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
end
|
13
|
+
it "stores label from constructor" do
|
14
|
+
field.label.must_equal label
|
16
15
|
end
|
17
16
|
|
18
|
-
|
17
|
+
it "stores path from constructor" do
|
18
|
+
field.path.must_equal path
|
19
|
+
end
|
19
20
|
|
20
|
-
|
21
|
+
it "default path should be empty array" do
|
22
|
+
Fields::Field.new.path.must_equal []
|
23
|
+
end
|
21
24
|
|
22
|
-
|
23
|
-
let(:field) { Fields::LabeledField.new :label => label }
|
25
|
+
describe "parameters" do
|
24
26
|
|
25
|
-
|
26
|
-
|
27
|
-
|
27
|
+
it "returns all parameters passed to a filed" do
|
28
|
+
expected_params = {
|
29
|
+
:label => label,
|
30
|
+
:path => path,
|
31
|
+
:some => :parameter
|
32
|
+
}
|
33
|
+
field.parameters.must_equal expected_params
|
28
34
|
end
|
29
35
|
|
30
|
-
it "is possible to set label in constructor" do
|
31
|
-
field.label.must_equal label
|
32
|
-
end
|
33
36
|
end
|
34
37
|
|
35
|
-
|
38
|
+
describe "display?" do
|
36
39
|
|
37
|
-
|
40
|
+
context "blank is allowed" do
|
38
41
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
:address => {
|
43
|
-
:city => {
|
44
|
-
:name => "New York",
|
45
|
-
:zip => "1234"
|
46
|
-
}
|
47
|
-
}
|
48
|
-
}}
|
49
|
-
|
50
|
-
let(:string_data) {{
|
51
|
-
"name" => "Eric Doe",
|
52
|
-
"email" => "eric.doe@example.com",
|
53
|
-
"address" => {
|
54
|
-
"city" => {
|
55
|
-
"name" => "Boston",
|
56
|
-
"zip" => "6789"
|
57
|
-
}
|
58
|
-
}
|
59
|
-
}}
|
42
|
+
it "returns false the value is nil" do
|
43
|
+
field.display?(nil).must_equal true
|
44
|
+
end
|
60
45
|
|
61
|
-
|
62
|
-
|
63
|
-
|
46
|
+
it "returns true when there is some data under the path" do
|
47
|
+
field.display?("some value").must_equal true
|
48
|
+
end
|
49
|
+
end
|
64
50
|
|
65
|
-
it "stores label from constructor" do
|
66
|
-
field.label.must_equal label
|
67
|
-
end
|
68
51
|
|
69
|
-
|
70
|
-
|
71
|
-
|
52
|
+
context "blank is not allowed" do
|
53
|
+
|
54
|
+
it "returns false the value is nil" do
|
55
|
+
blank_field.display?(nil).must_equal false
|
56
|
+
end
|
57
|
+
|
58
|
+
it "returns true when there is some data under the path" do
|
59
|
+
blank_field.display?("some value").must_equal true
|
60
|
+
end
|
61
|
+
end
|
72
62
|
|
73
|
-
it "default path should be empty array" do
|
74
|
-
Fields::DataField.new.path.must_equal []
|
75
63
|
end
|
76
64
|
|
77
|
-
|
65
|
+
describe "hide_blank?" do
|
78
66
|
|
79
|
-
it "
|
80
|
-
|
67
|
+
it "defaults to false" do
|
68
|
+
Fields::Field.new.hide_blank?.must_equal false
|
81
69
|
end
|
82
70
|
|
83
|
-
it "
|
84
|
-
|
71
|
+
it "can be set to true in the constructor" do
|
72
|
+
blank_field.hide_blank?.must_equal true
|
85
73
|
end
|
86
74
|
|
87
|
-
|
88
|
-
|
89
|
-
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
|
80
|
+
describe Fields::ContainerField do
|
81
|
+
|
82
|
+
describe "display?" do
|
83
|
+
|
84
|
+
context "blank is allowed" do
|
85
|
+
let(:field) { Fields::ContainerField.new :label => "Label" }
|
86
|
+
|
87
|
+
it "returns false the value is nil" do
|
88
|
+
field.display?(nil).must_equal true
|
89
|
+
end
|
90
|
+
|
91
|
+
it "returns false the value is empty array" do
|
92
|
+
field.display?([]).must_equal true
|
93
|
+
end
|
94
|
+
|
95
|
+
it "returns false the value is empty hash" do
|
96
|
+
field.display?({}).must_equal true
|
97
|
+
end
|
98
|
+
|
99
|
+
it "returns true when there is some data under the path" do
|
100
|
+
field.display?(["some value"]).must_equal true
|
101
|
+
end
|
102
|
+
|
90
103
|
end
|
91
104
|
|
105
|
+
context "blank is not allowed" do
|
106
|
+
let(:field) { Fields::ContainerField.new :label => "Label", :hide_blank => true }
|
92
107
|
|
93
|
-
|
108
|
+
it "returns false the value is nil" do
|
109
|
+
field.display?(nil).must_equal false
|
110
|
+
end
|
94
111
|
|
95
|
-
|
112
|
+
it "returns false the value is empty array" do
|
113
|
+
field.display?([]).must_equal false
|
114
|
+
end
|
96
115
|
|
116
|
+
it "returns false the value is empty hash" do
|
117
|
+
field.display?({}).must_equal false
|
118
|
+
end
|
97
119
|
|
120
|
+
it "returns true when there is some data under the path" do
|
121
|
+
field.display?(["some value"]).must_equal true
|
122
|
+
end
|
123
|
+
|
124
|
+
end
|
125
|
+
|
126
|
+
end
|
127
|
+
|
128
|
+
end
|
@@ -91,3 +91,50 @@ describe HammerCLI::Output::Formatters::ListFormatter do
|
|
91
91
|
formatter.format('some string').must_equal 'some string'
|
92
92
|
end
|
93
93
|
end
|
94
|
+
|
95
|
+
|
96
|
+
describe HammerCLI::Output::Formatters::KeyValueFormatter do
|
97
|
+
|
98
|
+
let(:params) {
|
99
|
+
{
|
100
|
+
:name => "Name",
|
101
|
+
"value" => "Value",
|
102
|
+
}
|
103
|
+
}
|
104
|
+
|
105
|
+
it "serializes the value" do
|
106
|
+
formatter = HammerCLI::Output::Formatters::KeyValueFormatter.new
|
107
|
+
formatter.format(params).must_equal 'Name => Value'
|
108
|
+
end
|
109
|
+
|
110
|
+
it "returns empty string when the input is nil" do
|
111
|
+
formatter = HammerCLI::Output::Formatters::KeyValueFormatter.new
|
112
|
+
formatter.format(nil).must_equal ''
|
113
|
+
end
|
114
|
+
|
115
|
+
it "returns empty string value when the input is not a hash" do
|
116
|
+
formatter = HammerCLI::Output::Formatters::KeyValueFormatter.new
|
117
|
+
formatter.format('some string').must_equal ''
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
|
122
|
+
|
123
|
+
describe HammerCLI::Output::Formatters::LongTextFormatter do
|
124
|
+
|
125
|
+
it "prepends new line" do
|
126
|
+
formatter = HammerCLI::Output::Formatters::LongTextFormatter.new
|
127
|
+
formatter.format("Some\nmultiline\ntext").must_equal "\n Some\n multiline\n text"
|
128
|
+
end
|
129
|
+
|
130
|
+
it "accepts nil" do
|
131
|
+
formatter = HammerCLI::Output::Formatters::LongTextFormatter.new
|
132
|
+
formatter.format(nil).must_equal "\n "
|
133
|
+
end
|
134
|
+
|
135
|
+
it "enables to switch indentation off" do
|
136
|
+
formatter = HammerCLI::Output::Formatters::LongTextFormatter.new(:indent => false)
|
137
|
+
formatter.format("Some\nmultiline\ntext").must_equal "\nSome\nmultiline\ntext"
|
138
|
+
end
|
139
|
+
|
140
|
+
end
|
data/test/unit/settings_test.rb
CHANGED
@@ -43,6 +43,12 @@ describe HammerCLI::Settings do
|
|
43
43
|
settings.get(:b).must_equal 2
|
44
44
|
end
|
45
45
|
|
46
|
+
it "dumps all settings" do
|
47
|
+
data = {:a => 1, :b => 2}
|
48
|
+
settings.load(data)
|
49
|
+
settings.dump.must_equal data
|
50
|
+
end
|
51
|
+
|
46
52
|
it "merges settings on second load" do
|
47
53
|
settings.load({:a => 1, :b => 2, :d => {:e => 4, :f => 5}})
|
48
54
|
settings.load({:b => 'B', :c => 'C', :d => {:e => 'E'}})
|
@@ -60,7 +66,7 @@ describe HammerCLI::Settings do
|
|
60
66
|
settings.get(:b).must_be_nil
|
61
67
|
end
|
62
68
|
|
63
|
-
context "load from
|
69
|
+
context "load from paths" do
|
64
70
|
|
65
71
|
let(:config1) do
|
66
72
|
config1 = Tempfile.new 'config'
|
@@ -85,22 +91,47 @@ describe HammerCLI::Settings do
|
|
85
91
|
end
|
86
92
|
|
87
93
|
it "loads settings from file" do
|
88
|
-
settings.
|
94
|
+
settings.load_from_paths [config2.path, config1.path]
|
89
95
|
settings.get(:host).must_equal 'https://localhost.localdomain/'
|
90
96
|
settings.get(:username).must_equal 'admin'
|
91
97
|
end
|
92
98
|
|
93
99
|
it "clears path history on clear invokation" do
|
94
|
-
settings.
|
100
|
+
settings.load_from_paths [config2.path]
|
95
101
|
settings.clear
|
96
102
|
settings.path_history.must_equal []
|
97
103
|
end
|
98
104
|
|
99
105
|
it "store config path history" do
|
100
|
-
settings.
|
106
|
+
settings.load_from_paths [config2.path, config1.path]
|
101
107
|
settings.path_history.must_equal [config1.path, config2.path]
|
102
108
|
end
|
103
109
|
|
110
|
+
it "loads settings from dir" do
|
111
|
+
dir = Dir.mktmpdir
|
112
|
+
begin
|
113
|
+
File.open(File.join(dir, "cli_config.yml"), "w") do |f|
|
114
|
+
f.write(":param1: 'value1'\n")
|
115
|
+
end
|
116
|
+
module_dir = File.join(dir, 'cli.modules.d')
|
117
|
+
Dir.mkdir(module_dir)
|
118
|
+
File.open(File.join(module_dir, "cli_config.yml"), "w") do |f|
|
119
|
+
f.write(":module:\n")
|
120
|
+
f.write(" :param2: 'value2'\n")
|
121
|
+
end
|
122
|
+
|
123
|
+
settings.load_from_paths [config1.path, dir]
|
124
|
+
|
125
|
+
settings.get(:host).must_equal 'https://localhost/'
|
126
|
+
settings.get(:username).must_equal 'admin'
|
127
|
+
settings.get(:param1).must_equal 'value1'
|
128
|
+
settings.get(:module, :param2).must_equal 'value2'
|
129
|
+
|
130
|
+
ensure
|
131
|
+
FileUtils.remove_entry dir
|
132
|
+
end
|
133
|
+
|
134
|
+
end
|
104
135
|
end
|
105
136
|
end
|
106
137
|
|
data/test/unit/utils_test.rb
CHANGED
@@ -44,5 +44,50 @@ describe String do
|
|
44
44
|
|
45
45
|
end
|
46
46
|
|
47
|
+
describe "indent" do
|
48
|
+
|
49
|
+
it "indents single line string" do
|
50
|
+
"line one".indent_with(" ").must_equal " line one"
|
51
|
+
end
|
52
|
+
|
53
|
+
it "indents multi line string" do
|
54
|
+
"line one\nline two".indent_with(" ").must_equal " line one\n line two"
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
describe "interactive?" do
|
60
|
+
|
61
|
+
before :each do
|
62
|
+
@tty = STDOUT.tty?
|
63
|
+
STDOUT.stubs(:'tty?').returns(true)
|
64
|
+
end
|
65
|
+
|
66
|
+
after :each do
|
67
|
+
STDOUT.stubs(:'tty?').returns(@tty)
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should be true when called in tty" do
|
71
|
+
HammerCLI::Settings.load({
|
72
|
+
:ui => { :interactive => nil },
|
73
|
+
:_params => { :interactive => nil } })
|
74
|
+
HammerCLI::interactive?.must_equal true
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should by false when cli arg set" do
|
78
|
+
HammerCLI::Settings.load({
|
79
|
+
:ui => { :interactive => nil },
|
80
|
+
:_params => { :interactive => false } })
|
81
|
+
HammerCLI::interactive?.must_equal false
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should by false when turned off in cfg" do
|
85
|
+
HammerCLI::Settings.load({
|
86
|
+
:ui => { :interactive => false },
|
87
|
+
:_params => { :interactive => nil } })
|
88
|
+
HammerCLI::interactive?.must_equal false
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
47
92
|
end
|
48
93
|
|