optout 0.0.1 → 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.
- data/README.rdoc +31 -8
- data/lib/optout.rb +238 -62
- data/spec/optout_spec.rb +369 -217
- metadata +9 -9
data/spec/optout_spec.rb
CHANGED
@@ -1,155 +1,225 @@
|
|
1
|
-
require "
|
2
|
-
require "tempfile"
|
3
|
-
require "fileutils"
|
4
|
-
require "rbconfig"
|
5
|
-
|
6
|
-
def create_optout(options = {})
|
7
|
-
Optout.options(options) do
|
8
|
-
on :x, "-x"
|
9
|
-
on :y, "-y"
|
10
|
-
end
|
11
|
-
end
|
1
|
+
require "spec_helper"
|
12
2
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
class Optout
|
18
|
-
class Option
|
19
|
-
def unix?
|
20
|
-
true
|
3
|
+
shared_examples_for "a validator" do
|
4
|
+
context "when the option is nil" do
|
5
|
+
it "should not be validated" do
|
6
|
+
lambda { subject.argv(:x => nil) }.should_not raise_exception
|
21
7
|
end
|
22
8
|
end
|
23
9
|
end
|
24
10
|
|
25
11
|
shared_examples_for "something that validates files" do
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
it "should not raise an exception if a file does not exist but its directory does" do
|
34
|
-
file = File.join(@tmpdir, "__bad__")
|
35
|
-
optout = optout_option(@validator)
|
36
|
-
proc { optout.argv(:x => file) }.should_not raise_exception
|
12
|
+
context "when the file does not exist but its directory does" do
|
13
|
+
it "should not raise an exception" do
|
14
|
+
no_file = File.join(File.dirname(file), "does_not_exist")
|
15
|
+
optout = optout_option(described_class)
|
16
|
+
lambda { optout.argv(:x => no_file) }.should_not raise_exception
|
17
|
+
end
|
37
18
|
end
|
38
19
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
it "should raise an exception
|
43
|
-
FileUtils.chmod(0100,
|
44
|
-
optout = optout_option(
|
45
|
-
|
46
|
-
end
|
47
|
-
|
48
|
-
it "should not raise an exception when user permissions match" do
|
49
|
-
checker = proc do |validator|
|
50
|
-
proc { optout_option(validator).argv(options) }.should_not raise_exception
|
51
|
-
end
|
52
|
-
|
53
|
-
FileUtils.chmod(0100, @file)
|
54
|
-
checker.call(@validator.permissions("x"))
|
55
|
-
|
56
|
-
FileUtils.chmod(0200, @file)
|
57
|
-
checker.call(@validator.permissions("w"))
|
58
|
-
|
59
|
-
FileUtils.chmod(0400, @file)
|
60
|
-
checker.call(@validator.permissions("r"))
|
61
|
-
|
62
|
-
FileUtils.chmod(0700, @file)
|
63
|
-
checker.call(@validator.permissions("rwx"))
|
20
|
+
# Only some chmod() modes work on Win
|
21
|
+
describe "#permissions", :skip_on_windows => true do
|
22
|
+
context "when the specified user permissions aren't set" do
|
23
|
+
it "should raise an OptionInvalid exception" do
|
24
|
+
FileUtils.chmod(0100, file)
|
25
|
+
optout = optout_option(described_class.permissions("r"))
|
26
|
+
lambda { optout.argv(options) }.should raise_exception(Optout::OptionInvalid, /user permission/)
|
64
27
|
end
|
65
28
|
end
|
66
|
-
end
|
67
29
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
proc { optout.argv(options) }.should_not raise_exception
|
73
|
-
end
|
74
|
-
end
|
30
|
+
def chmod_and_check(mode, validator)
|
31
|
+
FileUtils.chmod(mode, file)
|
32
|
+
lambda { optout_option(validator).argv(options) }.should_not raise_exception
|
33
|
+
end
|
75
34
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
optout = optout_option(@validator.under(@tmpdir))
|
82
|
-
proc { optout.argv(options) }.should_not raise_exception
|
35
|
+
context "when user read is set" do
|
36
|
+
it "should not raise an exception" do
|
37
|
+
chmod_and_check(0400, described_class.permissions("r"))
|
38
|
+
end
|
83
39
|
end
|
84
|
-
|
85
|
-
it "should raise an exception if the parent directory does not match the given pattern" do
|
86
|
-
# We need to respect the @file's type to ensure other validation rules implicitly applied by the @validator pass.
|
87
|
-
# First create parent dirs to validate against
|
88
|
-
tmp = File.join(@tmpdir, "a1", "b1")
|
89
|
-
FileUtils.mkdir_p(tmp)
|
90
40
|
|
91
|
-
|
92
|
-
|
41
|
+
context "when user write is set" do
|
42
|
+
it "should not raise an exception" do
|
43
|
+
chmod_and_check(0200, described_class.permissions("w"))
|
44
|
+
end
|
45
|
+
end
|
93
46
|
|
94
|
-
|
95
|
-
|
96
|
-
|
47
|
+
context "when user execute is set" do
|
48
|
+
it "should not raise an exception" do
|
49
|
+
chmod_and_check(0100, described_class.permissions("x"))
|
50
|
+
end
|
51
|
+
end
|
97
52
|
|
98
|
-
|
99
|
-
|
53
|
+
context "when all permissions are set" do
|
54
|
+
it "should not raise an exception" do
|
55
|
+
chmod_and_check(0700, described_class.permissions("rwx"))
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
100
59
|
|
101
|
-
|
102
|
-
|
103
|
-
|
60
|
+
describe "#exists" do
|
61
|
+
subject { optout_option(described_class.exists) }
|
62
|
+
|
63
|
+
context "when the file exists" do
|
64
|
+
it "does not raise an exception" do
|
65
|
+
lambda { subject.argv(options) }.should_not raise_exception
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
context "when the file does not exist" do
|
70
|
+
it "raises an OptionInvalid exception" do
|
71
|
+
lambda { subject.argv(:x => file + "no_file") }.should raise_exception(Optout::OptionInvalid, /does not exist/)
|
104
72
|
end
|
105
73
|
end
|
106
74
|
end
|
107
75
|
|
108
|
-
describe "
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
76
|
+
describe "#under" do
|
77
|
+
context "when not under the given directory" do
|
78
|
+
it "should raise an OptionInvalid exception" do
|
79
|
+
optout = optout_option(described_class.under(File.join("wrong", "path")))
|
80
|
+
lambda { optout.argv(options) }.should raise_exception(Optout::OptionInvalid, /must be under/)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
context "when under the given directory" do
|
85
|
+
it "should not raise an exception" do
|
86
|
+
optout = optout_option(described_class.under(File.dirname(file)))
|
87
|
+
lambda { optout.argv(options) }.should_not raise_exception
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
context "when the parent directory does not match the given regex" do
|
92
|
+
it "should raise an OptionInvalid exception" do
|
93
|
+
optout = optout_option(described_class.under(/_{20},#{Time.now.to_i}$/))
|
94
|
+
lambda { optout.argv(options) }.should raise_exception(Optout::OptionInvalid, /must be under/)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
context "when the parent directory matches the given regex" do
|
99
|
+
it "should not raise an exception" do
|
100
|
+
ends_with = File.dirname(file)[-1,1]
|
101
|
+
optout = optout_option(described_class.under(/#{Regexp.quote(ends_with)}$/))
|
102
|
+
lambda { optout.argv(options) }.should_not raise_exception
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
describe "#named" do
|
108
|
+
context "when the basename matches the regex" do
|
109
|
+
it "should not raise an exception" do
|
110
|
+
ends_with = File.basename(subject)[-1,1]
|
111
|
+
optout = optout_option(described_class.named(/#{Regexp.quote(ends_with)}$/))
|
112
|
+
lambda { optout.argv(options) }.should_not raise_exception
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
context "when the basename does not match the regex" do
|
117
|
+
it "should raise an OptionInvalid exception" do
|
118
|
+
optout = optout_option(described_class.named(/\A#{Time.now.to_i}/))
|
119
|
+
lambda { optout.argv(options) }.should raise_exception(Optout::OptionInvalid, /name must match/)
|
120
|
+
end
|
115
121
|
end
|
116
122
|
|
117
|
-
|
118
|
-
|
119
|
-
|
123
|
+
context "when the basename is not equal" do
|
124
|
+
it "should raise an OptionInvalid exception" do
|
125
|
+
optout = optout_option(described_class.named(Time.now.to_s))
|
126
|
+
lambda { optout.argv(options) }.should raise_exception(Optout::OptionInvalid, /name must match/)
|
127
|
+
end
|
128
|
+
end
|
120
129
|
|
121
|
-
|
122
|
-
|
123
|
-
|
130
|
+
context "when the basename is equal" do
|
131
|
+
it "should not raise an exception" do
|
132
|
+
optout = optout_option(described_class.named(File.basename(file)))
|
133
|
+
lambda { optout.argv(options) }.should_not raise_exception
|
134
|
+
end
|
124
135
|
end
|
125
136
|
end
|
126
137
|
end
|
127
138
|
|
128
139
|
describe Optout do
|
129
|
-
describe "
|
140
|
+
describe "#on" do
|
130
141
|
before(:each) { @optout = Optout.new }
|
131
142
|
|
132
|
-
it "
|
133
|
-
|
134
|
-
proc { Optout.options { on } }.should raise_exception(ArgumentError, /option key required/)
|
143
|
+
it "requires the option's key" do
|
144
|
+
lambda { @optout.on }.should raise_exception(ArgumentError, /option key required/)
|
135
145
|
end
|
136
|
-
|
146
|
+
|
137
147
|
it "should not allow an option to be defined twice" do
|
138
148
|
@optout.on :x
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
149
|
+
[:x, "x"].each do |opt|
|
150
|
+
lambda { @optout.on opt }.should raise_exception(ArgumentError, /already defined/)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
describe "the :required option" do
|
155
|
+
context "when true" do
|
156
|
+
subject { optout_option(:required => true) }
|
157
|
+
|
158
|
+
it "should raise an OptionRequired exception if the option is missing" do
|
159
|
+
lambda { subject.argv }.should raise_exception(Optout::OptionRequired, /'x'/)
|
160
|
+
lambda { subject.argv(:x => nil) }.should raise_exception(Optout::OptionRequired, /'x'/)
|
161
|
+
end
|
162
|
+
|
163
|
+
it "should not raise an exception if the option is not missing" do
|
164
|
+
lambda { subject.argv(:x => "x") }.should_not raise_exception
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
context "when false" do
|
169
|
+
it "should not raise an exception if the option is missing" do
|
170
|
+
optout = optout_option(:required => false)
|
171
|
+
lambda { optout.argv }.should_not raise_exception
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
describe "the :multiple option" do
|
177
|
+
let(:collection) do
|
178
|
+
[ :x => %w|a b|,
|
179
|
+
:x => { :a => "a", :b => "b" } ]
|
180
|
+
end
|
181
|
+
|
182
|
+
context "when false" do
|
183
|
+
subject { optout_option(:multiple => false) }
|
184
|
+
|
185
|
+
it "should raise an OptionInvalid exception if an option contains multiple values" do
|
186
|
+
collection.each do |options|
|
187
|
+
lambda { subject.argv(options) }.should raise_exception(Optout::OptionInvalid, /multiple values/)
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
it "should not raise an exception if an option contains a collection with only 1 element" do
|
192
|
+
[ :x => %w|a|,
|
193
|
+
:x => { :a => "a" } ].each do |options|
|
194
|
+
lambda { subject.argv(options) }.should_not raise_exception
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
it "should not raise an exception if an option contains a single value" do
|
199
|
+
lambda { subject.argv(:x => "x") }.should_not raise_exception
|
144
200
|
end
|
145
|
-
end
|
201
|
+
end
|
202
|
+
|
203
|
+
context "when true" do
|
204
|
+
subject { optout_option(:multiple => true) }
|
205
|
+
|
206
|
+
it "should not raise an OptionInvalid exception if an option contains multiple values" do
|
207
|
+
collection.each do |options|
|
208
|
+
lambda { subject.argv(options) }.should_not raise_exception
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
it "should not raise an OptionInvalid exception if an option contains a single value" do
|
213
|
+
lambda { subject.argv(:x => "x") }.should_not raise_exception
|
214
|
+
end
|
215
|
+
end
|
146
216
|
end
|
147
217
|
end
|
148
218
|
|
149
219
|
describe "creating options" do
|
150
220
|
before(:each) { @optout = create_optout }
|
151
221
|
|
152
|
-
context "as a string" do
|
222
|
+
context "as a string" do
|
153
223
|
it "should only output the option's value if there's no switch" do
|
154
224
|
optout = Optout.options { on :x }
|
155
225
|
optout.shell(:x => "x").should eql("'x'")
|
@@ -159,45 +229,53 @@ describe Optout do
|
|
159
229
|
@optout.shell({}).should be_empty
|
160
230
|
end
|
161
231
|
|
162
|
-
it "should
|
232
|
+
it "should raise an ArgumentError if the options are not a Hash" do
|
233
|
+
lambda { @optout.shell("optionz") }.should raise_exception(ArgumentError)
|
234
|
+
end
|
235
|
+
|
236
|
+
it "should only output the option's switch if its value if true" do
|
163
237
|
@optout.shell(:x => true, :y => true).should eql("-x -y")
|
164
238
|
end
|
165
239
|
|
166
|
-
it "should not output the option if its value is false" do
|
240
|
+
it "should not output the option if its value is false" do
|
167
241
|
@optout.shell(:x => false, :y => true).should eql("-y")
|
168
242
|
end
|
169
243
|
|
170
|
-
it "should only output the options that have a value" do
|
244
|
+
it "should only output the options that have a value" do
|
171
245
|
@optout.shell(:x => "x", :y => nil).should eql("-x 'x'")
|
172
246
|
end
|
173
|
-
|
174
|
-
it "should output all of the options" do
|
247
|
+
|
248
|
+
it "should output all of the options" do
|
175
249
|
@optout.shell(:x => "x", :y => "y").should eql("-x 'x' -y 'y'")
|
176
250
|
end
|
177
251
|
|
178
|
-
it "should escape the single quote char" do
|
252
|
+
it "should escape the single quote char" do
|
179
253
|
@optout.shell(:x => "' a'b'c '").should eql(%q|-x ''\'' a'\''b'\''c '\'''|)
|
180
254
|
end
|
181
255
|
|
182
|
-
it "should not separate switches from their value" do
|
256
|
+
it "should not separate switches from their value" do
|
183
257
|
optout = create_optout(:arg_separator => "")
|
184
258
|
optout.shell(:x => "x", :y => "y").should eql("-x'x' -y'y'")
|
185
259
|
end
|
186
|
-
|
260
|
+
|
187
261
|
it "should seperate all switches from their value with a '='" do
|
188
262
|
optout = create_optout(:arg_separator => "=")
|
189
263
|
optout.shell(:x => "x", :y => "y").should eql("-x='x' -y='y'")
|
190
|
-
end
|
264
|
+
end
|
191
265
|
|
192
|
-
it "should join all options with multiple values on a delimiter" do
|
266
|
+
it "should join all options with multiple values on a delimiter" do
|
193
267
|
optout = create_optout(:multiple => true)
|
194
268
|
optout.shell(:x => %w|a b c|, :y => "y").should eql("-x 'a,b,c' -y 'y'")
|
195
269
|
end
|
196
270
|
|
197
|
-
it "should join all options with multiple values on a ':'" do
|
271
|
+
it "should join all options with multiple values on a ':'" do
|
198
272
|
optout = create_optout(:multiple => ":")
|
199
273
|
optout.shell(:x => %w|a b c|, :y => "y").should eql("-x 'a:b:c' -y 'y'")
|
200
|
-
end
|
274
|
+
end
|
275
|
+
|
276
|
+
it "should not differentiate between a String key and a Symbol key" do
|
277
|
+
@optout.shell("x" => "x").should eql(@optout.shell(:x => "x"))
|
278
|
+
end
|
201
279
|
end
|
202
280
|
|
203
281
|
context "as an array" do
|
@@ -206,6 +284,10 @@ describe Optout do
|
|
206
284
|
optout.argv(:x => "x").should eql(["x"])
|
207
285
|
end
|
208
286
|
|
287
|
+
it "should raise an ArgumentError if the options are not a Hash" do
|
288
|
+
lambda { @optout.argv("optionz") }.should raise_exception(ArgumentError)
|
289
|
+
end
|
290
|
+
|
209
291
|
it "should output an empty array if the option hash is empty" do
|
210
292
|
@optout.argv({}).should be_empty
|
211
293
|
end
|
@@ -218,7 +300,7 @@ describe Optout do
|
|
218
300
|
@optout.argv(:x => false, :y => true).should eql(["-y"])
|
219
301
|
end
|
220
302
|
|
221
|
-
it "should only output the options that have a value" do
|
303
|
+
it "should only output the options that have a value" do
|
222
304
|
@optout.argv(:x => "x", :y => nil).should eql(["-x", "x"])
|
223
305
|
end
|
224
306
|
|
@@ -226,155 +308,225 @@ describe Optout do
|
|
226
308
|
@optout.argv(:x => "x", :y => "y").should eql(["-x", "x", "-y", "y"])
|
227
309
|
end
|
228
310
|
|
229
|
-
it "should not escape the single quote char" do
|
311
|
+
it "should not escape the single quote char" do
|
230
312
|
@optout.argv(:x => "' a'b'c '").should eql(["-x", "' a'b'c '"])
|
231
313
|
end
|
232
314
|
|
233
|
-
it "should not separate switches from their value" do
|
315
|
+
it "should not separate switches from their value" do
|
234
316
|
optout = create_optout(:arg_separator => "")
|
235
317
|
optout.argv(:x => "x", :y => "y").should eql(["-xx", "-yy"])
|
236
318
|
end
|
237
319
|
|
238
320
|
it "should seperate all of switches from their value with a '='" do
|
239
|
-
optout = create_optout(:arg_separator => "=")
|
321
|
+
optout = create_optout(:arg_separator => "=")
|
240
322
|
optout.argv(:x => "x", :y => "y").should eql(["-x=x", "-y=y"])
|
241
323
|
end
|
242
324
|
|
243
|
-
it "should join all options with multiple values on a delimiter" do
|
325
|
+
it "should join all options with multiple values on a delimiter" do
|
244
326
|
optout = create_optout(:multiple => true)
|
245
327
|
optout.argv(:x => %w|a b c|, :y => "y").should eql(["-x", "a,b,c", "-y", "y"])
|
246
328
|
end
|
247
329
|
|
248
|
-
it "should join all options with multiple values on a ':'" do
|
330
|
+
it "should join all options with multiple values on a ':'" do
|
249
331
|
optout = create_optout(:multiple => ":")
|
250
332
|
optout.argv(:x => %w|a b c|, :y => "y").should eql(["-x", "a:b:c", "-y", "y"])
|
251
|
-
end
|
333
|
+
end
|
334
|
+
|
335
|
+
it "should not differentiate between a String key and a Symbol key" do
|
336
|
+
@optout.argv("x" => "x").should eql(@optout.argv(:x => "x"))
|
337
|
+
end
|
252
338
|
end
|
253
339
|
end
|
254
340
|
|
255
341
|
# TODO: Check exception.key
|
256
|
-
describe "validation rules" do
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
proc { optout.argv(:bad => 123) }.should_not raise_exception
|
265
|
-
end
|
342
|
+
describe "validation rules" do
|
343
|
+
describe "the :check_keys option" do
|
344
|
+
context "when true" do
|
345
|
+
it "raises an exception if the option hash contains an unknown key" do
|
346
|
+
optout = create_optout
|
347
|
+
lambda { optout.argv(:bad => 123) }.should raise_exception(Optout::OptionUnknown, /bad/)
|
348
|
+
end
|
349
|
+
end
|
266
350
|
|
267
|
-
|
268
|
-
|
269
|
-
|
351
|
+
context "when false" do
|
352
|
+
it "does not raise an exception if the option hash contains an unknown key" do
|
353
|
+
optout = create_optout(:check_keys => false)
|
354
|
+
lambda { optout.argv(:bad => 123) }.should_not raise_exception
|
355
|
+
end
|
356
|
+
end
|
270
357
|
end
|
271
358
|
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
359
|
+
describe "type checking" do
|
360
|
+
it_should_behave_like "a validator"
|
361
|
+
subject { optout_option(Float) }
|
362
|
+
|
363
|
+
context "when the type is correct" do
|
364
|
+
it "should not raise an exception" do
|
365
|
+
lambda { subject.argv(:x => 123.0) }.should_not raise_exception
|
366
|
+
end
|
276
367
|
end
|
277
|
-
|
278
|
-
|
279
|
-
|
368
|
+
|
369
|
+
context "when the type is incorrect" do
|
370
|
+
it "should raise an OptionInvalid exception" do
|
371
|
+
lambda { subject.argv(:x => 123) }.should raise_exception(Optout::OptionInvalid, /type Float/)
|
372
|
+
end
|
280
373
|
end
|
281
374
|
end
|
282
375
|
|
283
|
-
|
284
|
-
|
376
|
+
describe "restricting the option to a set of values " do
|
377
|
+
it_should_behave_like "a validator"
|
378
|
+
subject { optout_option(%w|sshaw skye|) }
|
285
379
|
|
286
|
-
|
287
|
-
|
288
|
-
|
380
|
+
context "when a value is included in the set" do
|
381
|
+
it "should not raise an exception" do
|
382
|
+
lambda { subject.argv(:x => "skye") }.should_not raise_exception
|
383
|
+
end
|
289
384
|
end
|
290
385
|
|
291
|
-
|
292
|
-
|
386
|
+
context "when a value is not included in the set" do
|
387
|
+
it "should raise an OptionInvalid exception" do
|
388
|
+
lambda { subject.argv(:x => "jay_kat") }.should raise_exception(Optout::OptionInvalid, /must be one of/)
|
389
|
+
end
|
390
|
+
end
|
293
391
|
end
|
294
392
|
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
393
|
+
describe "pattern matching" do
|
394
|
+
it_should_behave_like "a validator"
|
395
|
+
subject { optout_option(/X\d{2}/) }
|
396
|
+
|
397
|
+
context "when it matches" do
|
398
|
+
it "should not raise an exception" do
|
399
|
+
lambda { subject.argv(:x => "X21") }.should_not raise_exception
|
400
|
+
end
|
299
401
|
end
|
300
402
|
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
proc { optout.argv(:x => 123) }.should raise_exception(Optout::OptionInvalid, /type Float/)
|
307
|
-
proc { optout.argv(:x => 123.0) }.should_not raise_exception(Optout::OptionInvalid)
|
403
|
+
context "when it does not match" do
|
404
|
+
it "should raise an OptionInvalid exception" do
|
405
|
+
lambda { subject.argv(:x => "X7") }.should raise_exception(Optout::OptionInvalid, /match pattern/)
|
406
|
+
end
|
407
|
+
end
|
308
408
|
end
|
309
409
|
|
310
|
-
|
311
|
-
|
410
|
+
describe Optout::Boolean do
|
411
|
+
it_should_behave_like "a validator"
|
412
|
+
subject { optout_option(Optout::Boolean) }
|
312
413
|
|
313
|
-
|
314
|
-
|
414
|
+
context "when the option's a boolean" do
|
415
|
+
it "should not raise an exception" do
|
416
|
+
[ false, true ].each do |v|
|
417
|
+
lambda { subject.argv(:x => v) }.should_not raise_exception
|
418
|
+
end
|
419
|
+
end
|
315
420
|
end
|
316
421
|
|
317
|
-
|
318
|
-
|
422
|
+
context "when the option's not a boolean" do
|
423
|
+
it "should raise an OptionInvalid exception" do
|
424
|
+
lambda { subject.argv(:x => "x") }.should raise_exception(Optout::OptionInvalid, /does not accept/)
|
425
|
+
end
|
426
|
+
end
|
427
|
+
end
|
428
|
+
end
|
429
|
+
|
430
|
+
describe "a custom validator" do
|
431
|
+
context "when it responds to :validate!" do
|
432
|
+
it "should be called" do
|
433
|
+
klass = mock("validator")
|
434
|
+
klass.should_receive(:validate!)
|
435
|
+
optout = optout_option(klass)
|
436
|
+
optout.argv(:x => "x")
|
319
437
|
end
|
320
438
|
end
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
439
|
+
|
440
|
+
context "when it does not respond to :validate!" do
|
441
|
+
it "should raise an ArgumentError" do
|
442
|
+
optout = optout_option(Class.new.new)
|
443
|
+
lambda { optout.argv(:x => "x") }.should raise_exception(ArgumentError, /don't know how to validate/)
|
444
|
+
end
|
445
|
+
end
|
446
|
+
end
|
447
|
+
|
448
|
+
describe "unknown validation rules" do
|
449
|
+
it "should raise an ArgumentError" do
|
450
|
+
optout = optout_option("whaaaaa")
|
451
|
+
lambda { optout.argv(:x => "x") }.should raise_exception(ArgumentError, /don't know how to validate/)
|
326
452
|
end
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
453
|
+
end
|
454
|
+
|
455
|
+
describe "#required" do
|
456
|
+
before :all do
|
457
|
+
@optout = Optout.new
|
458
|
+
@optout.required do
|
459
|
+
on :x, "-x"
|
460
|
+
on :y, "-y"
|
333
461
|
end
|
334
462
|
end
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
463
|
+
|
464
|
+
context "when options are missing" do
|
465
|
+
it "should raise an OptionRequired exception" do
|
466
|
+
lambda { @optout.argv }.should raise_exception(Optout::OptionRequired, /'x|y'/)
|
467
|
+
lambda { @optout.argv :x => "x" }.should raise_exception(Optout::OptionRequired, /'y'/)
|
468
|
+
lambda { @optout.argv :y => "y" }.should raise_exception(Optout::OptionRequired, /'x'/)
|
341
469
|
end
|
470
|
+
end
|
342
471
|
|
343
|
-
|
344
|
-
|
472
|
+
context "when no options are missing" do
|
473
|
+
it "should not raise an exception" do
|
474
|
+
lambda { @optout.argv :x => "x", :y => "y" }.should_not raise_exception
|
475
|
+
end
|
345
476
|
end
|
477
|
+
end
|
346
478
|
|
347
|
-
|
348
|
-
|
349
|
-
|
479
|
+
describe "#optional" do
|
480
|
+
before :all do
|
481
|
+
@optout = Optout.new
|
482
|
+
@optout.optional do
|
483
|
+
on :x, "-x"
|
484
|
+
on :y, "-y"
|
485
|
+
end
|
486
|
+
end
|
487
|
+
|
488
|
+
it "should not raise an exception if any options are missing" do
|
489
|
+
lambda { @optout.argv }.should_not raise_exception(Optout::OptionRequired)
|
490
|
+
lambda { @optout.argv(:x => "x", :y => "y") }.should_not raise_exception(Optout::OptionRequired)
|
350
491
|
end
|
492
|
+
end
|
493
|
+
end
|
351
494
|
|
352
|
-
|
353
|
-
|
495
|
+
shared_context "file validation" do
|
496
|
+
before(:all) { @tmpdir = Dir.mktmpdir }
|
497
|
+
after(:all) { FileUtils.rm_rf(@tmpdir) }
|
498
|
+
end
|
354
499
|
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
end
|
500
|
+
describe Optout::File do
|
501
|
+
include_context "file validation"
|
502
|
+
it_should_behave_like "something that validates files"
|
359
503
|
|
360
|
-
|
361
|
-
|
362
|
-
proc { optout.argv(:x => @tmpdir) }.should raise_exception(Optout::OptionInvalid, /can't create a file/)
|
363
|
-
end
|
364
|
-
end
|
504
|
+
before(:all) { @file = Tempfile.new("", @tmpdir) }
|
505
|
+
subject { @file.path }
|
365
506
|
|
366
|
-
|
367
|
-
|
507
|
+
let(:file) { @file.path }
|
508
|
+
let(:options) { { :x => file } }
|
368
509
|
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
510
|
+
context "when the option is not a file" do
|
511
|
+
it "raises an OptionInvalid exception" do
|
512
|
+
optout = optout_option(described_class)
|
513
|
+
lambda { optout.argv(:x => @tmpdir) }.should raise_exception(Optout::OptionInvalid, /can't create a file/)
|
514
|
+
end
|
515
|
+
end
|
516
|
+
end
|
517
|
+
|
518
|
+
describe Optout::Dir do
|
519
|
+
include_context "file validation"
|
520
|
+
it_should_behave_like "something that validates files"
|
373
521
|
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
522
|
+
subject { @tmpdir }
|
523
|
+
let(:file) { @tmpdir }
|
524
|
+
let(:options) { {:x => file} }
|
525
|
+
|
526
|
+
context "when the option is not a directory" do
|
527
|
+
it "raises an OptionInvalid exception" do
|
528
|
+
optout = optout_option(described_class)
|
529
|
+
lambda { optout.argv(:x => Tempfile.new("", @tmpdir).path) }.should raise_exception(Optout::OptionInvalid)
|
378
530
|
end
|
379
531
|
end
|
380
532
|
end
|