opt_parse_validator 0.0.2
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/.gitignore +3 -0
- data/.rspec +2 -0
- data/.rubocop.yml +4 -0
- data/.simplecov +4 -0
- data/.travis.yml +15 -0
- data/Gemfile +6 -0
- data/README.md +40 -0
- data/Rakefile +9 -0
- data/lib/opt_parse_validator/hacks.rb +15 -0
- data/lib/opt_parse_validator/options_file.rb +62 -0
- data/lib/opt_parse_validator/opts/base.rb +74 -0
- data/lib/opt_parse_validator/opts/boolean.rb +20 -0
- data/lib/opt_parse_validator/opts/choice.rb +33 -0
- data/lib/opt_parse_validator/opts/credentials.rb +14 -0
- data/lib/opt_parse_validator/opts/directory_path.rb +10 -0
- data/lib/opt_parse_validator/opts/file_path.rb +24 -0
- data/lib/opt_parse_validator/opts/integer.rb +12 -0
- data/lib/opt_parse_validator/opts/path.rb +61 -0
- data/lib/opt_parse_validator/opts/positive_integer.rb +13 -0
- data/lib/opt_parse_validator/opts/proxy.rb +5 -0
- data/lib/opt_parse_validator/opts/string.rb +6 -0
- data/lib/opt_parse_validator/opts/uri.rb +24 -0
- data/lib/opt_parse_validator/opts/url.rb +9 -0
- data/lib/opt_parse_validator/opts.rb +3 -0
- data/lib/opt_parse_validator/version.rb +4 -0
- data/lib/opt_parse_validator.rb +77 -0
- data/opt_parse_validator.gemspec +32 -0
- data/spec/fixtures/options_file/default.json +4 -0
- data/spec/fixtures/options_file/malformed.json +4 -0
- data/spec/fixtures/options_file/override.yml +1 -0
- data/spec/fixtures/options_file/unsupported.ext +1 -0
- data/spec/fixtures/r.txt +1 -0
- data/spec/fixtures/rwx.txt +1 -0
- data/spec/lib/opt_parse_validator/options_file_spec.rb +50 -0
- data/spec/lib/opt_parse_validator/opts/base_spec.rb +169 -0
- data/spec/lib/opt_parse_validator/opts/boolean_spec.rb +36 -0
- data/spec/lib/opt_parse_validator/opts/choice_spec.rb +78 -0
- data/spec/lib/opt_parse_validator/opts/credentials_spec.rb +23 -0
- data/spec/lib/opt_parse_validator/opts/direcyory_path_spec.rb +25 -0
- data/spec/lib/opt_parse_validator/opts/file_path_spec.rb +93 -0
- data/spec/lib/opt_parse_validator/opts/integer_spec.rb +19 -0
- data/spec/lib/opt_parse_validator/opts/path_spec.rb +7 -0
- data/spec/lib/opt_parse_validator/opts/positive_integer_spec.rb +19 -0
- data/spec/lib/opt_parse_validator/opts/proxy_spec.rb +12 -0
- data/spec/lib/opt_parse_validator/opts/uri_spec.rb +58 -0
- data/spec/lib/opt_parse_validator/opts/url_spec.rb +28 -0
- data/spec/lib/opt_parse_validator/version_spec.rb +7 -0
- data/spec/lib/opt_parse_validator_spec.rb +152 -0
- data/spec/spec_helper.rb +25 -0
- metadata +213 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe OptParseValidator::OptParser do
|
|
4
|
+
|
|
5
|
+
subject(:parser) { described_class.new }
|
|
6
|
+
let(:fixtures) { File.join(FIXTURES, 'options_file') }
|
|
7
|
+
let(:default_file) { File.join(fixtures, 'default.json') }
|
|
8
|
+
let(:override_file) { File.join(fixtures, 'override.yml') }
|
|
9
|
+
|
|
10
|
+
describe '#load_options_files' do
|
|
11
|
+
|
|
12
|
+
context 'when error' do
|
|
13
|
+
before { parser.options_files << config_file }
|
|
14
|
+
|
|
15
|
+
context 'when the format is not supported' do
|
|
16
|
+
let(:config_file) { File.join(fixtures, 'unsupported.ext') }
|
|
17
|
+
let(:exception) { "The format #{File.extname(config_file).delete('.')} is not supported" }
|
|
18
|
+
|
|
19
|
+
it 'raises an error' do
|
|
20
|
+
expect { parser.load_options_files }.to raise_error(exception)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
context 'when file content is malformed' do
|
|
25
|
+
let(:config_file) { File.join(fixtures, 'malformed.json') }
|
|
26
|
+
let(:exception) { "Parse Error, #{config_file} seems to be malformed" }
|
|
27
|
+
|
|
28
|
+
it 'raises an error' do
|
|
29
|
+
expect { parser.load_options_files }.to raise_error(exception)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
context 'otherwise' do
|
|
35
|
+
let(:verbose_opt) { OptParseValidator::OptBoolean.new(%w(-v --verbose)) }
|
|
36
|
+
let(:override_opt) { OptParseValidator::OptString.new(['--override-me VALUE'], normalize: :to_sym) }
|
|
37
|
+
|
|
38
|
+
let(:opts) { [verbose_opt, override_opt] }
|
|
39
|
+
|
|
40
|
+
let(:expected) { { verbose: true, override_me: :Yeaa } }
|
|
41
|
+
|
|
42
|
+
it 'sets everything correctly and get the right results' do
|
|
43
|
+
parser.options_files << default_file << override_file
|
|
44
|
+
parser.add(*opts)
|
|
45
|
+
|
|
46
|
+
expect(parser.results([])).to eq expected
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe OptParseValidator::OptBase do
|
|
4
|
+
subject(:opt) { described_class.new(option, attrs) }
|
|
5
|
+
let(:option) { %w(-v --verbose) }
|
|
6
|
+
let(:attrs) { {} }
|
|
7
|
+
|
|
8
|
+
describe '#to_long' do
|
|
9
|
+
after { expect(described_class.new(@option).to_long).to eq @expected }
|
|
10
|
+
|
|
11
|
+
context 'when not found' do
|
|
12
|
+
it 'returns nil' do
|
|
13
|
+
@option = %w(-v)
|
|
14
|
+
@expected = nil
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
context 'when found' do
|
|
19
|
+
it 'returns the long name' do
|
|
20
|
+
@option = ['-v', '--[no-]verbose VALUE [OPT]', 'Verbose Mode']
|
|
21
|
+
@expected = '--verbose'
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
describe '#to_sym' do
|
|
27
|
+
after :each do
|
|
28
|
+
if @exception
|
|
29
|
+
expect { described_class.new(@option).to_sym }.to raise_error(@exception)
|
|
30
|
+
else
|
|
31
|
+
expect(described_class.new(@option).to_sym).to eq(@expected)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
context 'without REQUIRED or OPTIONAL arguments' do
|
|
36
|
+
context 'with short option' do
|
|
37
|
+
it 'returns :test' do
|
|
38
|
+
@option = %w(-t --test Testing)
|
|
39
|
+
@expected = :test
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it 'returns :its_a_long_option' do
|
|
43
|
+
@option = ['-l', '--its-a-long-option', "Testing '-' replacement"]
|
|
44
|
+
@expected = :its_a_long_option
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
context 'without short option' do
|
|
49
|
+
it 'returns :long' do
|
|
50
|
+
@option = ['--long']
|
|
51
|
+
@expected = :long
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
it 'returns :long_option' do
|
|
55
|
+
@option = ['--long-option', 'No short !']
|
|
56
|
+
@expected = :long_option
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
context 'without long option' do
|
|
61
|
+
it 'raises an error' do
|
|
62
|
+
@option = ['-v', 'long option missing']
|
|
63
|
+
@exception = 'Could not find option symbol for ["-v", "long option missing"]'
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
it 'raises an error' do
|
|
67
|
+
@option = ['long option missing']
|
|
68
|
+
@exception = 'Could not find option symbol for ["long option missing"]'
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
context 'with multiple long option names (like alias)' do
|
|
73
|
+
it 'returns the first long option found' do
|
|
74
|
+
@option = %w(--check-long --cl)
|
|
75
|
+
@expected = :check_long
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
context 'when negative prefix name' do
|
|
81
|
+
it 'returns the positive option symbol' do
|
|
82
|
+
@option = %w(-v --[no-]verbose)
|
|
83
|
+
@expected = :verbose
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
context 'with REQUIRED or OPTIONAL arguments' do
|
|
88
|
+
it 'should removed the OPTIONAL argument' do
|
|
89
|
+
@option = ['-p', '--page [PAGE_NUMBER]']
|
|
90
|
+
@expected = :page
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
it 'should removed the REQUIRED argument' do
|
|
94
|
+
@option = ['--url TARGET_URL']
|
|
95
|
+
@expected = :url
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
describe '#new, #required?' do
|
|
101
|
+
context 'when no :required' do
|
|
102
|
+
its(:option) { should eq(option) }
|
|
103
|
+
its(:required?) { should be_falsey }
|
|
104
|
+
its(:to_sym) { should eq(:verbose) }
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
context 'when :required' do
|
|
108
|
+
let(:attrs) { { required: true } }
|
|
109
|
+
|
|
110
|
+
its(:required?) { should be true }
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
describe '#normalize' do
|
|
115
|
+
after { expect(opt.normalize(@value)).to eq @expected }
|
|
116
|
+
|
|
117
|
+
context 'when no :normalize attribute' do
|
|
118
|
+
it 'returns the value' do
|
|
119
|
+
@value = 'test'
|
|
120
|
+
@expected = @value
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
context 'when a single normalization' do
|
|
125
|
+
let(:attrs) { { normalize: :to_sym } }
|
|
126
|
+
|
|
127
|
+
context 'when the value does not have a to_sym method' do
|
|
128
|
+
it 'returns the value' do
|
|
129
|
+
@value = 1.0
|
|
130
|
+
@expected = @value
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
context 'when a to_sym method' do
|
|
135
|
+
it 'returns the symbol' do
|
|
136
|
+
@value = 'test'
|
|
137
|
+
@expected = :test
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
context 'when multiple normalization' do
|
|
143
|
+
let(:attrs) { { normalize: [:to_sym, 2.0, :upcase] } }
|
|
144
|
+
|
|
145
|
+
it 'apply each of them (if possible)' do
|
|
146
|
+
@value = 'test'
|
|
147
|
+
@expected = :TEST
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
describe '#validate' do
|
|
153
|
+
context 'when an empty or nil value' do
|
|
154
|
+
it 'raises an error' do
|
|
155
|
+
[nil, ''].each do |value|
|
|
156
|
+
expect { opt.validate(value) }
|
|
157
|
+
.to raise_error('Empty option value supplied')
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
context 'when a valid value' do
|
|
163
|
+
it 'returns it' do
|
|
164
|
+
expect(opt.validate('testing')).to eq 'testing'
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe OptParseValidator::OptBoolean do
|
|
4
|
+
|
|
5
|
+
subject(:opt) { described_class.new(['-b', '--bool BOOL']) }
|
|
6
|
+
|
|
7
|
+
describe '#validate' do
|
|
8
|
+
context 'when does not match TRUE_PATTERN and FALSE_PATTERN' do
|
|
9
|
+
it 'raises an error' do
|
|
10
|
+
expect { opt.validate("true\nfalse") }
|
|
11
|
+
.to raise_error('Invalid boolean value, expected true|t|yes|y|1|false|f|no|n|0')
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
context 'when matches TRUE_PATTERN' do
|
|
16
|
+
after { expect(opt.validate(@argument)).to be true }
|
|
17
|
+
|
|
18
|
+
%w(true t yes y 1).each do |arg|
|
|
19
|
+
it 'returns true' do
|
|
20
|
+
@argument = arg
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
context 'when matches FALSE_PATTERN' do
|
|
26
|
+
after { expect(opt.validate(@argument)).to be false }
|
|
27
|
+
|
|
28
|
+
%w(false f no n 0).each do |arg|
|
|
29
|
+
it 'returns false' do
|
|
30
|
+
@argument = arg
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
end
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe OptParseValidator::OptChoice do
|
|
4
|
+
subject(:opt) { described_class.new(option, attrs) }
|
|
5
|
+
let(:option) { %w(-f --format FORMAT) }
|
|
6
|
+
let(:attrs) { { choices: %w(json cli) } }
|
|
7
|
+
|
|
8
|
+
describe '#new' do
|
|
9
|
+
context 'when errors' do
|
|
10
|
+
after { expect { opt }.to raise_error(@exception) }
|
|
11
|
+
|
|
12
|
+
context 'when :choices not provided' do
|
|
13
|
+
let(:attrs) { {} }
|
|
14
|
+
|
|
15
|
+
it 'raises an error' do
|
|
16
|
+
@exception = 'The :choices attribute is mandatory'
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
context 'when :choices is not an array' do
|
|
21
|
+
let(:attrs) { { choices: 'wrong type' } }
|
|
22
|
+
|
|
23
|
+
it 'raises an error' do
|
|
24
|
+
@exception = 'The :choices attribute must be an array'
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
context 'when valid' do
|
|
30
|
+
it 'sets the option correctly' do
|
|
31
|
+
expect { opt }.to_not raise_error
|
|
32
|
+
expect(opt.attrs[:choices]).to eq attrs[:choices]
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
describe '#validate' do
|
|
38
|
+
after :each do
|
|
39
|
+
if @exception
|
|
40
|
+
expect { opt.validate(@value) }.to raise_error(@exception)
|
|
41
|
+
else
|
|
42
|
+
expect(opt.validate(@value)).to eq(@expected)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
context 'when the value is not in the choices' do
|
|
47
|
+
it 'raises an error' do
|
|
48
|
+
@value = 'invalid-format'
|
|
49
|
+
@exception = "'invalid-format' is not a valid choice, expected one of the followings: json,cli"
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
context 'when :case_sensitive' do
|
|
53
|
+
let(:attrs) { { choices: %w(json cli), case_sensitive: true } }
|
|
54
|
+
|
|
55
|
+
it 'raises an error' do
|
|
56
|
+
@value = 'JSON'
|
|
57
|
+
@exception = "'JSON' is not a valid choice, expected one of the followings: json,cli"
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
context 'when valid choice' do
|
|
63
|
+
it 'returns the choice' do
|
|
64
|
+
@value = 'JSON'
|
|
65
|
+
@expected = 'json'
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
context 'when :case_sensitive' do
|
|
69
|
+
let(:attrs) { { choices: %w(JSON cli), case_sensitive: true } }
|
|
70
|
+
|
|
71
|
+
it 'raises an error' do
|
|
72
|
+
@value = 'JSON'
|
|
73
|
+
@expected = 'JSON'
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe OptParseValidator::OptCredentials do
|
|
4
|
+
|
|
5
|
+
subject(:opt) { described_class.new(['-l', '--login USERNAME:PASSWORD']) }
|
|
6
|
+
|
|
7
|
+
describe '#validate' do
|
|
8
|
+
context 'when incorrect format' do
|
|
9
|
+
it 'raises an error' do
|
|
10
|
+
expect { opt.validate('wrong') }
|
|
11
|
+
.to raise_error 'Incorrect credentials format, username:password expected'
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
context 'when valid format' do
|
|
16
|
+
it 'returns a hash with :username and :password' do
|
|
17
|
+
expect(opt.validate('admin:P@ssw:rd'))
|
|
18
|
+
.to eq(username: 'admin', password: 'P@ssw:rd')
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe OptParseValidator::OptDirectoryPath do
|
|
4
|
+
|
|
5
|
+
subject(:opt) { described_class.new(['-d', '--dir DIR'], attrs) }
|
|
6
|
+
let(:attrs) { {} }
|
|
7
|
+
let(:dir) { File.join(FIXTURES, 'options_file') }
|
|
8
|
+
|
|
9
|
+
its(:attrs) { should eq directory: true }
|
|
10
|
+
|
|
11
|
+
describe '#validate' do
|
|
12
|
+
context 'when it is a directory' do
|
|
13
|
+
it 'returns the path' do
|
|
14
|
+
expect(opt.validate(dir)).to eq dir
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
context 'when it\s not ' do
|
|
19
|
+
it 'raises an error' do
|
|
20
|
+
expect { opt.validate('yolo.txt') }.to raise_error "'yolo.txt' is not a directory"
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
end
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe OptParseValidator::OptFilePath do
|
|
4
|
+
|
|
5
|
+
subject(:opt) { described_class.new(['-f', '--file FILE_PATH'], attrs) }
|
|
6
|
+
let(:attrs) { {} }
|
|
7
|
+
let(:rwx_file) { File.join(FIXTURES, 'rwx.txt') }
|
|
8
|
+
let(:r_file) { File.join(FIXTURES, 'r.txt') }
|
|
9
|
+
|
|
10
|
+
its(:attrs) { should eq file: true }
|
|
11
|
+
|
|
12
|
+
describe '#validate' do
|
|
13
|
+
context 'when :extensions' do
|
|
14
|
+
let(:attrs) { { extensions: 'txt' } }
|
|
15
|
+
|
|
16
|
+
its('allowed_attrs.first') { should eq :extensions }
|
|
17
|
+
|
|
18
|
+
context 'when it matches' do
|
|
19
|
+
it 'returns the path' do
|
|
20
|
+
expect(opt.validate(rwx_file)).to eq rwx_file
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
context 'when it does no match' do
|
|
25
|
+
it 'raises an error' do
|
|
26
|
+
expect { opt.validate('yolo.aa') }
|
|
27
|
+
.to raise_error "The extension of 'yolo.aa' is not allowed"
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
context 'when :executable' do
|
|
33
|
+
let(:attrs) { { executable: true } }
|
|
34
|
+
|
|
35
|
+
it 'returns the path if the file is +x' do
|
|
36
|
+
expect(opt.validate(rwx_file)).to eq rwx_file
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it 'raises an error if not ' do
|
|
40
|
+
expect { opt.validate(r_file) }.to raise_error "'#{r_file}' is not executable"
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
context 'when :readable' do
|
|
45
|
+
let(:attrs) { { readable: true, exists: false } }
|
|
46
|
+
|
|
47
|
+
it 'returns the path if the file is +r' do
|
|
48
|
+
expect(opt.validate(rwx_file)).to eq rwx_file
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it 'raises an error otherwise' do
|
|
52
|
+
file = File.join(FIXTURES, 'yolo.txt')
|
|
53
|
+
|
|
54
|
+
expect { opt.validate(file) }.to raise_error "'#{file}' is not readable"
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
context 'when :writable' do
|
|
59
|
+
context 'when the path exists' do
|
|
60
|
+
let(:attrs) { { writable: true } }
|
|
61
|
+
|
|
62
|
+
it 'returns the path if the path is +x' do
|
|
63
|
+
expect(opt.validate(rwx_file)).to eq rwx_file
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
it 'raises an error otherwise' do
|
|
67
|
+
expect { opt.validate(r_file) }.to raise_error "'#{r_file}' is not writable"
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
context 'when it does not exist' do
|
|
72
|
+
let(:attrs) { { writable: true, exists: false } }
|
|
73
|
+
|
|
74
|
+
context 'when the parent directory is +w' do
|
|
75
|
+
let(:file) { File.join(FIXTURES, 'options_file', 'not_there.txt') }
|
|
76
|
+
|
|
77
|
+
it 'returns the path' do
|
|
78
|
+
expect(opt.validate(file)).to eq file
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
context 'when the parent directory is not +w' do
|
|
83
|
+
let(:file) { File.join(FIXTURES, 'hfjhg', 'yolo.rb') }
|
|
84
|
+
|
|
85
|
+
it 'raises an error' do
|
|
86
|
+
expect { opt.validate(file) }.to raise_error "'#{file}' is not writable"
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe OptParseValidator::OptInteger do
|
|
4
|
+
|
|
5
|
+
subject(:opt) { described_class.new(['-i', '--int INT']) }
|
|
6
|
+
|
|
7
|
+
describe '#validate' do
|
|
8
|
+
context 'when not an integer' do
|
|
9
|
+
it 'raises an error' do
|
|
10
|
+
expect { opt.validate('a') }.to raise_error('a is not an integer')
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it 'returns the integer' do
|
|
15
|
+
expect(opt.validate('12')).to eq 12
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe OptParseValidator::OptPositiveInteger do
|
|
4
|
+
|
|
5
|
+
subject(:opt) { described_class.new(['-i', '--int INT']) }
|
|
6
|
+
|
|
7
|
+
describe '#validate' do
|
|
8
|
+
context 'when not > 0' do
|
|
9
|
+
it 'raises an error' do
|
|
10
|
+
expect { opt.validate('-3') }.to raise_error('-3 is not > 0')
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it 'returns the integer' do
|
|
15
|
+
expect(opt.validate('20')).to eq 20
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe OptParseValidator::OptProxy do
|
|
4
|
+
|
|
5
|
+
subject(:opt) { described_class.new(['--proxy PROXY'], attrs) }
|
|
6
|
+
let(:attrs) { { protocols: %w(http https socks socks5 socks4) } }
|
|
7
|
+
|
|
8
|
+
describe '#validate' do
|
|
9
|
+
# Handled by OptURI
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe OptParseValidator::OptURI do
|
|
4
|
+
|
|
5
|
+
subject(:opt) { described_class.new(['-u', '--uri URI'], attrs) }
|
|
6
|
+
let(:attrs) { {} }
|
|
7
|
+
|
|
8
|
+
describe '#new, #allowed_protocols' do
|
|
9
|
+
context 'when no attrs supplied' do
|
|
10
|
+
its(:allowed_protocols) { should be_empty }
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
context 'when only one protocol supplied' do
|
|
14
|
+
let(:attrs) { { protocols: 'http' } }
|
|
15
|
+
|
|
16
|
+
it 'sets it' do
|
|
17
|
+
opt.allowed_protocols << 'ftp'
|
|
18
|
+
expect(opt.allowed_protocols).to eq %w(http ftp)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
context 'when multiple protocols are given' do
|
|
23
|
+
let(:attrs) { { protocols: %w(ftp https) } }
|
|
24
|
+
|
|
25
|
+
it 'sets them' do
|
|
26
|
+
expect(opt.allowed_protocols).to eq attrs[:protocols]
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
describe '#validate' do
|
|
32
|
+
context 'when the allowed_protocols is empty' do
|
|
33
|
+
it 'accepts all protocols' do
|
|
34
|
+
%w(http ftp file).each do |p|
|
|
35
|
+
expected = "#{p}://testing"
|
|
36
|
+
|
|
37
|
+
expect(opt.validate(expected)).to eq expected
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
context 'when allowed_protocols is set' do
|
|
43
|
+
let(:attrs) { { protocols: %w(https) } }
|
|
44
|
+
|
|
45
|
+
it 'raises an error if the protocol is not allowed' do
|
|
46
|
+
expect { opt.validate('ftp://ishouldnotbethere') }
|
|
47
|
+
.to raise_error(Addressable::URI::InvalidURIError)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
it 'returns the uri string if valid' do
|
|
51
|
+
expected = 'https://example.com/'
|
|
52
|
+
|
|
53
|
+
expect(opt.validate(expected)).to eq expected
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe OptParseValidator::OptURL do
|
|
4
|
+
|
|
5
|
+
subject(:opt) { described_class.new(['-u', '--url URL']) }
|
|
6
|
+
|
|
7
|
+
describe '#validate' do
|
|
8
|
+
context 'when the url is empty' do
|
|
9
|
+
it 'raises an error' do
|
|
10
|
+
expect { opt.validate('') }.to raise_error(Addressable::URI::InvalidURIError)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
context 'when the protocol is not allowed' do
|
|
15
|
+
it 'raises an error' do
|
|
16
|
+
expect { opt.validate('ftp://ftp.domain.com') }
|
|
17
|
+
.to raise_error(Addressable::URI::InvalidURIError)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it 'returns the url' do
|
|
22
|
+
url = 'https://duckduckgo.com/'
|
|
23
|
+
|
|
24
|
+
expect(opt.validate(url)).to eq url
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
end
|