command_mapper 0.1.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/ruby.yml +27 -0
  3. data/.gitignore +10 -0
  4. data/.rspec +1 -0
  5. data/.yardopts +1 -0
  6. data/ChangeLog.md +25 -0
  7. data/Gemfile +15 -0
  8. data/LICENSE.txt +20 -0
  9. data/README.md +369 -0
  10. data/Rakefile +12 -0
  11. data/commnad_mapper.gemspec +61 -0
  12. data/gemspec.yml +23 -0
  13. data/lib/command_mapper/arg.rb +75 -0
  14. data/lib/command_mapper/argument.rb +142 -0
  15. data/lib/command_mapper/command.rb +606 -0
  16. data/lib/command_mapper/exceptions.rb +19 -0
  17. data/lib/command_mapper/option.rb +282 -0
  18. data/lib/command_mapper/option_value.rb +21 -0
  19. data/lib/command_mapper/sudo.rb +73 -0
  20. data/lib/command_mapper/types/enum.rb +35 -0
  21. data/lib/command_mapper/types/hex.rb +82 -0
  22. data/lib/command_mapper/types/input_dir.rb +35 -0
  23. data/lib/command_mapper/types/input_file.rb +35 -0
  24. data/lib/command_mapper/types/input_path.rb +29 -0
  25. data/lib/command_mapper/types/key_value.rb +131 -0
  26. data/lib/command_mapper/types/key_value_list.rb +45 -0
  27. data/lib/command_mapper/types/list.rb +90 -0
  28. data/lib/command_mapper/types/map.rb +64 -0
  29. data/lib/command_mapper/types/num.rb +50 -0
  30. data/lib/command_mapper/types/str.rb +85 -0
  31. data/lib/command_mapper/types/type.rb +102 -0
  32. data/lib/command_mapper/types.rb +6 -0
  33. data/lib/command_mapper/version.rb +4 -0
  34. data/lib/command_mapper.rb +2 -0
  35. data/spec/arg_spec.rb +137 -0
  36. data/spec/argument_spec.rb +513 -0
  37. data/spec/commnad_spec.rb +1175 -0
  38. data/spec/exceptions_spec.rb +14 -0
  39. data/spec/option_spec.rb +882 -0
  40. data/spec/option_value_spec.rb +17 -0
  41. data/spec/spec_helper.rb +6 -0
  42. data/spec/sudo_spec.rb +24 -0
  43. data/spec/types/enum_spec.rb +31 -0
  44. data/spec/types/hex_spec.rb +158 -0
  45. data/spec/types/input_dir_spec.rb +30 -0
  46. data/spec/types/input_file_spec.rb +34 -0
  47. data/spec/types/input_path_spec.rb +32 -0
  48. data/spec/types/key_value_list_spec.rb +100 -0
  49. data/spec/types/key_value_spec.rb +272 -0
  50. data/spec/types/list_spec.rb +143 -0
  51. data/spec/types/map_spec.rb +62 -0
  52. data/spec/types/num_spec.rb +90 -0
  53. data/spec/types/str_spec.rb +232 -0
  54. data/spec/types/type_spec.rb +59 -0
  55. metadata +118 -0
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+ require 'command_mapper/option_value'
3
+ require 'command_mapper/types/list'
4
+
5
+ describe CommandMapper::OptionValue do
6
+ describe "#format" do
7
+ let(:type) { Types::List.new }
8
+
9
+ subject { described_class.new(type: type) }
10
+
11
+ let(:value) { [1,2,3] }
12
+
13
+ it "must call the #type.format" do
14
+ expect(subject.format(value)).to eq(type.format(value))
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,6 @@
1
+ require 'rspec'
2
+ require 'command_mapper/version'
3
+ include CommandMapper
4
+
5
+ require 'simplecov'
6
+ SimpleCov.start
data/spec/sudo_spec.rb ADDED
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+ require 'command_mapper/sudo'
3
+
4
+ describe CommandMapper::Sudo do
5
+ let(:command) { %w[ls -la /root] }
6
+
7
+ subject { described_class.new({command: command}) }
8
+
9
+ describe "#initialize" do
10
+ it "must accept a command keyword" do
11
+ expect(subject.command).to eq(command)
12
+ end
13
+ end
14
+
15
+ describe "#argv" do
16
+ it "the first argument must be 'sudo'" do
17
+ expect(subject.command_argv.first).to eq('sudo')
18
+ end
19
+
20
+ it "must end with the command arguments" do
21
+ expect(subject.command_argv[-command.length..-1]).to eq(command)
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+ require 'command_mapper/types/enum'
3
+
4
+ describe CommandMapper::Types::Enum do
5
+ let(:values) { [:foo, 42, :bar] }
6
+
7
+ subject { described_class.new(values) }
8
+
9
+ describe "#initialize" do
10
+ it "must set #values" do
11
+ expect(subject.values).to eq(values)
12
+ end
13
+
14
+ it "must populate #map with the values and their String forms" do
15
+ expect(subject.map).to eq(
16
+ Hash[values.map { |value|
17
+ [value, value.to_s]
18
+ }]
19
+ )
20
+ end
21
+ end
22
+
23
+ describe ".[]" do
24
+ subject { described_class[*values] }
25
+
26
+ it "must create a new Enum with the given values" do
27
+ expect(subject).to be_kind_of(described_class)
28
+ expect(subject.values).to eq(values)
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,158 @@
1
+ require 'spec_helper'
2
+ require 'command_mapper/types/hex'
3
+
4
+ describe CommandMapper::Types::Hex do
5
+ describe "#initialize" do
6
+ it "must default #leading_zero? to false" do
7
+ expect(subject.leading_zero?).to be(false)
8
+ end
9
+
10
+ context "when initialized with leading_zero: true" do
11
+ subject { described_class.new(leading_zero: true) }
12
+
13
+ it "must set #leading_zero? to true" do
14
+ expect(subject.leading_zero?).to be(true)
15
+ end
16
+ end
17
+ end
18
+
19
+ describe "#leading_zero?" do
20
+ context "when initialized with leading_zero: true" do
21
+ subject { described_class.new(leading_zero: true) }
22
+
23
+ it "must return true" do
24
+ expect(subject.leading_zero?).to be(true)
25
+ end
26
+ end
27
+
28
+ context "when initialized with leading_zero: false" do
29
+ subject { described_class.new(leading_zero: false) }
30
+
31
+ it "must return false" do
32
+ expect(subject.leading_zero?).to be(false)
33
+ end
34
+ end
35
+ end
36
+
37
+ describe "#validate" do
38
+ context "when given a String" do
39
+ context "and the String only contains decimal digits" do
40
+ let(:value) { "0123456789" }
41
+
42
+ it "must return true" do
43
+ expect(subject.validate(value)).to be(true)
44
+ end
45
+
46
+ context "and the String begins with a '0x'" do
47
+ let(:value) { "0x0123456789" }
48
+
49
+ it "must return true" do
50
+ expect(subject.validate(value)).to be(true)
51
+ end
52
+ end
53
+
54
+ context "and the String contains a newline" do
55
+ let(:value) { "01234\n56789" }
56
+
57
+ it "must return [false, \"not in hex format (...)\"]" do
58
+ expect(subject.validate(value)).to eq(
59
+ [false, "not in hex format (#{value.inspect})"]
60
+ )
61
+ end
62
+ end
63
+ end
64
+
65
+ context "and the String only contains hex digits" do
66
+ let(:value) { "abcdef" }
67
+
68
+ it "must return true" do
69
+ expect(subject.validate(value)).to be(true)
70
+ end
71
+
72
+ context "and the String begins with a '0x'" do
73
+ let(:value) { "0xabcdef" }
74
+
75
+ it "must return true" do
76
+ expect(subject.validate(value)).to be(true)
77
+ end
78
+ end
79
+
80
+ context "and the String contains a newline" do
81
+ let(:value) { "abc\ndef" }
82
+
83
+ it "must return [false, \"not in hex format (...)\"]" do
84
+ expect(subject.validate(value)).to eq(
85
+ [false, "not in hex format (#{value.inspect})"]
86
+ )
87
+ end
88
+ end
89
+ end
90
+
91
+ context "but the String does not contain other characters" do
92
+ let(:value) { "foo" }
93
+
94
+ it "must return [false, \"not in hex format (...)\"]" do
95
+ expect(subject.validate(value)).to eq(
96
+ [false, "not in hex format (#{value.inspect})"]
97
+ )
98
+ end
99
+
100
+ context "and the String contains a newline" do
101
+ let(:value) { "foo\nbar" }
102
+
103
+ it "must return [false, \"not in hex format (...)\"]" do
104
+ expect(subject.validate(value)).to eq(
105
+ [false, "not in hex format (#{value.inspect})"]
106
+ )
107
+ end
108
+ end
109
+ end
110
+ end
111
+ end
112
+
113
+ describe "#format" do
114
+ context "when given an Integer" do
115
+ let(:value) { 255 }
116
+
117
+ it "must return the hexadecimal form of the Integer" do
118
+ expect(subject.format(value)).to eq("ff")
119
+ end
120
+
121
+ context "when initialized with leading_zero: true" do
122
+ subject { described_class.new(leading_zero: true) }
123
+
124
+ it "must prepend the hexadecimal number with '0x'" do
125
+ expect(subject.format(value)).to eq("0xff")
126
+ end
127
+ end
128
+ end
129
+
130
+ context "when given a String" do
131
+ context "and it contains hexadecimal digits" do
132
+ let(:value) { "ff" }
133
+
134
+ it "must return the String" do
135
+ expect(subject.format(value)).to eq("ff")
136
+ end
137
+
138
+ context "but the String does start with '0x'" do
139
+ let(:value) { "0xff" }
140
+
141
+ it "must remove '0x' prefix" do
142
+ expect(subject.format(value)).to eq("ff")
143
+ end
144
+ end
145
+
146
+ context "when #leading_zero? is true" do
147
+ subject { described_class.new(leading_zero: true) }
148
+
149
+ context "but the String does not start with '0x'" do
150
+ it "must prepend the String with '0x'" do
151
+ expect(subject.format(value)).to eq("0xff")
152
+ end
153
+ end
154
+ end
155
+ end
156
+ end
157
+ end
158
+ end
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+ require 'command_mapper/types/input_dir'
3
+
4
+ describe CommandMapper::Types::InputDir do
5
+ describe "#validate" do
6
+ context "when given a valid file path" do
7
+ let(:value) { __FILE__ }
8
+
9
+ it "must return [false, 'directory does not exist (...)']" do
10
+ expect(subject.validate(value)).to eq([false, "directory does not exist (#{value.inspect})"])
11
+ end
12
+ end
13
+
14
+ context "when given a valid directory path" do
15
+ let(:value) { __dir__ }
16
+
17
+ it "must return true" do
18
+ expect(subject.validate(value)).to eq(true)
19
+ end
20
+ end
21
+
22
+ context "when given a path that does not exist" do
23
+ let(:value) { "/path/does/not/exist" }
24
+
25
+ it "must return [false, 'path does not exist (...)']" do
26
+ expect(subject.validate(value)).to eq([false, "path does not exist (#{value.inspect})"])
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+ require 'command_mapper/types/input_file'
3
+
4
+ describe CommandMapper::Types::InputFile do
5
+ describe "#validate" do
6
+ context "when given a valid file path" do
7
+ let(:value) { __FILE__ }
8
+
9
+ it "must return true" do
10
+ expect(subject.validate(value)).to be(true)
11
+ end
12
+ end
13
+
14
+ context "when given a valid directory path" do
15
+ let(:value) { __dir__ }
16
+
17
+ it "must return [false, 'file does not exist (...)']" do
18
+ expect(subject.validate(value)).to eq(
19
+ [false, "file does not exist (#{value.inspect})"]
20
+ )
21
+ end
22
+ end
23
+
24
+ context "when given a path that does not exist" do
25
+ let(:value) { "/path/does/not/exist" }
26
+
27
+ it "must return [false, 'path does not exist (...)']" do
28
+ expect(subject.validate(value)).to eq(
29
+ [false, "path does not exist (#{value.inspect})"]
30
+ )
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,32 @@
1
+ require 'spec_helper'
2
+ require 'command_mapper/types/input_path'
3
+
4
+ describe CommandMapper::Types::InputPath do
5
+ describe "#validate" do
6
+ context "when given a valid file path" do
7
+ let(:value) { __FILE__ }
8
+
9
+ it "must return true" do
10
+ expect(subject.validate(value)).to be(true)
11
+ end
12
+ end
13
+
14
+ context "when given a valid directory path" do
15
+ let(:value) { __dir__ }
16
+
17
+ it "must return true" do
18
+ expect(subject.validate(value)).to be(true)
19
+ end
20
+ end
21
+
22
+ context "when given a path that does not exist" do
23
+ let(:value) { "/path/does/not/exist" }
24
+
25
+ it "must return [false, 'path does not exist (...)']" do
26
+ expect(subject.validate(value)).to eq(
27
+ [false, "path does not exist (#{value.inspect})"]
28
+ )
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,100 @@
1
+ require 'spec_helper'
2
+ require 'command_mapper/types/key_value_list'
3
+
4
+ describe CommandMapper::Types::KeyValueList do
5
+ describe "#initialize" do
6
+ it "must default #separator to ','" do
7
+ expect(subject.separator).to eq(',')
8
+ end
9
+
10
+ it "must initialize #type to a Types::KeyValue object" do
11
+ expect(subject.type).to be_kind_of(Types::KeyValue)
12
+ end
13
+
14
+ it "must default #type.separator to '='" do
15
+ expect(subject.type.separator).to eq('=')
16
+ end
17
+
18
+ context "when given the separator: keyword" do
19
+ let(:separator) { ';' }
20
+
21
+ subject { described_class.new(separator: separator) }
22
+
23
+ it "must set #separator" do
24
+ expect(subject.separator).to eq(separator)
25
+ end
26
+ end
27
+
28
+ context "when given the key_value_separator: keyword" do
29
+ let(:separator) { ':' }
30
+
31
+ subject { described_class.new(key_value_separator: separator) }
32
+
33
+ it "must set #type.separator" do
34
+ expect(subject.type.separator).to eq(separator)
35
+ end
36
+ end
37
+ end
38
+
39
+ describe "#format" do
40
+ context "when given an Array" do
41
+ context "containing a single key:value pair" do
42
+ let(:key) { "foo" }
43
+ let(:value) { 42 }
44
+
45
+ let(:array) { [[key, value]] }
46
+
47
+ it "must join the key and value with #type.separator" do
48
+ expect(subject.format(array)).to eq(
49
+ "#{key}#{subject.type.separator}#{value}"
50
+ )
51
+ end
52
+ end
53
+
54
+ context "when given multiple key:value pairs" do
55
+ let(:key1) { "foo" }
56
+ let(:value1) { 42 }
57
+ let(:key2) { "bar" }
58
+ let(:value2) { 100 }
59
+
60
+ let(:array) { [[key1, value1], [key2, value2]] }
61
+
62
+ it "must join the keys and values with #type.separator, and then with #separator" do
63
+ expect(subject.format(array)).to eq(
64
+ "#{key1}#{subject.type.separator}#{value1}#{subject.separator}#{key2}#{subject.type.separator}#{value2}"
65
+ )
66
+ end
67
+ end
68
+ end
69
+
70
+ context "when given an Hash" do
71
+ context "containing a single key:value pair" do
72
+ let(:key) { "foo" }
73
+ let(:value) { 42 }
74
+
75
+ let(:hash) { {key => value} }
76
+
77
+ it "must join the key and value with #type.separator" do
78
+ expect(subject.format(hash)).to eq(
79
+ "#{key}#{subject.type.separator}#{value}"
80
+ )
81
+ end
82
+ end
83
+
84
+ context "containing multiple key:value pairs" do
85
+ let(:key1) { "foo" }
86
+ let(:value1) { 42 }
87
+ let(:key2) { "bar" }
88
+ let(:value2) { 100 }
89
+
90
+ let(:hash) { {key1 => value1, key2 => value2} }
91
+
92
+ it "must join the keys and values with #type.separator, and then with #separator" do
93
+ expect(subject.format(hash)).to eq(
94
+ "#{key1}#{subject.type.separator}#{value1}#{subject.separator}#{key2}#{subject.type.separator}#{value2}"
95
+ )
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end