hammer_cli 0.0.9 → 0.0.10
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +5 -5
- data/doc/creating_apipie_commands.md +296 -0
- data/doc/creating_commands.md +547 -0
- data/doc/developer_docs.md +5 -926
- data/doc/development_tips.md +30 -0
- data/doc/writing_a_plugin.md +90 -0
- data/lib/hammer_cli/abstract.rb +31 -11
- data/lib/hammer_cli/apipie/resource.rb +14 -6
- data/lib/hammer_cli/apipie/write_command.rb +14 -5
- data/lib/hammer_cli/exception_handler.rb +7 -4
- data/lib/hammer_cli/options/normalizers.rb +27 -0
- data/lib/hammer_cli/output/adapter/abstract.rb +8 -8
- data/lib/hammer_cli/output/adapter/csv.rb +37 -4
- data/lib/hammer_cli/output/adapter/silent.rb +2 -2
- data/lib/hammer_cli/output/dsl.rb +3 -1
- data/lib/hammer_cli/output/output.rb +24 -19
- data/lib/hammer_cli/utils.rb +18 -0
- data/lib/hammer_cli/version.rb +1 -1
- data/lib/hammer_cli.rb +1 -0
- data/test/unit/abstract_test.rb +296 -0
- data/test/unit/apipie/command_test.rb +270 -0
- data/test/unit/apipie/fake_api.rb +101 -0
- data/test/unit/apipie/read_command_test.rb +34 -0
- data/test/unit/apipie/write_command_test.rb +38 -0
- data/test/unit/exception_handler_test.rb +45 -0
- data/test/unit/main_test.rb +47 -0
- data/test/unit/options/normalizers_test.rb +148 -0
- data/test/unit/options/option_definition_test.rb +43 -0
- data/test/unit/output/adapter/abstract_test.rb +96 -0
- data/test/unit/output/adapter/base_test.rb +27 -0
- data/test/unit/output/adapter/csv_test.rb +75 -0
- data/test/unit/output/adapter/table_test.rb +58 -0
- data/test/unit/output/definition_test.rb +27 -0
- data/test/unit/output/dsl_test.rb +119 -0
- data/test/unit/output/fields_test.rb +97 -0
- data/test/unit/output/formatters_test.rb +83 -0
- data/test/unit/output/output_test.rb +104 -0
- data/test/unit/settings_test.rb +106 -0
- data/test/unit/test_helper.rb +20 -0
- data/test/unit/utils_test.rb +35 -0
- data/test/unit/validator_test.rb +142 -0
- metadata +112 -35
- data/LICENSE +0 -5
- data/hammer_cli_complete +0 -13
@@ -0,0 +1,119 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '../test_helper')
|
2
|
+
|
3
|
+
|
4
|
+
class CustomFieldType
|
5
|
+
attr_reader :options
|
6
|
+
|
7
|
+
def initialize(options)
|
8
|
+
@options = options
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe HammerCLI::Output::Dsl do
|
13
|
+
|
14
|
+
let(:dsl) { HammerCLI::Output::Dsl.new }
|
15
|
+
let(:field_type) { FieldType }
|
16
|
+
let(:first_field) { dsl.fields[0] }
|
17
|
+
let(:last_field) { dsl.fields[-1] }
|
18
|
+
|
19
|
+
it "should be empty after initialization" do
|
20
|
+
dsl.fields.length.must_equal 0
|
21
|
+
end
|
22
|
+
|
23
|
+
context "fields" do
|
24
|
+
it "should create DataField as default field type" do
|
25
|
+
dsl.build do
|
26
|
+
field :f, "F"
|
27
|
+
end
|
28
|
+
first_field.class.must_equal Fields::DataField
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should create DataField of desired type" do
|
32
|
+
dsl.build do
|
33
|
+
field :f, "F", CustomFieldType
|
34
|
+
end
|
35
|
+
first_field.class.must_equal CustomFieldType
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should store all field details" do
|
39
|
+
dsl.build do
|
40
|
+
field :f, "F"
|
41
|
+
end
|
42
|
+
|
43
|
+
first_field.must_equal last_field
|
44
|
+
first_field.path.must_equal [:f]
|
45
|
+
first_field.label.must_equal "F"
|
46
|
+
end
|
47
|
+
|
48
|
+
it "can define multiple fields" do
|
49
|
+
dsl.build do
|
50
|
+
field :name, "Name"
|
51
|
+
field :surname, "Surname"
|
52
|
+
field :email, "Email"
|
53
|
+
end
|
54
|
+
|
55
|
+
dsl.fields.length.must_equal 3
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context "custom fields" do
|
60
|
+
|
61
|
+
let(:options) {{:a => 1, :b => 2}}
|
62
|
+
|
63
|
+
it "it creates field of a desired type" do
|
64
|
+
dsl.build do
|
65
|
+
custom_field CustomFieldType, :a => 1, :b => 2
|
66
|
+
end
|
67
|
+
first_field.class.must_equal CustomFieldType
|
68
|
+
end
|
69
|
+
|
70
|
+
it "passes all options to the field instance" do
|
71
|
+
dsl.build do
|
72
|
+
custom_field CustomFieldType, :a => 1, :b => 2
|
73
|
+
end
|
74
|
+
first_field.options.must_equal options
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
context "path definition" do
|
80
|
+
|
81
|
+
it "from appends to path" do
|
82
|
+
dsl.build do
|
83
|
+
from :key1 do
|
84
|
+
field :email, "Email"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
last_field.path.must_equal [:key1, :email]
|
88
|
+
end
|
89
|
+
|
90
|
+
it "path can be nil to handle the parent structure" do
|
91
|
+
dsl.build do
|
92
|
+
from :key1 do
|
93
|
+
field nil, "Email"
|
94
|
+
end
|
95
|
+
end
|
96
|
+
last_field.path.must_equal [:key1]
|
97
|
+
end
|
98
|
+
|
99
|
+
it "from can be nested" do
|
100
|
+
dsl.build do
|
101
|
+
from :key1 do
|
102
|
+
from :key2 do
|
103
|
+
from :key3 do
|
104
|
+
field :name, "Name"
|
105
|
+
end
|
106
|
+
field :email, "Email"
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
first_field.path.must_equal [:key1, :key2, :key3, :name]
|
111
|
+
last_field.path.must_equal [:key1, :key2, :email]
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
|
116
|
+
|
117
|
+
|
118
|
+
end
|
119
|
+
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '../test_helper')
|
2
|
+
|
3
|
+
|
4
|
+
describe Fields::Field do
|
5
|
+
|
6
|
+
let(:field) { Fields::Field.new }
|
7
|
+
|
8
|
+
describe "get_value" do
|
9
|
+
it "should exist" do
|
10
|
+
assert field.respond_to? :get_value
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should take data as a parameter" do
|
14
|
+
field.method(:get_value).arity.must_equal 1
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
describe Fields::LabeledField do
|
21
|
+
|
22
|
+
let(:label) { "Some Label" }
|
23
|
+
let(:field) { Fields::LabeledField.new :label => label }
|
24
|
+
|
25
|
+
context "labels" do
|
26
|
+
it "has label" do
|
27
|
+
assert field.respond_to? :label
|
28
|
+
end
|
29
|
+
|
30
|
+
it "is possible to set label in constructor" do
|
31
|
+
field.label.must_equal label
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
describe Fields::DataField do
|
38
|
+
|
39
|
+
let(:symbol_data) {{
|
40
|
+
:name => "John Doe",
|
41
|
+
:email => "john.doe@example.com",
|
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
|
+
}}
|
60
|
+
|
61
|
+
let(:label) { "Some Label" }
|
62
|
+
let(:path) { [:address, :city, :name] }
|
63
|
+
let(:field) { Fields::DataField.new :label => label, :path => path }
|
64
|
+
|
65
|
+
it "stores label from constructor" do
|
66
|
+
field.label.must_equal label
|
67
|
+
end
|
68
|
+
|
69
|
+
it "stores path from constructor" do
|
70
|
+
field.path.must_equal path
|
71
|
+
end
|
72
|
+
|
73
|
+
it "default path should be empty array" do
|
74
|
+
Fields::DataField.new.path.must_equal []
|
75
|
+
end
|
76
|
+
|
77
|
+
context "getting data" do
|
78
|
+
|
79
|
+
it "should pick correct value" do
|
80
|
+
field.get_value(symbol_data).must_equal symbol_data[:address][:city][:name]
|
81
|
+
end
|
82
|
+
|
83
|
+
it "should pick correct value independent of key type" do
|
84
|
+
field.get_value(string_data).must_equal string_data["address"]["city"]["name"]
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should pick correct value even if data contains empty key (#3352)" do
|
88
|
+
string_data[''] = {}
|
89
|
+
field.get_value(string_data).must_equal string_data["address"]["city"]["name"]
|
90
|
+
end
|
91
|
+
|
92
|
+
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
|
97
|
+
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '../test_helper')
|
2
|
+
|
3
|
+
describe HammerCLI::Output::Formatters::FormatterLibrary do
|
4
|
+
it "accepts formatter" do
|
5
|
+
lib = HammerCLI::Output::Formatters::FormatterLibrary.new(
|
6
|
+
:Id => HammerCLI::Output::Formatters::FieldFormatter.new)
|
7
|
+
lib.formatter_for_type(Fields::Id).must_be_instance_of HammerCLI::Output::Formatters::FormatterContainer
|
8
|
+
end
|
9
|
+
|
10
|
+
it "can add formatter to instance" do
|
11
|
+
lib = HammerCLI::Output::Formatters::FormatterLibrary.new
|
12
|
+
lib.register_formatter :Id, HammerCLI::Output::Formatters::FieldFormatter.new
|
13
|
+
lib.formatter_for_type(Fields::Id).must_be_instance_of HammerCLI::Output::Formatters::FormatterContainer
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe HammerCLI::Output::Formatters::FieldFormatter do
|
18
|
+
let(:formatter) { HammerCLI::Output::Formatters::FieldFormatter.new }
|
19
|
+
it "has format method" do
|
20
|
+
formatter.respond_to?(:format).must_equal true
|
21
|
+
end
|
22
|
+
|
23
|
+
it "has tags" do
|
24
|
+
formatter.tags.must_be_kind_of Array
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should know if it has matching tags" do
|
28
|
+
formatter.stubs(:tags).returns([:tag])
|
29
|
+
formatter.match?([:tag]).must_equal true
|
30
|
+
formatter.match?([:notag]).must_equal false
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe HammerCLI::Output::Formatters::FormatterContainer do
|
35
|
+
|
36
|
+
class TestFormatter
|
37
|
+
def format(data)
|
38
|
+
data+'.'
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
it "accepts formatter" do
|
43
|
+
container = HammerCLI::Output::Formatters::FormatterContainer.new(TestFormatter.new)
|
44
|
+
container.format('').must_equal '.'
|
45
|
+
end
|
46
|
+
|
47
|
+
it "has format method" do
|
48
|
+
container = HammerCLI::Output::Formatters::FormatterContainer.new
|
49
|
+
container.respond_to?(:format).must_equal true
|
50
|
+
end
|
51
|
+
|
52
|
+
it "can add formatter to instance" do
|
53
|
+
container = HammerCLI::Output::Formatters::FormatterContainer.new(TestFormatter.new)
|
54
|
+
container.add_formatter TestFormatter.new
|
55
|
+
container.format('').must_equal '..'
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe HammerCLI::Output::Formatters::ColorFormatter do
|
60
|
+
it "colorizes the value" do
|
61
|
+
formatter = HammerCLI::Output::Formatters::ColorFormatter.new(:red)
|
62
|
+
formatter.format('red').must_equal "\e[31mred\e[0m"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe HammerCLI::Output::Formatters::DateFormatter do
|
67
|
+
it "formats the date" do
|
68
|
+
formatter = HammerCLI::Output::Formatters::DateFormatter.new
|
69
|
+
formatter.format('2000-01-01 21:01:01').must_equal "2000/01/01 21:01:01"
|
70
|
+
end
|
71
|
+
|
72
|
+
it "returns empty string on wrong value" do
|
73
|
+
formatter = HammerCLI::Output::Formatters::DateFormatter.new
|
74
|
+
formatter.format('wrong value').must_equal ""
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe HammerCLI::Output::Formatters::ListFormatter do
|
79
|
+
it "serializes the value" do
|
80
|
+
formatter = HammerCLI::Output::Formatters::ListFormatter.new
|
81
|
+
formatter.format([1, 2]).must_equal '1, 2'
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '../test_helper')
|
2
|
+
|
3
|
+
describe HammerCLI::Output::Output do
|
4
|
+
|
5
|
+
let(:adapter) { HammerCLI::Output::Adapter::Silent }
|
6
|
+
let(:definition) { HammerCLI::Output::Definition.new }
|
7
|
+
|
8
|
+
let(:context) { { :adapter => :silent } }
|
9
|
+
let(:out_class) { HammerCLI::Output::Output }
|
10
|
+
let(:out) { out_class.new(context) }
|
11
|
+
|
12
|
+
context "messages" do
|
13
|
+
|
14
|
+
let(:msg) { "Some message" }
|
15
|
+
let(:details) { "Some\nmessage\ndetails" }
|
16
|
+
let(:msg_arg) { {:a => 'A'} }
|
17
|
+
|
18
|
+
it "prints info message via adapter" do
|
19
|
+
adapter.any_instance.expects(:print_message).with(msg, {})
|
20
|
+
out.print_message(msg)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "prints info message via adapter with arguments" do
|
24
|
+
adapter.any_instance.expects(:print_message).with(msg, msg_arg)
|
25
|
+
out.print_message(msg, msg_arg)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "prints error message via adapter" do
|
29
|
+
adapter.any_instance.expects(:print_error).with(msg, nil, {})
|
30
|
+
out.print_error(msg, nil)
|
31
|
+
end
|
32
|
+
|
33
|
+
it "prints error message via adapter with arguments" do
|
34
|
+
adapter.any_instance.expects(:print_error).with(msg, nil, msg_arg)
|
35
|
+
out.print_error(msg, nil, msg_arg)
|
36
|
+
end
|
37
|
+
|
38
|
+
it "prints error message with details via adapter" do
|
39
|
+
adapter.any_instance.expects(:print_error).with(msg, details, {})
|
40
|
+
out.print_error(msg, details)
|
41
|
+
end
|
42
|
+
|
43
|
+
it "prints error message from exception via adapter" do
|
44
|
+
adapter.any_instance.expects(:print_error).with(msg, nil, {})
|
45
|
+
out.print_error(Exception.new(msg), nil)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context "data" do
|
50
|
+
|
51
|
+
let(:item1) { {} }
|
52
|
+
let(:item2) { {} }
|
53
|
+
let(:collection) { [item1, item2] }
|
54
|
+
|
55
|
+
it "prints single resource" do
|
56
|
+
adapter.any_instance.expects(:print_records).with([], [{}])
|
57
|
+
out.print_records(definition, item1)
|
58
|
+
end
|
59
|
+
|
60
|
+
it "prints array of resources" do
|
61
|
+
adapter.any_instance.expects(:print_records).with([], collection)
|
62
|
+
out.print_records(definition, collection)
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
context "adapters" do
|
68
|
+
it "should register adapter" do
|
69
|
+
out_class.register_adapter(:test, HammerCLI::Output::Adapter::Silent)
|
70
|
+
out_class.adapters[:test].must_equal(HammerCLI::Output::Adapter::Silent)
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should return required default adapter" do
|
74
|
+
out = out_class.new({}, {:default_adapter => :silent})
|
75
|
+
out.adapter.must_be_instance_of HammerCLI::Output::Adapter::Silent
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should use adapter form context" do
|
79
|
+
out = out_class.new({:adapter => :silent})
|
80
|
+
out.adapter.must_be_instance_of HammerCLI::Output::Adapter::Silent
|
81
|
+
end
|
82
|
+
|
83
|
+
it "should prioritize adapter from the context" do
|
84
|
+
out = out_class.new({:adapter => :table}, {:default_adapter => :silent})
|
85
|
+
out.adapter.must_be_instance_of HammerCLI::Output::Adapter::Table
|
86
|
+
end
|
87
|
+
|
88
|
+
it "should use base adapter if the requested default was not found" do
|
89
|
+
out = out_class.new({}, {:default_adapter => :unknown})
|
90
|
+
out.adapter.must_be_instance_of HammerCLI::Output::Adapter::Base
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
context "formatters" do
|
95
|
+
it "should register formatter" do
|
96
|
+
formatter = HammerCLI::Output::Formatters::FieldFormatter.new
|
97
|
+
out_class.register_formatter(formatter, :type1, :type2)
|
98
|
+
out_class.formatters[:type1].must_equal([formatter])
|
99
|
+
out_class.formatters[:type2].must_equal([formatter])
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
|
+
|
3
|
+
describe HammerCLI::Settings do
|
4
|
+
|
5
|
+
before :each do
|
6
|
+
# clean up global settings
|
7
|
+
HammerCLI::Settings.clear
|
8
|
+
end
|
9
|
+
|
10
|
+
let(:settings) { HammerCLI::Settings }
|
11
|
+
|
12
|
+
it "returns nil when nothing is loaded" do
|
13
|
+
settings.get(:a).must_be_nil
|
14
|
+
settings.get(:a, :b).must_be_nil
|
15
|
+
end
|
16
|
+
|
17
|
+
it "returns nil on unknown key" do
|
18
|
+
settings.load({:a => 1})
|
19
|
+
settings.get(:b).must_be_nil
|
20
|
+
end
|
21
|
+
|
22
|
+
it "returns correct value" do
|
23
|
+
settings.load({:a => 1})
|
24
|
+
settings.get(:a).must_equal 1
|
25
|
+
end
|
26
|
+
|
27
|
+
it "takes both strings and symbols" do
|
28
|
+
settings.load({:a => 1, 'b' => 2})
|
29
|
+
settings.get('a').must_equal 1
|
30
|
+
settings.get(:b).must_equal 2
|
31
|
+
end
|
32
|
+
|
33
|
+
it "finds nested settings" do
|
34
|
+
settings.load({:a => {:b => 1}})
|
35
|
+
settings.get(:a, :b).must_equal 1
|
36
|
+
settings.get(:a, 'b').must_equal 1
|
37
|
+
settings.get('a', :b).must_equal 1
|
38
|
+
end
|
39
|
+
|
40
|
+
it "loads all settings" do
|
41
|
+
settings.load({:a => 1, :b => 2})
|
42
|
+
settings.get(:a).must_equal 1
|
43
|
+
settings.get(:b).must_equal 2
|
44
|
+
end
|
45
|
+
|
46
|
+
it "merges settings on second load" do
|
47
|
+
settings.load({:a => 1, :b => 2, :d => {:e => 4, :f => 5}})
|
48
|
+
settings.load({:b => 'B', :c => 'C', :d => {:e => 'E'}})
|
49
|
+
settings.get(:a).must_equal 1
|
50
|
+
settings.get(:b).must_equal 'B'
|
51
|
+
settings.get(:c).must_equal 'C'
|
52
|
+
settings.get(:d, :e).must_equal 'E'
|
53
|
+
settings.get(:d, :f).must_equal 5
|
54
|
+
end
|
55
|
+
|
56
|
+
it "clear wipes all settings" do
|
57
|
+
settings.load({:a => 1, :b => 2})
|
58
|
+
settings.clear
|
59
|
+
settings.get(:a).must_be_nil
|
60
|
+
settings.get(:b).must_be_nil
|
61
|
+
end
|
62
|
+
|
63
|
+
context "load from file" do
|
64
|
+
|
65
|
+
let(:config1) do
|
66
|
+
config1 = Tempfile.new 'config'
|
67
|
+
config1 << ":host: 'https://localhost/'\n"
|
68
|
+
config1 << ":username: 'admin'\n"
|
69
|
+
config1.close
|
70
|
+
config1
|
71
|
+
end
|
72
|
+
|
73
|
+
let(:config2) do
|
74
|
+
config2 = Tempfile.new 'config2'
|
75
|
+
config2 << ":host: 'https://localhost.localdomain/'\n"
|
76
|
+
config2.close
|
77
|
+
config2
|
78
|
+
end
|
79
|
+
|
80
|
+
let(:config_without_creds) do
|
81
|
+
config_without_creds = Tempfile.new('config_without_creds')
|
82
|
+
config_without_creds << ":host: 'https://localhost.localdomain/'\n"
|
83
|
+
config_without_creds.close
|
84
|
+
config_without_creds
|
85
|
+
end
|
86
|
+
|
87
|
+
it "loads settings from file" do
|
88
|
+
settings.load_from_file [config2.path, config1.path]
|
89
|
+
settings.get(:host).must_equal 'https://localhost.localdomain/'
|
90
|
+
settings.get(:username).must_equal 'admin'
|
91
|
+
end
|
92
|
+
|
93
|
+
it "clears path history on clear invokation" do
|
94
|
+
settings.load_from_file [config2.path]
|
95
|
+
settings.clear
|
96
|
+
settings.path_history.must_equal []
|
97
|
+
end
|
98
|
+
|
99
|
+
it "store config path history" do
|
100
|
+
settings.load_from_file [config2.path, config1.path]
|
101
|
+
settings.path_history.must_equal [config1.path, config2.path]
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'simplecov'
|
2
|
+
require 'pathname'
|
3
|
+
|
4
|
+
SimpleCov.use_merging true
|
5
|
+
SimpleCov.start do
|
6
|
+
command_name 'MiniTest'
|
7
|
+
add_filter 'test'
|
8
|
+
end
|
9
|
+
SimpleCov.root Pathname.new(File.dirname(__FILE__) + "../../../")
|
10
|
+
|
11
|
+
|
12
|
+
require 'minitest/autorun'
|
13
|
+
require 'minitest/spec'
|
14
|
+
require "minitest-spec-context"
|
15
|
+
require "mocha/setup"
|
16
|
+
|
17
|
+
require 'hammer_cli'
|
18
|
+
|
19
|
+
Logging.logger.root.appenders = Logging::Appenders['__test__'] || Logging::Appenders::StringIo.new('__test__')
|
20
|
+
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
|
+
|
3
|
+
|
4
|
+
describe String do
|
5
|
+
|
6
|
+
context "formatting" do
|
7
|
+
|
8
|
+
let(:str) { "AA%<a>s BB%<b>s" }
|
9
|
+
let(:curly_str) { "AA%{a}s BB%{b}s" }
|
10
|
+
let(:pos_str) { "AA%s BB%s" }
|
11
|
+
|
12
|
+
it "should not fail without expected parameters" do
|
13
|
+
str.format({}).must_equal 'AA BB'
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should replace positional parameters" do
|
17
|
+
pos_str.format(['A', 'B']).must_equal 'AAA BBB'
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should replace named parameters" do
|
21
|
+
str.format(:a => 'A', :b => 'B').must_equal 'AAA BBB'
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should replace named parameters with string keys" do
|
25
|
+
str.format('a' => 'A', 'b' => 'B').must_equal 'AAA BBB'
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should replace named parameters marked with curly brackets" do
|
29
|
+
curly_str.format(:a => 'A', :b => 'B').must_equal 'AAA BBB'
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
@@ -0,0 +1,142 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
|
+
|
3
|
+
|
4
|
+
# describe HammerCLI::OptionValidator do
|
5
|
+
|
6
|
+
|
7
|
+
# end
|
8
|
+
|
9
|
+
describe "constraints" do
|
10
|
+
|
11
|
+
class FakeCmd < Clamp::Command
|
12
|
+
def initialize
|
13
|
+
super("")
|
14
|
+
@option_a = 1
|
15
|
+
@option_b = 1
|
16
|
+
@option_c = 1
|
17
|
+
@option_d = nil
|
18
|
+
@option_e = nil
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
let(:cmd) {
|
23
|
+
FakeCmd.new
|
24
|
+
}
|
25
|
+
|
26
|
+
let(:option_names) { ["a", "b", "c", "d", "e"] }
|
27
|
+
let(:options_def) {
|
28
|
+
option_names.collect{ |n| Clamp::Option::Definition.new(["-"+n, "--option-"+n], n.upcase, "Option "+n.upcase) }
|
29
|
+
}
|
30
|
+
let(:options) { options_def.collect{|d| d.of(cmd) } }
|
31
|
+
|
32
|
+
describe HammerCLI::Validator::BaseConstraint do
|
33
|
+
|
34
|
+
let(:cls) { HammerCLI::Validator::BaseConstraint }
|
35
|
+
|
36
|
+
describe "exist?" do
|
37
|
+
it "throws not implemented error" do
|
38
|
+
constraint = cls.new(options, [:option_a, :option_b, :option_c])
|
39
|
+
proc{ constraint.exist? }.must_raise NotImplementedError
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe "rejected" do
|
44
|
+
it "should raise exception when exist? returns true" do
|
45
|
+
constraint = cls.new(options, [])
|
46
|
+
constraint.stubs(:exist?).returns(true)
|
47
|
+
proc{ constraint.rejected }.must_raise HammerCLI::Validator::ValidationError
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should raise exception with a message" do
|
51
|
+
constraint = cls.new(options, [])
|
52
|
+
constraint.stubs(:exist?).returns(true)
|
53
|
+
begin
|
54
|
+
constraint.rejected :msg => "CUSTOM MESSAGE"
|
55
|
+
rescue HammerCLI::Validator::ValidationError => e
|
56
|
+
e.message.must_equal "CUSTOM MESSAGE"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should return nil when exist? returns true" do
|
61
|
+
constraint = cls.new(options, [])
|
62
|
+
constraint.stubs(:exist?).returns(false)
|
63
|
+
constraint.rejected.must_equal nil
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe "required" do
|
68
|
+
it "should raise exception when exist? returns true" do
|
69
|
+
constraint = cls.new(options, [])
|
70
|
+
constraint.stubs(:exist?).returns(false)
|
71
|
+
proc{ constraint.required }.must_raise HammerCLI::Validator::ValidationError
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should raise exception with a message" do
|
75
|
+
constraint = cls.new(options, [])
|
76
|
+
constraint.stubs(:exist?).returns(false)
|
77
|
+
begin
|
78
|
+
constraint.rejected :msg => "CUSTOM MESSAGE"
|
79
|
+
rescue HammerCLI::Validator::ValidationError => e
|
80
|
+
e.message.must_equal "CUSTOM MESSAGE"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should return nil when exist? returns true" do
|
85
|
+
constraint = cls.new(options, [])
|
86
|
+
constraint.stubs(:exist?).returns(true)
|
87
|
+
constraint.required.must_equal nil
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
|
93
|
+
describe HammerCLI::Validator::AllConstraint do
|
94
|
+
|
95
|
+
let(:cls) { HammerCLI::Validator::AllConstraint }
|
96
|
+
|
97
|
+
describe "exist?" do
|
98
|
+
|
99
|
+
it "should return true when no options are passed" do
|
100
|
+
constraint = cls.new(options, [])
|
101
|
+
constraint.exist?.must_equal true
|
102
|
+
end
|
103
|
+
|
104
|
+
it "should return true when all the options exist" do
|
105
|
+
constraint = cls.new(options, [:option_a, :option_b, :option_c])
|
106
|
+
constraint.exist?.must_equal true
|
107
|
+
end
|
108
|
+
|
109
|
+
it "should return false when one of the options is missing" do
|
110
|
+
constraint = cls.new(options, [:option_a, :option_b, :option_c, :option_d])
|
111
|
+
constraint.exist?.must_equal false
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
116
|
+
|
117
|
+
describe HammerCLI::Validator::AnyConstraint do
|
118
|
+
|
119
|
+
let(:cls) { HammerCLI::Validator::AnyConstraint }
|
120
|
+
|
121
|
+
describe "exist?" do
|
122
|
+
|
123
|
+
it "should return true when no options are passed" do
|
124
|
+
constraint = cls.new(options, [])
|
125
|
+
constraint.exist?.must_equal true
|
126
|
+
end
|
127
|
+
|
128
|
+
it "should return true when one of the options exist" do
|
129
|
+
constraint = cls.new(options, [:option_a, :option_d, :option_e])
|
130
|
+
constraint.exist?.must_equal true
|
131
|
+
end
|
132
|
+
|
133
|
+
it "should return false when all the options are missing" do
|
134
|
+
constraint = cls.new(options, [:option_d, :option_e])
|
135
|
+
constraint.exist?.must_equal false
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
end
|
140
|
+
|
141
|
+
|
142
|
+
end
|