command_mapper 0.1.0.pre1
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.
- checksums.yaml +7 -0
- data/.github/workflows/ruby.yml +27 -0
- data/.gitignore +10 -0
- data/.rspec +1 -0
- data/.yardopts +1 -0
- data/ChangeLog.md +25 -0
- data/Gemfile +15 -0
- data/LICENSE.txt +20 -0
- data/README.md +369 -0
- data/Rakefile +12 -0
- data/commnad_mapper.gemspec +61 -0
- data/gemspec.yml +23 -0
- data/lib/command_mapper/arg.rb +75 -0
- data/lib/command_mapper/argument.rb +142 -0
- data/lib/command_mapper/command.rb +606 -0
- data/lib/command_mapper/exceptions.rb +19 -0
- data/lib/command_mapper/option.rb +282 -0
- data/lib/command_mapper/option_value.rb +21 -0
- data/lib/command_mapper/sudo.rb +73 -0
- data/lib/command_mapper/types/enum.rb +35 -0
- data/lib/command_mapper/types/hex.rb +82 -0
- data/lib/command_mapper/types/input_dir.rb +35 -0
- data/lib/command_mapper/types/input_file.rb +35 -0
- data/lib/command_mapper/types/input_path.rb +29 -0
- data/lib/command_mapper/types/key_value.rb +131 -0
- data/lib/command_mapper/types/key_value_list.rb +45 -0
- data/lib/command_mapper/types/list.rb +90 -0
- data/lib/command_mapper/types/map.rb +64 -0
- data/lib/command_mapper/types/num.rb +50 -0
- data/lib/command_mapper/types/str.rb +85 -0
- data/lib/command_mapper/types/type.rb +102 -0
- data/lib/command_mapper/types.rb +6 -0
- data/lib/command_mapper/version.rb +4 -0
- data/lib/command_mapper.rb +2 -0
- data/spec/arg_spec.rb +137 -0
- data/spec/argument_spec.rb +513 -0
- data/spec/commnad_spec.rb +1175 -0
- data/spec/exceptions_spec.rb +14 -0
- data/spec/option_spec.rb +882 -0
- data/spec/option_value_spec.rb +17 -0
- data/spec/spec_helper.rb +6 -0
- data/spec/sudo_spec.rb +24 -0
- data/spec/types/enum_spec.rb +31 -0
- data/spec/types/hex_spec.rb +158 -0
- data/spec/types/input_dir_spec.rb +30 -0
- data/spec/types/input_file_spec.rb +34 -0
- data/spec/types/input_path_spec.rb +32 -0
- data/spec/types/key_value_list_spec.rb +100 -0
- data/spec/types/key_value_spec.rb +272 -0
- data/spec/types/list_spec.rb +143 -0
- data/spec/types/map_spec.rb +62 -0
- data/spec/types/num_spec.rb +90 -0
- data/spec/types/str_spec.rb +232 -0
- data/spec/types/type_spec.rb +59 -0
- 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
|
data/spec/spec_helper.rb
ADDED
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
|