hammer_cli 0.0.9 → 0.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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