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.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +5 -5
  3. data/doc/creating_apipie_commands.md +296 -0
  4. data/doc/creating_commands.md +547 -0
  5. data/doc/developer_docs.md +5 -926
  6. data/doc/development_tips.md +30 -0
  7. data/doc/writing_a_plugin.md +90 -0
  8. data/lib/hammer_cli/abstract.rb +31 -11
  9. data/lib/hammer_cli/apipie/resource.rb +14 -6
  10. data/lib/hammer_cli/apipie/write_command.rb +14 -5
  11. data/lib/hammer_cli/exception_handler.rb +7 -4
  12. data/lib/hammer_cli/options/normalizers.rb +27 -0
  13. data/lib/hammer_cli/output/adapter/abstract.rb +8 -8
  14. data/lib/hammer_cli/output/adapter/csv.rb +37 -4
  15. data/lib/hammer_cli/output/adapter/silent.rb +2 -2
  16. data/lib/hammer_cli/output/dsl.rb +3 -1
  17. data/lib/hammer_cli/output/output.rb +24 -19
  18. data/lib/hammer_cli/utils.rb +18 -0
  19. data/lib/hammer_cli/version.rb +1 -1
  20. data/lib/hammer_cli.rb +1 -0
  21. data/test/unit/abstract_test.rb +296 -0
  22. data/test/unit/apipie/command_test.rb +270 -0
  23. data/test/unit/apipie/fake_api.rb +101 -0
  24. data/test/unit/apipie/read_command_test.rb +34 -0
  25. data/test/unit/apipie/write_command_test.rb +38 -0
  26. data/test/unit/exception_handler_test.rb +45 -0
  27. data/test/unit/main_test.rb +47 -0
  28. data/test/unit/options/normalizers_test.rb +148 -0
  29. data/test/unit/options/option_definition_test.rb +43 -0
  30. data/test/unit/output/adapter/abstract_test.rb +96 -0
  31. data/test/unit/output/adapter/base_test.rb +27 -0
  32. data/test/unit/output/adapter/csv_test.rb +75 -0
  33. data/test/unit/output/adapter/table_test.rb +58 -0
  34. data/test/unit/output/definition_test.rb +27 -0
  35. data/test/unit/output/dsl_test.rb +119 -0
  36. data/test/unit/output/fields_test.rb +97 -0
  37. data/test/unit/output/formatters_test.rb +83 -0
  38. data/test/unit/output/output_test.rb +104 -0
  39. data/test/unit/settings_test.rb +106 -0
  40. data/test/unit/test_helper.rb +20 -0
  41. data/test/unit/utils_test.rb +35 -0
  42. data/test/unit/validator_test.rb +142 -0
  43. metadata +112 -35
  44. data/LICENSE +0 -5
  45. 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